Commit d5893eb8 authored by Emmanuel Lepage's avatar Emmanuel Lepage

Complete contact support is back

parent 39764571
......@@ -31,7 +31,6 @@ ActionSetAccountFirst::ActionSetAccountFirst(Account* account, QObject *parent)
this, SLOT(emitSetFirst()));
}
ActionSetAccountFirst::~ActionSetAccountFirst()
{
}
......
......@@ -4,44 +4,109 @@
#include <akonadi/collectionfilterproxymodel.h>
#include <akonadi/collectionmodel.h>
#include <akonadi/kmime/messagemodel.h>
#include <contactgroupsearchjob.h>
#include <kabc/contactgroup.h>
#include <kabc/phonenumber.h>
#include <akonadi/recursiveitemfetchjob.h>
#include <akonadi/itemfetchscope.h>
#include <akonadi/collectionfetchjob.h>
#include <akonadi/collectionfetchscope.h>
#include "lib/Contact.h"
AkonadiBackend* AkonadiBackend::m_pInstance = 0;
AkonadiBackend::AkonadiBackend(QObject* parent) : QObject(parent)
{
QTimer::singleShot( 0, this, SLOT( delayedInit() ) );
//QTimer::singleShot( 0, this, SLOT( delayedInit() ) );
m_pSession = new Akonadi::Session( "SFLPhone::instance" );
// fetching all collections containing emails recursively, starting at the root collection
Akonadi::CollectionFetchJob *job = new Akonadi::CollectionFetchJob( Akonadi::Collection::root(), Akonadi::CollectionFetchJob::Recursive, this );
job->fetchScope().setContentMimeTypes( QStringList() << "text/directory" );
connect( job, SIGNAL( collectionsReceived( const Akonadi::Collection::List& ) ), this, SLOT( collectionsReceived( const Akonadi::Collection::List& ) ) );
}
virtual AkonadiBackend::~AkonadiBackend()
AkonadiBackend::~AkonadiBackend()
{
}
AkonadiBackend* AkonadiBackend::getInstance()
{
if (m_pInstance == NULL) {
m_pInstance = new AkonadiBackend(0);
}
return m_pInstance;
}
static bool AkonadiBackend::init()
ContactList AkonadiBackend::update(Akonadi::Collection collection)
{
if ( !Akonadi::Control::start( this ) ) {
return false;
m_pCollection = collection;
ContactList contacts;
if ( !collection.isValid() ) {
qDebug() << "The current collection is not valid";
return contacts;
}
Akonadi::RecursiveItemFetchJob *job = new Akonadi::RecursiveItemFetchJob( collection, QStringList() << KABC::Addressee::mimeType() << KABC::ContactGroup::mimeType());
job->fetchScope().fetchFullPayload();
if ( job->exec() ) {
const Akonadi::Item::List items = job->items();
foreach ( const Akonadi::Item &item, items ) {
if ( item.hasPayload<KABC::ContactGroup>() ) {
qDebug() << "Group:" << item.payload<KABC::ContactGroup>().name();
}
if ( item.hasPayload<KABC::Addressee>() ) {
KABC::Addressee tmp = item.payload<KABC::Addressee>();
Contact* aContact = new Contact();
KABC::PhoneNumber::List numbers = tmp.phoneNumbers();
PhoneNumbers newNumbers;
foreach (KABC::PhoneNumber number, numbers) {
newNumbers << new Contact::PhoneNumber(number.number(),number.typeLabel());
m_pContactByPhone[number.number()] = aContact;
}
aContact->setNickName (tmp.nickName() );
aContact->setFormattedName (tmp.formattedName() );
aContact->setFirstName (tmp.givenName() );
aContact->setFamilyName (tmp.familyName() );
aContact->setOrganization (tmp.organization() );
aContact->setPreferredEmail (tmp.preferredEmail() );
aContact->setPhoneNumbers (newNumbers );
if (!tmp.photo().data().isNull())
aContact->setPhoto(new QPixmap(QPixmap::fromImage( tmp.photo().data()).scaled(QSize(48,48))));
else
aContact->setPhoto(0);
contacts << aContact;
}
}
}
return true;
qDebug() << "End collect "<< contacts.size() << "\n\n\n";
return contacts;
}
void AkonadiBackend::createModels()
ContactList AkonadiBackend::update()
{
return update(m_pCollection);
}
Contact* AkonadiBackend::getContactByPhone(QString phoneNumber)
{
Akonadi::CollectionModel *collectionModel = new Akonadi::CollectionModel( this );
Akonadi::CollectionFilterProxyModel *filterModel = new Akonadi::CollectionFilterProxyModel( this );
filterModel->setSourceModel( collectionModel );
filterModel->addMimeTypeFilter( QLatin1String( "message/rfc822" ) );
Akonadi::ItemModel *itemModel = new Akonadi::MessageModel( this );
ui_detacherview_base.folderView->setModel( filterModel );
ui_detacherview_base.messageView->setModel( itemModel );
connect( ui_detacherview_base.folderView, SIGNAL( currentChanged( Akonadi::Collection ) ),
itemModel, SLOT( setCollection( Akonadi::Collection ) ) );
return m_pContactByPhone[phoneNumber];
}
void AkonadiBackend::collectionsReceived( const Akonadi::Collection::List& list)
{
foreach (Akonadi::Collection coll, list) {
qDebug() << "\n\n\n\n\n\nLoading collection" << coll.name();
update(coll);
emit collectionChanged();
}
}
\ No newline at end of file
......@@ -2,17 +2,37 @@
#define AKONADI_BACKEND_H
#include <QObject>
#include <akonadi/session.h>
#include <akonadi/collectionmodel.h>
#include <kabc/addressee.h>
#include <kabc/addresseelist.h>
class Contact;
typedef QList<Contact*> ContactList;
class AkonadiBackend : public QObject {
Q_OBJECT
public:
AkonadiBackend* getInstance();
static AkonadiBackend* getInstance();
Contact* getContactByPhone(QString phoneNumber);
private:
AkonadiBackend(QObject* parent);
virtual ~AkonadiBackend();
static bool init();
//Attributes
AkonadiBackend* instance;
static AkonadiBackend* m_pInstance;
Akonadi::Session* m_pSession;
Akonadi::Collection m_pCollection;
QHash<QString,Contact*> m_pContactByPhone;
public slots:
ContactList update();
ContactList update(Akonadi::Collection collection);
void collectionsReceived( const Akonadi::Collection::List& );
signals:
void collectionChanged();
};
#endif
\ No newline at end of file
......@@ -45,6 +45,7 @@ SET( sflphone_client_kde_SRCS
widgets/BookmarkDock.cpp
Codec.cpp
AccountListModel.cpp
AkonadiBackend.cpp
CallView.cpp
AccountView.cpp
)
......
......@@ -35,6 +35,8 @@
#include "lib/sflphone_const.h"
#include "lib/instance_interface_singleton.h"
#include "lib/configurationmanager_interface_singleton.h"
#include "lib/Contact.h"
#include "AkonadiBackend.h"
SFLPhone* SFLPhone::m_sApp = NULL;
......@@ -278,24 +280,6 @@ void SFLPhone::quitButton()
qApp->quit();
}
void SFLPhone::sendNotif(QString caller)
{
// notification = new KNotification ( QString("test_notification"), this );
// notification->setText("messageText") ;
// notification->setPixmap( QPixmap( this->windowIcon().pixmap(32, 32) ));
// notification->setActions( QStringList( i18n( "Open chat" ) ) );
// notification->addContext( QString::fromLatin1("call") , "caller" ) ;
// notification->sendEvent();
// KNotification::event(QString("test_notification"),
// QString("Allo"),
// this->windowIcon().pixmap(32, 32),
// parentWidget(),
// KNotification::CloseOnTimeout,
// KGlobal::mainComponent());
KNotification::event(KNotification::Notification, "New incomming call", "New call from: \n" + caller);
}
void SFLPhone::changeEvent(QEvent* event)
{
if (event->type() == QEvent::ActivationChange && iconChanged && isActiveWindow()) {
......@@ -397,7 +381,11 @@ void SFLPhone::on_m_pView_incomingCall(const Call * call)
putForeground();
}*/
//if(configurationManager.getNotify()) {
sendNotif(call->getPeerName().isEmpty() ? call->getPeerPhoneNumber() : call->getPeerName());
Contact* contact = AkonadiBackend::getInstance()->getContactByPhone(call->getPeerPhoneNumber());
if (contact) {
KNotification::event(KNotification::Notification, "New incomming call", "New call from: \n" + call->getPeerName().isEmpty() ? call->getPeerPhoneNumber() : call->getPeerName(),*contact->getPhoto());
}
KNotification::event(KNotification::Notification, "New incomming call", "New call from: \n" + call->getPeerName().isEmpty() ? call->getPeerPhoneNumber() : call->getPeerName());
//}
}
......
......@@ -121,7 +121,6 @@ public:
~SFLPhone();
bool initialize();
void setupActions();
void sendNotif(QString caller);
void trayIconSignal();
SFLPhoneView * getView();
QList<QAction *> getCallActions();
......
......@@ -48,6 +48,9 @@
<entry name="displayDataRange" type="Bool">
<label>Defines whether call history is restricted to a specific date range</label>
</entry>
<entry name="displayContactCallHistory" type="Bool">
<label>Defines if the individual contact history list is visible</label>
</entry>
<!-- Audio Settings -->
......
......@@ -28,7 +28,7 @@
const call_state Call::actionPerformedStateMap [11][5] =
{
// ACCEPT REFUSE TRANSFER HOLD RECORD
// ACCEPT REFUSE TRANSFER HOLD RECORD
/*INCOMING */ {CALL_STATE_INCOMING , CALL_STATE_INCOMING , CALL_STATE_ERROR , CALL_STATE_INCOMING , CALL_STATE_INCOMING },
/*RINGING */ {CALL_STATE_ERROR , CALL_STATE_RINGING , CALL_STATE_ERROR , CALL_STATE_ERROR , CALL_STATE_RINGING },
/*CURRENT */ {CALL_STATE_ERROR , CALL_STATE_CURRENT , CALL_STATE_TRANSFER , CALL_STATE_CURRENT , CALL_STATE_CURRENT },
......@@ -45,7 +45,7 @@ const call_state Call::actionPerformedStateMap [11][5] =
const function Call::actionPerformedFunctionMap[11][5] =
{
// ACCEPT REFUSE TRANSFER HOLD RECORD
// ACCEPT REFUSE TRANSFER HOLD RECORD
/*INCOMING */ {&Call::accept , &Call::refuse , &Call::acceptTransf , &Call::acceptHold , &Call::setRecord },
/*RINGING */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::nothing , &Call::setRecord },
/*CURRENT */ {&Call::nothing , &Call::hangUp , &Call::nothing , &Call::hold , &Call::setRecord },
......@@ -62,7 +62,7 @@ const function Call::actionPerformedFunctionMap[11][5] =
const call_state Call::stateChangedStateMap [11][6] =
{
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE
/*INCOMING */ {CALL_STATE_INCOMING , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },
/*RINGING */ {CALL_STATE_RINGING , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },
/*CURRENT */ {CALL_STATE_CURRENT , CALL_STATE_CURRENT , CALL_STATE_BUSY , CALL_STATE_HOLD , CALL_STATE_OVER , CALL_STATE_FAILURE },
......@@ -78,9 +78,9 @@ const call_state Call::stateChangedStateMap [11][6] =
const function Call::stateChangedFunctionMap[11][6] =
{
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE
/*INCOMING */ {&Call::nothing , &Call::start , &Call::startWeird , &Call::startWeird , &Call::startStop , &Call::start },
/*RINGING */ {&Call::nothing , &Call::start , &Call::start , &Call::start , &Call::startStop , &Call::start },
// RINGING CURRENT BUSY HOLD HUNGUP FAILURE
/*INCOMING */ {&Call::nothing , &Call::start , &Call::startWeird , &Call::startWeird , &Call::startStop , &Call::start },
/*RINGING */ {&Call::nothing , &Call::start , &Call::start , &Call::start , &Call::startStop , &Call::start },
/*CURRENT */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },
/*DIALING */ {&Call::nothing , &Call::warning , &Call::warning , &Call::warning , &Call::stop , &Call::warning },
/*HOLD */ {&Call::nothing , &Call::nothing , &Call::warning , &Call::nothing , &Call::stop , &Call::nothing },
......
......@@ -46,7 +46,7 @@ Contact::Contact()
Contact::~Contact()
{
delete photo;
delete m_pPhoto;
}
void Contact::initItem()
......@@ -59,34 +59,88 @@ void Contact::initItemWidget()
}
QString Contact::getPhoneNumber() const
PhoneNumbers Contact::getPhoneNumbers() const
{
return phoneNumber;
return m_pNumbers;
}
QString Contact::getNickName() const
{
return nickName;
return m_pNickName;
}
QString Contact::getFirstName() const
{
return firstName;
return m_pFirstName;
}
QString Contact::getSecondName() const
{
return secondName;
return m_pSecondName;
}
const QPixmap* Contact::getPhoto() const
{
return photo;
return m_pPhoto;
}
QString Contact::getFormattedName() const
{
return m_pFormattedName;
}
QString Contact::getOrganization() const
{
return m_pOrganization;
}
QString Contact::getPreferredEmail() const
{
return m_pPreferredEmail;
}
QString Contact::getType() const
{
return type;
return m_pType;
}
void Contact::setPhoneNumbers(PhoneNumbers numbers)
{
m_pNumbers = numbers;
}
void Contact::setNickName(QString name)
{
m_pNickName = name;
}
void Contact::setFirstName(QString name)
{
m_pFirstName = name;
}
void Contact::setFamilyName(QString name)
{
m_pSecondName = name;
}
void Contact::setPhoto(QPixmap* photo)
{
m_pPhoto = photo;
}
void Contact::setFormattedName(QString name)
{
m_pFormattedName = name;
}
void Contact::setOrganization(QString name)
{
m_pOrganization = name;
}
void Contact::setPreferredEmail(QString name)
{
m_pPreferredEmail = name;
}
\ No newline at end of file
......@@ -36,33 +36,65 @@
@author Jérémy Quentin <jeremy.quentin@savoirfairelinux.com>
*/
class LIB_EXPORT Contact : public QObject{
private:
QString firstName;
QString secondName;
QString nickName;
QString phoneNumber;
QPixmap* photo;
QString type;
bool displayPhoto;
Q_OBJECT
public:
class PhoneNumber {
public:
PhoneNumber(QString number, QString type)
: m_pNumber(number),m_pType(type){}
QString& getNumber() {
return m_pNumber ;
}
QString& getType() {
return m_pType ;
}
private:
QString m_pNumber ;
QString m_pType ;
};
typedef QList<Contact::PhoneNumber*> PhoneNumbers;
private:
QString m_pFirstName ;
QString m_pSecondName ;
QString m_pNickName ;
QPixmap* m_pPhoto ;
QString m_pType ;
QString m_pFormattedName ;
QString m_pPreferredEmail ;
QString m_pOrganization ;
bool displayPhoto ;
PhoneNumbers m_pNumbers ;
public:
//Constructors & Destructors
explicit Contact();
virtual ~Contact();
//Getters
virtual QString getPhoneNumber() const;
virtual QString getNickName() const;
virtual QString getFirstName() const;
virtual QString getSecondName() const;
virtual const QPixmap* getPhoto() const;
virtual QString getType() const;
virtual void initItem();
virtual PhoneNumbers getPhoneNumbers() const;
virtual QString getNickName() const;
virtual QString getFirstName() const;
virtual QString getSecondName() const;
virtual QString getFormattedName() const;
virtual QString getOrganization() const;
virtual QString getPreferredEmail() const;
virtual const QPixmap* getPhoto() const;
virtual QString getType() const;
virtual void initItem();
virtual void setPhoneNumbers (PhoneNumbers );
virtual void setFormattedName (QString name );
virtual void setNickName (QString name );
virtual void setFirstName (QString name );
virtual void setFamilyName (QString name );
virtual void setOrganization (QString name );
virtual void setPreferredEmail (QString name );
virtual void setPhoto (QPixmap* photo );
protected:
virtual void initItemWidget();
};
typedef Contact::PhoneNumbers PhoneNumbers;
#endif
......@@ -26,6 +26,8 @@
#include "lib/sflphone_const.h"
#include "CallTreeItem.h"
#include "lib/Contact.h"
#include "AkonadiBackend.h"
const char * CallTreeItem::callStateIcons[12] = {ICON_INCOMING, ICON_RINGING, ICON_CURRENT, ICON_DIALING, ICON_HOLD, ICON_FAILURE, ICON_BUSY, ICON_TRANSFER, ICON_TRANSF_HOLD, "", "", ICON_CONFERENCE};
......@@ -65,10 +67,11 @@ void CallTreeItem::setCall(Call *call)
return;
}
labelIcon = new QLabel();
labelCallNumber2 = new QLabel(itemCall->getPeerPhoneNumber());
labelIcon = new QLabel();
labelCallNumber2 = new QLabel(itemCall->getPeerPhoneNumber());
labelTransferPrefix = new QLabel(i18n("Transfer to : "));
labelTransferNumber = new QLabel();
labelPeerName = new QLabel();
QSpacerItem* verticalSpacer = new QSpacerItem(16777215, 20, QSizePolicy::Expanding, QSizePolicy::Expanding);
QHBoxLayout* mainLayout = new QHBoxLayout();
......@@ -89,7 +92,7 @@ void CallTreeItem::setCall(Call *call)
mainLayout->addWidget(labelIcon);
if(! itemCall->getPeerName().isEmpty()) {
labelPeerName = new QLabel(itemCall->getPeerName());
labelPeerName->setText(itemCall->getPeerName());
descr->addWidget(labelPeerName);
}
......@@ -113,6 +116,22 @@ void CallTreeItem::setCall(Call *call)
void CallTreeItem::updated()
{
Contact* contact = AkonadiBackend::getInstance()->getContactByPhone(itemCall->getPeerPhoneNumber());
if (contact) {
labelIcon->setPixmap(*contact->getPhoto());
labelPeerName->setText("<b>"+contact->getFormattedName()+"</b>");
}
else {
labelIcon->setPixmap(QPixmap(KIcon("user-identity").pixmap(QSize(48,48))));
if(! itemCall->getPeerName().trimmed().isEmpty()) {
labelPeerName->setText("<b>"+itemCall->getPeerName()+"</b>");
}
else {
labelPeerName->setText("<b>Unknow</b>");
}
}
call_state state = itemCall->getState();
bool recording = itemCall->getRecording();
if(state != CALL_STATE_OVER) {
......
......@@ -2,15 +2,16 @@
#include "ContactDock.h"
#include <QtGui/QVBoxLayout>
#include <QtGui/QTableWidget>
#include <QtGui/QListWidget>
#include <QtGui/QTreeWidget>
#include <QtGui/QHeaderView>
#include <QtGui/QCheckBox>
#include <QtCore/QDateTime>
#include <akonadi/collectionfilterproxymodel.h>
#include <akonadi/contact/contactstreemodel.h>
#include <akonadi/kmime/messagemodel.h>
#include <akonadi/changerecorder.h>
#include <akonadi/session.h>
#include <kabc/addressee.h>
#include <kabc/picture.h>
#include <kabc/phonenumber.h>
......@@ -25,7 +26,11 @@
#include <akonadi/recursiveitemfetchjob.h>
#include <kicon.h>
#include "AkonadiBackend.h"
#include "ContactItemWidget.h"
#include "conf/ConfigurationSkeleton.h"
#include "lib/Call.h"
#include "SFLPhone.h"
class QNumericTreeWidgetItem : public QTreeWidgetItem {
public:
......@@ -48,12 +53,12 @@ class QNumericTreeWidgetItem : public QTreeWidgetItem {
ContactDock::ContactDock(QWidget* parent) : QDockWidget(parent)
{
m_pFilterLE = new KLineEdit();
m_pCollCCB = new Akonadi::CollectionComboBox;
m_pSplitter = new QSplitter(Qt::Vertical,this);
m_pSortByCBB = new QComboBox(this);
m_pContactView = new QTreeWidget(this);
m_pCallView = new QTableWidget(this);
m_pFilterLE = new KLineEdit ( );
m_pSplitter = new QSplitter ( Qt::Vertical,this );
m_pSortByCBB = new QComboBox ( this );
m_pContactView = new QTreeWidget ( this );
m_pCallView = new QListWidget ( this );
m_pShowHistoCK = new QCheckBox ( this );
QStringList sortType;
sortType << "Name" << "Organisation" << "Phone number type" << "Rencently used" << "Group";
......@@ -71,24 +76,25 @@ ContactDock::ContactDock(QWidget* parent) : QDockWidget(parent)
m_pFilterLE->setPlaceholderText("Filter");
m_pFilterLE->setClearButtonShown(true);
m_pShowHistoCK->setChecked(ConfigurationSkeleton::displayContactCallHistory());
m_pShowHistoCK->setText("Display history");
QVBoxLayout* mainLayout = new QVBoxLayout(mainWidget);
mainLayout->addWidget(m_pCollCCB);
mainLayout->addWidget(m_pSortByCBB);
mainLayout->addWidget(m_pSplitter);
m_pSplitter->addWidget(m_pContactView);
m_pSplitter->addWidget(m_pCallView);
mainLayout->addWidget(m_pFilterLE);
mainLayout->addWidget ( m_pSortByCBB );
mainLayout->addWidget ( m_pShowHistoCK );
mainLayout->addWidget ( m_pSplitter );
m_pSplitter->addWidget ( m_pContactView );
m_pSplitter->addWidget ( m_pCallView );
mainLayout->addWidget ( m_pFilterLE );
m_pSplitter->setChildrenCollapsible(true);
m_pSplitter->setStretchFactor(0,7);