1
/***************************************************************************
2
* Copyright (C) 2009-2013 by Savoir-Faire Linux *
3
* Author : Mathieu Leduc-Hamel mathieu.leduc-hamel@savoirfairelinux.com *
4
* Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>*
6
* This program is free software; you can redistribute it and/or modify *
7
* it under the terms of the GNU General Public License as published by *
8
* the Free Software Foundation; either version 3 of the License, or *
9
* (at your option) any later version. *
11
* This program 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. *
16
* You should have received a copy of the GNU General Public License *
17
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
18
**************************************************************************/
21
#include "contactitemwidget.h"
24
#include <QtCore/QMimeData>
25
#include <QtCore/QProcess>
26
#include <QtGui/QApplication>
27
#include <QtGui/QClipboard>
28
#include <QtGui/QGridLayout>
29
#include <QtGui/QMenu>
30
#include <QtGui/QLabel>
31
#include <QtGui/QSpacerItem>
32
#include <QtGui/QBitmap>
33
#include <QtGui/QPainter>
40
#include <KStandardDirs>
41
#include <KInputDialog>
47
#include "klib/akonadibackend.h"
48
#include "widgets/bookmarkdock.h"
49
#include "klib/configurationskeleton.h"
50
#include "klib/helperfunctions.h"
51
#include "widgets/translucentbuttons.h"
55
#include "lib/contact.h"
56
#include "lib/sflphone_const.h"
59
ContactItemWidget::ContactItemWidget(QWidget *parent)
60
: QWidget(parent), m_pMenu(0),m_pOrganizationL(0),m_pEmailL(0),m_pContactKA(0), m_pIconL(0), m_pContactNameL(0),
63
setContextMenuPolicy(Qt::CustomContextMenu);
66
m_pCallAgain = new KAction(this);
67
m_pCallAgain->setShortcut ( Qt::CTRL + Qt::Key_Enter );
68
m_pCallAgain->setText ( i18n("Call Again") );
69
m_pCallAgain->setIcon ( KIcon("call-start") );
71
m_pEditContact = new KAction(this);
72
m_pEditContact->setShortcut ( Qt::CTRL + Qt::Key_E );
73
m_pEditContact->setText ( i18n("Edit contact") );
74
m_pEditContact->setIcon ( KIcon("contact-new") );
76
m_pCopy = new KAction(this);
77
m_pCopy->setShortcut ( Qt::CTRL + Qt::Key_C );
78
m_pCopy->setText ( i18n("Copy") );
79
m_pCopy->setIcon ( KIcon("edit-copy") );
81
m_pEmail = new KAction(this);
82
m_pEmail->setShortcut ( Qt::CTRL + Qt::Key_M );
83
m_pEmail->setText ( i18n("Send Email") );
84
m_pEmail->setIcon ( KIcon("mail-message-new") );
85
m_pEmail->setEnabled ( false );
87
m_pAddPhone = new KAction(this);
88
m_pAddPhone->setShortcut ( Qt::CTRL + Qt::Key_N );
89
m_pAddPhone->setText ( i18n("Add Phone Number") );
90
m_pAddPhone->setIcon ( KIcon("list-resource-add") );
91
m_pEmail->setEnabled ( false );
93
m_pBookmark = new KAction(this);
94
m_pBookmark->setShortcut ( Qt::CTRL + Qt::Key_D );
95
m_pBookmark->setText ( i18n("Bookmark") );
96
m_pBookmark->setIcon ( KIcon("bookmarks") );
98
connect(m_pCallAgain , SIGNAL(triggered()) , this,SLOT(callAgain()) );
99
connect(m_pEditContact , SIGNAL(triggered()) , this,SLOT(editContact()));
100
connect(m_pCopy , SIGNAL(triggered()) , this,SLOT(copy()) );
101
connect(m_pEmail , SIGNAL(triggered()) , this,SLOT(sendEmail()) );
102
connect(m_pAddPhone , SIGNAL(triggered()) , this,SLOT(addPhone()) );
103
connect(m_pBookmark , SIGNAL(triggered()) , this,SLOT(bookmark()) );
106
m_pBtnTrans = new TranslucentButtons(this);
107
m_pBtnTrans->setText ( i18n("Transfer"));
108
m_pBtnTrans->setVisible( false);
109
m_pBtnTrans->setPixmap ( new QImage(KStandardDirs::locate("data","sflphone-client-kde/transferarraw.png")));
110
connect(m_pBtnTrans,SIGNAL(dataDropped(QMimeData*)),this,SLOT(transferEvent(QMimeData*)));
111
} //ContactItemWidget
114
ContactItemWidget::~ContactItemWidget()
116
if (m_pIconL) delete m_pIconL ;
117
if (m_pContactNameL) delete m_pContactNameL ;
118
if (m_pCallNumberL) delete m_pCallNumberL ;
119
if (m_pOrganizationL) delete m_pOrganizationL;
120
if (m_pEmailL) delete m_pEmailL ;
121
if (m_pMenu) delete m_pMenu ;
123
delete m_pCallAgain ;
124
delete m_pEditContact ;
132
/*****************************************************************************
136
****************************************************************************/
139
void ContactItemWidget::setContact(Contact* contact)
141
m_pContactKA = contact;
142
m_pIconL = new QLabel ( this );
143
m_pContactNameL = new QLabel ( );
144
m_pCallNumberL = new QLabel ( this );
146
m_pIconL->setMinimumSize(70,48);
147
m_pIconL->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
149
QSpacerItem* verticalSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding);
151
m_pIconL->setMaximumSize(48,9999);
152
m_pIconL->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
154
m_pIconL->setPixmap(QPixmap(KIcon("user-identity").pixmap(QSize(48,48))));
156
QGridLayout* mainLayout = new QGridLayout(this);
157
mainLayout->setContentsMargins(0,0,0,0);
158
mainLayout->addWidget( m_pIconL , 0 , 0 , 4 , 1 );
159
mainLayout->addWidget( m_pContactNameL , 0 , 1 );
163
if (ConfigurationSkeleton::displayOrganisation() && !contact->getOrganization().isEmpty()) {
164
m_pOrganizationL = new QLabel ( this );
165
mainLayout->addWidget( m_pOrganizationL, row , 1);
168
mainLayout->addWidget( m_pCallNumberL , row , 1 );
171
if (ConfigurationSkeleton::displayEmail() && !contact->getPreferredEmail().isEmpty()) {
172
m_pEmailL = new QLabel ( );
173
mainLayout->addWidget( m_pEmailL , row , 1 );
177
mainLayout->addItem(verticalSpacer , row , 1 );
179
setLayout(mainLayout);
180
setMinimumSize(QSize(50, 30));
183
connect(this,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showContext(QPoint)));
186
if ( m_pContactNameL ) {
187
QFontMetrics fm(m_pContactNameL->font());
188
height += fm.height();
190
if ( m_pCallNumberL ) {
191
QFontMetrics fm(m_pCallNumberL->font());
192
height += fm.height();
194
if ( m_pOrganizationL ) {
195
QFontMetrics fm(m_pOrganizationL->font());
196
height += fm.height();
199
QFontMetrics fm(m_pEmailL->font());
200
height += fm.height();
205
m_Size = QSize(0,height+8);
207
if (!m_pContactKA->getPreferredEmail().isEmpty()) {
208
m_pEmail->setEnabled(true);
212
///Set the model index
213
void ContactItemWidget::setItem(QTreeWidgetItem* item)
219
/*****************************************************************************
223
****************************************************************************/
225
///The contact need to be updated
226
void ContactItemWidget::updated()
228
m_pContactNameL->setText("<b>"+m_pContactKA->getFormattedName()+"</b>");
229
if (m_pOrganizationL && !m_pContactKA->getOrganization().isEmpty()) {
230
m_pOrganizationL->setText(m_pContactKA->getOrganization());
232
else if (m_pOrganizationL) {
233
m_pOrganizationL->setVisible(false);
236
if (m_pEmailL && !getEmail().isEmpty()) {
237
m_pEmailL->setText(getEmail());
239
else if (m_pEmailL) {
240
m_pEmailL->setVisible(false);
243
PhoneNumbers numbers = m_pContactKA->getPhoneNumbers();
245
if (getCallNumbers().count() == 1)
246
m_pCallNumberL->setText(getCallNumbers()[0]->getNumber());
248
m_pCallNumberL->setText(i18np("%1 number","%1 numbers",getCallNumbers().count()));
250
if (!m_pContactKA->getPhoto()) {
252
m_pIconL->setPixmap(QPixmap(KIcon("user-identity").pixmap(QSize(48,48))));
255
QPixmap pxm =*m_pContactKA->getPhoto();
256
QRect pxRect = pxm.rect();
257
QBitmap mask(pxRect.size());
258
QPainter customPainter(&mask);
259
customPainter.setRenderHint (QPainter::Antialiasing, true );
260
customPainter.fillRect (pxRect ,"white" );
261
customPainter.setBackground (QColor("black") );
262
customPainter.setBrush (QColor("black") );
263
customPainter.drawRoundedRect(pxRect,5,5);
265
m_pIconL->setPixmap(pxm);
270
/*****************************************************************************
274
****************************************************************************/
276
///Return contact name
277
const QString& ContactItemWidget::getContactName() const
279
return m_pContactKA->getFormattedName();
282
///Return call number
283
PhoneNumbers ContactItemWidget::getCallNumbers() const
285
return m_pContactKA->getPhoneNumbers();
288
///Return the organisation
289
const QString& ContactItemWidget::getOrganization() const
291
return m_pContactKA->getOrganization();
294
///Return the email address
295
const QString& ContactItemWidget::getEmail() const
297
return m_pContactKA->getPreferredEmail();
300
///Return the picture
301
QPixmap* ContactItemWidget::getPicture() const
303
return (QPixmap*) m_pContactKA->getPhoto();
306
///Return the model index
307
QTreeWidgetItem* ContactItemWidget::getItem() const
312
///Return the contact object
313
Contact* ContactItemWidget::getContact() const
319
QString ContactItemWidget::showNumberSelector(bool& ok)
321
if (m_pContactKA->getPhoneNumbers().size() > 1) {
323
QHash<QString,QString> map;
324
foreach (Contact::PhoneNumber* number, m_pContactKA->getPhoneNumbers()) {
325
map[number->getType()+" ("+number->getNumber()+')'] = number->getNumber();
326
list << number->getType()+" ("+number->getNumber()+')';
328
QString result = KInputDialog::getItem ( i18n("Select phone number"), i18n("This contact has many phone numbers, please select the one you wish to call"), list, 0, false, &ok,this);
331
kDebug() << "Operation cancelled";
335
else if (m_pContactKA->getPhoneNumbers().size() == 1) {
337
return m_pContactKA->getPhoneNumbers()[0]->getNumber();
345
///Return precalculated size hint, prevent it from being computed over and over
346
QSize ContactItemWidget::sizeHint () const
351
/*****************************************************************************
355
****************************************************************************/
357
///Show the context menu
358
void ContactItemWidget::showContext(const QPoint& pos)
361
m_pMenu = new QMenu( this );
362
m_pMenu->addAction( m_pCallAgain );
363
m_pMenu->addAction( m_pEditContact );
364
m_pMenu->addAction( m_pAddPhone );
365
m_pMenu->addAction( m_pCopy );
366
m_pMenu->addAction( m_pEmail );
367
m_pMenu->addAction( m_pBookmark );
369
PhoneNumbers numbers = m_pContactKA->getPhoneNumbers();
370
m_pBookmark->setEnabled(numbers.count() == 1);
371
m_pMenu->exec(mapToGlobal(pos));
376
void ContactItemWidget::sendEmail()
378
kDebug() << "Sending email";
379
QProcess *myProcess = new QProcess(this);
380
QStringList arguments;
381
myProcess->start("xdg-email", (arguments << m_pContactKA->getPreferredEmail()));
384
///Call the same number again
386
void ContactItemWidget::callAgain()
388
kDebug() << "Calling ";
390
QString number = showNumberSelector(ok);
392
Call* call = SFLPhone::model()->addDialingCall(m_pContactKA->getFormattedName(), AccountList::getCurrentAccount());
394
call->setCallNumber(number);
395
call->setPeerName(m_pContactKA->getFormattedName());
396
call->actionPerformed(CALL_ACTION_ACCEPT);
399
HelperFunctions::displayNoAccountMessageBox(this);
404
///Copy contact to clipboard
405
void ContactItemWidget::copy()
407
kDebug() << "Copying contact";
408
QMimeData* mimeData = new QMimeData();
409
mimeData->setData(MIME_CONTACT, m_pContactKA->getUid().toUtf8());
410
QString numbers(m_pContactKA->getFormattedName()+": ");
411
QString numbersHtml("<b>"+m_pContactKA->getFormattedName()+"</b><br />");
412
foreach (Contact::PhoneNumber* number, m_pContactKA->getPhoneNumbers()) {
413
numbers += number->getNumber()+" ("+number->getType()+") ";
414
numbersHtml += number->getNumber()+" ("+number->getType()+") <br />";
416
mimeData->setData("text/plain", numbers.toUtf8());
417
mimeData->setData("text/html", numbersHtml.toUtf8());
418
QClipboard* clipboard = QApplication::clipboard();
419
clipboard->setMimeData(mimeData);
423
void ContactItemWidget::editContact()
425
kDebug() << "Edit contact";
426
AkonadiBackend::getInstance()->editContact(m_pContactKA);
429
///Add a new phone number for this contact
431
void ContactItemWidget::addPhone()
433
kDebug() << "Adding to contact";
435
QString text = KInputDialog::getText( i18n("Enter a new number"), i18n("New number:"), QString(), &ok,this);
436
if (ok && !text.isEmpty()) {
437
AkonadiBackend::getInstance()->addPhoneNumber(m_pContactKA,text,"work");
441
///Add this contact to the bookmark list
442
void ContactItemWidget::bookmark()
444
PhoneNumbers numbers = m_pContactKA->getPhoneNumbers();
445
if (numbers.count() == 1)
446
SFLPhone::app()->bookmarkDock()->addBookmark(numbers[0]->getNumber());
450
/*****************************************************************************
454
****************************************************************************/
456
///Called when a drag and drop occur while the item have not been dropped yet
457
void ContactItemWidget::dragEnterEvent ( QDragEnterEvent *e )
459
kDebug() << "Drag enter";
460
if (e->mimeData()->hasFormat( MIME_CALLID) && m_pBtnTrans) {
461
m_pBtnTrans->setHoverState(true);
462
m_pBtnTrans->setMinimumSize(width()-16,height()-4);
463
m_pBtnTrans->setMaximumSize(width()-16,height()-4);
464
m_pBtnTrans->move(8,2);
465
m_pBtnTrans->setVisible(true);
466
m_pBtnTrans->setHoverState(true);
473
///The cursor move on a potential drag event
474
void ContactItemWidget::dragMoveEvent ( QDragMoveEvent *e )
476
m_pBtnTrans->setHoverState(true);
480
///A potential drag event is cancelled
481
void ContactItemWidget::dragLeaveEvent ( QDragLeaveEvent *e )
483
m_pBtnTrans->setHoverState(false);
484
m_pBtnTrans->setVisible(false);
485
kDebug() << "Drag leave";
489
///Called when a call is dropped on transfer
490
void ContactItemWidget::transferEvent(QMimeData* data)
492
if (data->hasFormat( MIME_CALLID)) {
494
QString result = showNumberSelector(ok);
496
Call* call = SFLPhone::model()->getCall(data->data(MIME_CALLID));
497
if (dynamic_cast<Call*>(call)) {
498
call->changeCurrentState(CALL_STATE_TRANSFERRED);
499
SFLPhone::model()->transfer(call, result);
504
kDebug() << "Invalid mime data";
505
m_pBtnTrans->setHoverState(false);
506
m_pBtnTrans->setVisible(false);
510
void ContactItemWidget::dropEvent(QDropEvent *e)
512
kDebug() << "Drop accepted";
513
if (dynamic_cast<const QMimeData*>(e->mimeData()) && e->mimeData()->hasFormat( MIME_CALLID)) {
514
transferEvent((QMimeData*)e->mimeData());
518
kDebug() << "Invalid drop data";
524
void ContactItemWidget::mouseDoubleClickEvent(QMouseEvent *e )
526
PhoneNumbers numbers = m_pContactKA->getPhoneNumbers();
528
if (getCallNumbers().count() == 1) {