diff --git a/kde/src/ActionSetAccountFirst.cpp b/kde/src/ActionSetAccountFirst.cpp index 7a5829fa0ea6cbb26ae1a5dd97b5a0071bcead35..974180d16584e317e0209bddddcf0093b53e0f33 100755 --- a/kde/src/ActionSetAccountFirst.cpp +++ b/kde/src/ActionSetAccountFirst.cpp @@ -31,7 +31,6 @@ ActionSetAccountFirst::ActionSetAccountFirst(Account* account, QObject *parent) this, SLOT(emitSetFirst())); } - ActionSetAccountFirst::~ActionSetAccountFirst() { } diff --git a/kde/src/AkonadiBackend.cpp b/kde/src/AkonadiBackend.cpp index 30f625245ed952cea8e88ece41560ad666aba51e..ecd95ac5d9e634635131cb425f2f1ef02729e6bd 100644 --- a/kde/src/AkonadiBackend.cpp +++ b/kde/src/AkonadiBackend.cpp @@ -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 diff --git a/kde/src/AkonadiBackend.h b/kde/src/AkonadiBackend.h index a8e60f8e0d2b3bd3288734c07e3ccc9f8516ad55..e43984aeb164510b96da6b01102a44326f66c01f 100644 --- a/kde/src/AkonadiBackend.h +++ b/kde/src/AkonadiBackend.h @@ -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 diff --git a/kde/src/CMakeLists.txt b/kde/src/CMakeLists.txt index bc645c802cf4267a2aba9d14321658c8a89c900b..1fe5b49aa721fb0036754bcd4ebf676def043c95 100755 --- a/kde/src/CMakeLists.txt +++ b/kde/src/CMakeLists.txt @@ -45,6 +45,7 @@ SET( sflphone_client_kde_SRCS widgets/BookmarkDock.cpp Codec.cpp AccountListModel.cpp + AkonadiBackend.cpp CallView.cpp AccountView.cpp ) diff --git a/kde/src/SFLPhone.cpp b/kde/src/SFLPhone.cpp index e6c793c53b530abecdaec9299d004ff868795dbf..2d5da4e980ddda4d7bc4dfbf28ae796d599a5c2e 100755 --- a/kde/src/SFLPhone.cpp +++ b/kde/src/SFLPhone.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()); //} } diff --git a/kde/src/SFLPhone.h b/kde/src/SFLPhone.h index 59c6b5e57823ae6d1c04e66f99b715d49c4dab8e..a445e1ad597030c92fe57532fca9caa863d3f00d 100755 --- a/kde/src/SFLPhone.h +++ b/kde/src/SFLPhone.h @@ -121,7 +121,6 @@ public: ~SFLPhone(); bool initialize(); void setupActions(); - void sendNotif(QString caller); void trayIconSignal(); SFLPhoneView * getView(); QList<QAction *> getCallActions(); diff --git a/kde/src/conf/sflphone-client-kde.kcfg b/kde/src/conf/sflphone-client-kde.kcfg index 9ffc30081059bc7d89614369235f534aa1f1ac93..70d0d00315e2ceca5febed3928b99f993ec3b639 100755 --- a/kde/src/conf/sflphone-client-kde.kcfg +++ b/kde/src/conf/sflphone-client-kde.kcfg @@ -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 --> diff --git a/kde/src/lib/Call.cpp b/kde/src/lib/Call.cpp index 52f8e5394c4626386afb624b58cf1410ebb29e0a..b23e67f1a93c91e6c8a75a4a90749fe7bed3bfe8 100644 --- a/kde/src/lib/Call.cpp +++ b/kde/src/lib/Call.cpp @@ -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 }, diff --git a/kde/src/lib/Contact.cpp b/kde/src/lib/Contact.cpp index 8f952c56a45aa0c1632e705863d23039700d5b1c..54731e870fe132589e29d250428679ce03ebbb4d 100644 --- a/kde/src/lib/Contact.cpp +++ b/kde/src/lib/Contact.cpp @@ -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 diff --git a/kde/src/lib/Contact.h b/kde/src/lib/Contact.h index 2584aa80fb02aa0d5f0b46b02c587f02e9e9f8cf..33a5955e8a9759bc7fd336a6b675c1cd9058a5a7 100644 --- a/kde/src/lib/Contact.h +++ b/kde/src/lib/Contact.h @@ -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 diff --git a/kde/src/widgets/CallTreeItem.cpp b/kde/src/widgets/CallTreeItem.cpp index a093533bc41b9b90d428e473ff100fc541f35a28..95cf271c7f26f4333be1fcb5da5238731e48ee59 100644 --- a/kde/src/widgets/CallTreeItem.cpp +++ b/kde/src/widgets/CallTreeItem.cpp @@ -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) { diff --git a/kde/src/widgets/ContactDock.cpp b/kde/src/widgets/ContactDock.cpp index 2ab3736dc9d0961f4d1b17280637b41bbcdc0f82..aee22b880ea9796367a2d68bcd7d435bea3d961b 100644 --- a/kde/src/widgets/ContactDock.cpp +++ b/kde/src/widgets/ContactDock.cpp @@ -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); - - m_pCollCCB->setMimeTypeFilter( QStringList() << KABC::Addressee::mimeType() ); - m_pCollCCB->setAccessRightsFilter( Akonadi::Collection::ReadOnly ); - Akonadi::Session *session = new Akonadi::Session( "SFLPhone::instance" ); - - connect (m_pCollCCB, SIGNAL(currentChanged(Akonadi::Collection)),this,SLOT(reloadContact())); + connect (AkonadiBackend::getInstance(),SIGNAL(collectionChanged()), this, SLOT(reloadContact() )); + connect (m_pContactView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),this, SLOT(loadContactHistory(QTreeWidgetItem*) )); + connect (m_pFilterLE, SIGNAL(textChanged(QString)), this, SLOT(filter(QString) )); + connect (m_pShowHistoCK, SIGNAL(toggled(bool)), m_pCallView, SLOT(setVisible(bool) )); setWindowTitle("Contact"); } @@ -97,60 +103,63 @@ ContactDock::~ContactDock() } -KABC::Addressee::List ContactDock::collectAddressBookContacts() const -{ - KABC::Addressee::List contacts; - const Akonadi::Collection collection = m_pCollCCB->currentCollection(); - 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>() ) { - contacts << item.payload<KABC::Addressee>(); - qDebug() << "Addressee:" << item.payload<KABC::Addressee>().givenName(); - } - } - } - - qDebug() << "End collect "<< contacts.size() << "\n\n\n"; - return contacts; -} - void ContactDock::reloadContact() { - KABC::Addressee::List list = collectAddressBookContacts(); - - qDebug() << "About to display items" << list.size(); - foreach (KABC::Addressee addr, list) { - qDebug() << "In list:"; + ContactList list = AkonadiBackend::getInstance()->update(); + foreach (Contact* cont, list) { ContactItemWidget* aContact = new ContactItemWidget(m_pContactView); QNumericTreeWidgetItem* item = new QNumericTreeWidgetItem(m_pContactView); item->widget = aContact; aContact->setItem(item); - aContact->setContact(addr); + aContact->setContact(cont); - KABC::PhoneNumber::List numbers = aContact->getCallNumbers(); - if (aContact->getCallNumbers().count() > 1) { - foreach (KABC::PhoneNumber number, numbers) { + PhoneNumbers numbers = aContact->getContact()->getPhoneNumbers(); + qDebug() << "Phone count" << numbers.count(); + if (numbers.count() > 1) { + foreach (Contact::PhoneNumber* number, numbers) { QNumericTreeWidgetItem* item2 = new QNumericTreeWidgetItem(item); - QLabel* numberL = new QLabel("<b>"+number.typeLabel()+":</b>"+number.number()); + QLabel* numberL = new QLabel("<b>"+number->getType()+":</b>"+number->getNumber()); m_pContactView->setItemWidget(item2,0,numberL); } } m_pContactView->addTopLevelItem(item); m_pContactView->setItemWidget(item,0,aContact); + m_pContacts << aContact; + } +} + +void ContactDock::loadContactHistory(QTreeWidgetItem* item) +{ + if (m_pShowHistoCK->isChecked()) { + m_pCallView->clear(); + if (dynamic_cast<QNumericTreeWidgetItem*>(item) != NULL) { + QNumericTreeWidgetItem* realItem = dynamic_cast<QNumericTreeWidgetItem*>(item); + foreach (Call* call, SFLPhone::app()->model()->getHistory()) { + if (realItem->widget != 0) { + foreach (Contact::PhoneNumber* number, realItem->widget->getContact()->getPhoneNumbers()) { + if (number->getNumber() == call->getPeerPhoneNumber()) { + m_pCallView->addItem(QDateTime::fromTime_t(call->getStartTimeStamp().toUInt()).toString()); + } + } + } + } + } + } +} + +void ContactDock::filter(QString text) +{ + foreach(ContactItemWidget* item, m_pContacts) { + bool foundNumber = false; + foreach (Contact::PhoneNumber* number, item->getContact()->getPhoneNumbers()) { + foundNumber |= number->getNumber().toLower().indexOf(text) != -1; + } + bool visible = (item->getContact()->getFormattedName().toLower().indexOf(text) != -1) + || (item->getContact()->getOrganization().toLower().indexOf(text) != -1) + || (item->getContact()->getPreferredEmail().toLower().indexOf(text) != -1) + || foundNumber; + item->getItem()->setHidden(!visible); } + m_pContactView->expandAll(); } \ No newline at end of file diff --git a/kde/src/widgets/ContactDock.h b/kde/src/widgets/ContactDock.h index fe9419e6405e601afb60fa45677ab98ceeb8eb4a..c77bf31cc5e90f913996199227dd263e26f44505 100644 --- a/kde/src/widgets/ContactDock.h +++ b/kde/src/widgets/ContactDock.h @@ -12,8 +12,11 @@ #include <akonadi/collectioncombobox.h> class QTreeWidget; -class QTableWidget; +class QListWidget; class QComboBox; +class QTreeWidgetItem; +class QCheckBox; +class ContactItemWidget; class ContactDock : public QDockWidget { Q_OBJECT @@ -21,17 +24,19 @@ public: ContactDock(QWidget* parent); virtual ~ContactDock(); private: + //Attributes KLineEdit* m_pFilterLE; - Akonadi::CollectionComboBox* m_pCollCCB; QSplitter* m_pSplitter; QTreeWidget* m_pContactView; - QTableWidget* m_pCallView; + QListWidget* m_pCallView; QComboBox* m_pSortByCBB; + QCheckBox* m_pShowHistoCK; + QList<ContactItemWidget*> m_pContacts; -public slots: - KABC::Addressee::List collectAddressBookContacts() const; private slots: void reloadContact(); + void loadContactHistory(QTreeWidgetItem* item); + void filter(QString text); }; #endif \ No newline at end of file diff --git a/kde/src/widgets/ContactItemWidget.cpp b/kde/src/widgets/ContactItemWidget.cpp index 1484b5264e77539020259386ad32d7230651cb8f..3e2caed5a1e2fd1ce14bf08d30df8f8362040831 100644 --- a/kde/src/widgets/ContactItemWidget.cpp +++ b/kde/src/widgets/ContactItemWidget.cpp @@ -39,7 +39,7 @@ ContactItemWidget::~ContactItemWidget() } -void ContactItemWidget::setContact(KABC::Addressee& contact) +void ContactItemWidget::setContact(Contact* contact) { m_pContactKA = contact; m_pIconL = new QLabel(this); @@ -75,9 +75,9 @@ void ContactItemWidget::setContact(KABC::Addressee& contact) void ContactItemWidget::updated() { - m_pContactNameL->setText("<b>"+m_pContactKA.formattedName()+"</b>"); - if (!m_pContactKA.organization().isEmpty()) { - m_pOrganizationL->setText(m_pContactKA.organization()); + m_pContactNameL->setText("<b>"+m_pContactKA->getFormattedName()+"</b>"); + if (!m_pContactKA->getOrganization().isEmpty()) { + m_pOrganizationL->setText(m_pContactKA->getOrganization()); } else { m_pOrganizationL->setVisible(false); @@ -90,51 +90,50 @@ void ContactItemWidget::updated() m_pEmailL->setVisible(false); } - KABC::PhoneNumber::List numbers = m_pContactKA.phoneNumbers(); - foreach (KABC::PhoneNumber number, numbers) { - qDebug() << "Phone:" << number.number() << number.typeLabel(); + PhoneNumbers numbers = m_pContactKA->getPhoneNumbers(); + foreach (Contact::PhoneNumber* number, numbers) { + qDebug() << "Phone:" << number->getNumber() << number->getType(); } if (getCallNumbers().count() == 1) - m_pCallNumberL->setText(getCallNumbers()[0].number()); + m_pCallNumberL->setText(getCallNumbers()[0]->getNumber()); else m_pCallNumberL->setText(QString::number(getCallNumbers().count())+" numbers"); - - QImage photo = m_pContactKA.photo().data(); - if (photo.isNull()) + + if (!m_pContactKA->getPhoto()) m_pIconL->setPixmap(QPixmap(KIcon("user-identity").pixmap(QSize(48,48)))); else - m_pIconL->setPixmap(QPixmap::fromImage( m_pContactKA.photo().data()).scaled(QSize(48,48)));; + m_pIconL->setPixmap(*m_pContactKA->getPhoto()); } -QPixmap* ContactItemWidget::getIcon() -{ - return new QPixmap(); -} +// QPixmap* ContactItemWidget::getIcon() +// { +// return new QPixmap(); +// } -QString ContactItemWidget::getContactName() +QString ContactItemWidget::getContactName() const { - return m_pContactKA.formattedName(); + return m_pContactKA->getFormattedName(); } -KABC::PhoneNumber::List ContactItemWidget::getCallNumbers() +PhoneNumbers ContactItemWidget::getCallNumbers() const { - return m_pContactKA.phoneNumbers(); + return m_pContactKA->getPhoneNumbers(); } -QString ContactItemWidget::getOrganization() +QString ContactItemWidget::getOrganization() const { - return m_pContactKA.organization(); + return m_pContactKA->getOrganization(); } -QString ContactItemWidget::getEmail() +QString ContactItemWidget::getEmail() const { - return m_pContactKA.fullEmail(); + return m_pContactKA->getPreferredEmail(); } -QString ContactItemWidget::getPicture() +QPixmap* ContactItemWidget::getPicture() const { - return m_pContactKA.photo().url(); + return (QPixmap*) m_pContactKA->getPhoto(); } QTreeWidgetItem* ContactItemWidget::getItem() @@ -145,4 +144,9 @@ QTreeWidgetItem* ContactItemWidget::getItem() void ContactItemWidget::setItem(QTreeWidgetItem* item) { m_pItem = item; +} + +Contact* ContactItemWidget::getContact() +{ + return m_pContactKA; } \ No newline at end of file diff --git a/kde/src/widgets/ContactItemWidget.h b/kde/src/widgets/ContactItemWidget.h index 4e55cb4db0b2160a54e450caba464acdd7d934ec..f7755c6dd36b2ed44022bca0e7b91502967ec368 100644 --- a/kde/src/widgets/ContactItemWidget.h +++ b/kde/src/widgets/ContactItemWidget.h @@ -35,6 +35,8 @@ #include <kabc/picture.h> #include <kabc/phonenumber.h> +#include <lib/Contact.h> + class QTreeWidgetItem; class ContactItemWidget : public QWidget @@ -45,21 +47,22 @@ class ContactItemWidget : public QWidget ~ContactItemWidget(); KABC::Addressee* contact() const; - void setContact(KABC::Addressee& contact); + void setContact(Contact* contact); static const char * callStateIcons[12]; - QPixmap* getIcon(); - QString getContactName(); - KABC::PhoneNumber::List getCallNumbers(); - QString getOrganization(); - QString getEmail(); - QString getPicture(); + //QPixmap* getIcon(); + QString getContactName() const; + PhoneNumbers getCallNumbers() const; + QString getOrganization() const; + QString getEmail() const; + QPixmap* getPicture() const; QTreeWidgetItem* getItem(); + Contact* getContact(); void setItem(QTreeWidgetItem* item); private: - KABC::Addressee m_pContactKA; + Contact* m_pContactKA; QLabel* m_pIconL; QLabel* m_pContactNameL; diff --git a/kde/src/widgets/HistoryDock.cpp b/kde/src/widgets/HistoryDock.cpp index 31bbb4bbba243ee831d2cf84d7ec3f9f347238e5..80925e90f47d62b119186470ee78a61932118863 100644 --- a/kde/src/widgets/HistoryDock.cpp +++ b/kde/src/widgets/HistoryDock.cpp @@ -14,6 +14,7 @@ #include "SFLPhone.h" #include "widgets/HistoryTreeItem.h" #include "conf/ConfigurationSkeleton.h" +#include "AkonadiBackend.h" class QNumericTreeWidgetItem : public QTreeWidgetItem { public: @@ -56,10 +57,10 @@ HistoryDock::HistoryDock(QWidget* parent) : QDockWidget(parent) m_pLinkPB->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Expanding); m_pLinkPB->setCheckable(true); - m_pItemView->headerItem()->setText(0,"Calls"); - m_pItemView->header()->setClickable(true); - m_pItemView->header()->setSortIndicatorShown(true); - m_pItemView->setAlternatingRowColors(true); + m_pItemView->headerItem()->setText(0,"Calls" ); + m_pItemView->header ()->setClickable(true ); + m_pItemView->header ()->setSortIndicatorShown(true ); + m_pItemView->setAlternatingRowColors(true ); m_pFilterLE->setPlaceholderText("Filter"); m_pFilterLE->setClearButtonShown(true); @@ -76,13 +77,11 @@ HistoryDock::HistoryDock(QWidget* parent) : QDockWidget(parent) mainLayout->addWidget(m_pSortByL ,0,0 ); mainLayout->addWidget(m_pSortByCBB ,0,1,1,2 ); mainLayout->addWidget(m_pAllTimeCB ,1,0,1,3 ); - mainLayout->addWidget(m_pLinkPB ,3,2,3,1 ); mainLayout->addWidget(m_pFromL ,2,0,1,2 ); mainLayout->addWidget(m_pFromDW ,3,0,1,2 ); mainLayout->addWidget(m_pToL ,4,0,1,2 ); mainLayout->addWidget(m_pToDW ,5,0,1,2 ); - mainLayout->addWidget(m_pItemView ,6,0,1,3 ); mainLayout->addWidget(m_pFilterLE ,7,0,1,3 ); @@ -95,11 +94,12 @@ HistoryDock::HistoryDock(QWidget* parent) : QDockWidget(parent) m_pCurrentFromDate = m_pFromDW->date(); m_pCurrentToDate = m_pToDW->date(); - connect(m_pAllTimeCB, SIGNAL(toggled(bool)), this, SLOT(enableDateRange(bool))); - connect(m_pFilterLE, SIGNAL(textChanged(QString)), this, SLOT(filter(QString))); - connect(m_pFromDW , SIGNAL(changed(QDate)), this, SLOT(updateLinkedFromDate(QDate))); - connect(m_pToDW , SIGNAL(changed(QDate)), this, SLOT(updateLinkedToDate(QDate))); - connect(m_pSortByCBB, SIGNAL(currentIndexChanged(int)), this, SLOT(reload())); + connect(m_pAllTimeCB, SIGNAL(toggled(bool)), this, SLOT(enableDateRange(bool) )); + connect(m_pFilterLE, SIGNAL(textChanged(QString)), this, SLOT(filter(QString) )); + connect(m_pFromDW , SIGNAL(changed(QDate)), this, SLOT(updateLinkedFromDate(QDate) )); + connect(m_pToDW , SIGNAL(changed(QDate)), this, SLOT(updateLinkedToDate(QDate) )); + connect(m_pSortByCBB, SIGNAL(currentIndexChanged(int)), this, SLOT(reload() )); + connect(AkonadiBackend::getInstance(), SIGNAL(collectionChanged()), this, SLOT(updateContactInfo() )); } HistoryDock::~HistoryDock() @@ -114,6 +114,13 @@ QString HistoryDock::getIdentity(HistoryTreeItem* item) return item->getName(); } +void HistoryDock::updateContactInfo() +{ + foreach(HistoryTreeItem* hitem, m_pHistory) { + hitem->updated(); + } +} + void HistoryDock::reload() { m_pItemView->clear(); diff --git a/kde/src/widgets/HistoryDock.h b/kde/src/widgets/HistoryDock.h index a1b6a698f9e66dcb8dd42b2e7dc4976bd50adf85..2180bad2eda876a2390d9e287f99df8f1429fc82 100644 --- a/kde/src/widgets/HistoryDock.h +++ b/kde/src/widgets/HistoryDock.h @@ -55,6 +55,7 @@ private slots: void updateLinkedFromDate(QDate date); void updateLinkedToDate(QDate date); void reload(); + void updateContactInfo(); }; #endif \ No newline at end of file diff --git a/kde/src/widgets/HistoryTreeItem.cpp b/kde/src/widgets/HistoryTreeItem.cpp index ce698d33fc2ec37b636b2d23206a3d73cdef1687..e34d749c3e88423e9cc1e7309faa784a990abd73 100644 --- a/kde/src/widgets/HistoryTreeItem.cpp +++ b/kde/src/widgets/HistoryTreeItem.cpp @@ -27,6 +27,8 @@ #include "lib/sflphone_const.h" #include "HistoryTreeItem.h" +#include "AkonadiBackend.h" +#include "lib/Contact.h" const char * HistoryTreeItem::callStateIcons[12] = {ICON_INCOMING, ICON_RINGING, ICON_CURRENT, ICON_DIALING, ICON_HOLD, ICON_FAILURE, ICON_BUSY, ICON_TRANSFER, ICON_TRANSF_HOLD, "", "", ICON_CONFERENCE}; @@ -54,24 +56,16 @@ void HistoryTreeItem::setCall(Call *call) labelIcon->setVisible(true); return; } - labelIcon = new QLabel(this); - labelPeerName = new QLabel(); - labelIcon = new QLabel(); + + labelIcon = new QLabel(this); + labelPeerName = new QLabel(); + labelIcon = new QLabel(); + labelIcon->setMinimumSize(70,48); labelIcon->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); labelCallNumber2 = new QLabel(itemCall->getPeerPhoneNumber()); QSpacerItem* verticalSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Expanding); - - - labelIcon->setPixmap(QPixmap(KIcon("user-identity").pixmap(QSize(48,48)))); - - if(! itemCall->getPeerName().trimmed().isEmpty()) { - labelPeerName = new QLabel("<b>"+itemCall->getPeerName()+"</b>"); - } - else { - labelPeerName = new QLabel("<b>Unknow</b>"); - } m_pTimeL = new QLabel(); m_pTimeL->setText(QDateTime::fromTime_t(itemCall->getStartTimeStamp().toUInt()).toString()); @@ -81,19 +75,17 @@ void HistoryTreeItem::setCall(Call *call) m_pDurationL->setText(QString("%1").arg(dur/3600,2)+":"+QString("%1").arg((dur%3600)/60,2)+":"+QString("%1").arg((dur%3600)%60,2)+" "); QGridLayout* mainLayout = new QGridLayout(this); - mainLayout->addWidget(labelIcon,0,0,4,1); - mainLayout->addWidget(labelPeerName,0,1); - mainLayout->addWidget(labelCallNumber2,1,1); - mainLayout->addWidget(m_pTimeL,2,1); - mainLayout->addItem(verticalSpacer,3,1); - mainLayout->addWidget(m_pDurationL,0,2,4,1); + mainLayout->addWidget( labelIcon,0,0,4,1 ); + mainLayout->addWidget( labelPeerName,0,1 ); + mainLayout->addWidget( labelCallNumber2,1,1 ); + mainLayout->addWidget( m_pTimeL,2,1 ); + mainLayout->addItem ( verticalSpacer,3,1 ); + mainLayout->addWidget( m_pDurationL,0,2,4,1 ); setLayout(mainLayout); setMinimumSize(QSize(50, 30)); - connect(itemCall, SIGNAL(changed()), - this, SLOT(updated())); - + connect(itemCall, SIGNAL(changed()), this, SLOT(updated())); updated(); m_pTimeStamp = itemCall->getStartTimeStamp().toUInt(); @@ -104,6 +96,22 @@ void HistoryTreeItem::setCall(Call *call) void HistoryTreeItem::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) {