From db76aa8eadb0cda1c3fc41ec653a0ab4e373c0e4 Mon Sep 17 00:00:00 2001
From: Edric Milaret <edric.ladent-milaret@savoirfairelinux.com>
Date: Mon, 11 May 2015 16:01:00 -0400
Subject: [PATCH] UI: add contact delegate

Display photo, name and number

Refs #73048

Change-Id: I3b347a57723d584fc4291f00e698f700ff719390
---
 RingWinClient.pro         |   6 ++-
 callwidget.cpp            |   2 +
 contactdelegate.cpp       | 102 ++++++++++++++++++++++++++++++++++++++
 contactdelegate.h         |  42 ++++++++++++++++
 images/account.png        | Bin 0 -> 444 bytes
 images/sort-variant.png   | Bin 0 -> 191 bytes
 windowscontactbackend.cpp |   9 ++--
 windowscontactbackend.h   |   2 +
 8 files changed, 157 insertions(+), 6 deletions(-)
 create mode 100644 contactdelegate.cpp
 create mode 100644 contactdelegate.h
 create mode 100644 images/account.png
 create mode 100644 images/sort-variant.png

diff --git a/RingWinClient.pro b/RingWinClient.pro
index 6186cba..3ce82f2 100644
--- a/RingWinClient.pro
+++ b/RingWinClient.pro
@@ -42,7 +42,8 @@ SOURCES += main.cpp\
     utils.cpp \
     wizarddialog.cpp \
     windowscontactbackend.cpp \
-    historydelegate.cpp
+    historydelegate.cpp \
+    contactdelegate.cpp
 
 HEADERS  += mainwindow.h \
     callwidget.h \
@@ -60,7 +61,8 @@ HEADERS  += mainwindow.h \
     utils.h \
     wizarddialog.h \
     windowscontactbackend.h \
-    historydelegate.h
+    historydelegate.h \
+    contactdelegate.h
 
 FORMS    += mainwindow.ui \
     callwidget.ui \
diff --git a/callwidget.cpp b/callwidget.cpp
index b61b80c..ff60724 100644
--- a/callwidget.cpp
+++ b/callwidget.cpp
@@ -30,6 +30,7 @@
 #include "categorizedcontactmodel.h"
 #include "windowscontactbackend.h"
 #include "historydelegate.h"
+#include "contactdelegate.h"
 
 #include "wizarddialog.h"
 
@@ -84,6 +85,7 @@ CallWidget::CallWidget(QWidget *parent) :
 
         CategorizedContactModel::instance()->setSortAlphabetical(false);
         ui->contactView->setModel(CategorizedContactModel::instance());
+        ui->contactView->setItemDelegate(new ContactDelegate());
 
         ui->speakerSlider->setValue(Audio::Settings::instance()->playbackVolume());
         ui->micSlider->setValue(Audio::Settings::instance()->captureVolume());
diff --git a/contactdelegate.cpp b/contactdelegate.cpp
new file mode 100644
index 0000000..e95b4fd
--- /dev/null
+++ b/contactdelegate.cpp
@@ -0,0 +1,102 @@
+/***************************************************************************
+ * Copyright (C) 2015 by Savoir-Faire Linux                                *
+ * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify    *
+ * it under the terms of the GNU General Public License as published by    *
+ * the Free Software Foundation; either version 3 of the License, or       *
+ * (at your option) any later version.                                     *
+ *                                                                         *
+ * This program is distributed in the hope that it will be useful,         *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ * GNU General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License       *
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ **************************************************************************/
+
+#include "contactdelegate.h"
+
+#include "person.h"
+#include "contactmethod.h"
+
+ContactDelegate::ContactDelegate(QObject *parent)
+    : QStyledItemDelegate(parent)
+{
+}
+
+
+void
+ContactDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
+                       const QModelIndex &index) const
+{
+    QStyleOptionViewItemV4 opt = option;
+    initStyleOption(&opt, index);
+
+    if (index.column() == 0) {
+        QString name = index.model()->data(index, Qt::DisplayRole).toString();
+        opt.text = "";
+        QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
+        style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
+        QRect rect = opt.rect;
+        QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ?
+                    QPalette::Normal : QPalette::Disabled;
+        if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
+            cg = QPalette::Inactive;
+        painter->setPen(opt.palette.color(cg, QPalette::Text));
+        painter->setOpacity(1.0);
+        painter->drawText(QRect(rect.left()+sizeImage_+5, rect.top(),
+                                rect.width(), rect.height()/2),
+                                opt.displayAlignment, name);
+
+        QVariant var_c = index.child(0,0).data(
+                    static_cast<int>(Person::Role::Object));
+        if (var_c.isValid()) {
+            Person *c = var_c.value<Person *>();
+            QVariant var_p = c->photo();
+            painter->drawRect(QRect(rect.left(), rect.top(),
+                                    sizeImage_+1, sizeImage_+1));
+            if (var_p.isValid()) {
+                painter->drawImage(QRect(rect.left()+1, rect.top()+1,
+                                         sizeImage_, sizeImage_),
+                                   var_p.value<QImage>());
+            } else {
+                QImage defaultImage(":images/account.png");
+                painter->drawImage(QRect(rect.left(), rect.top(),
+                                         sizeImage_, sizeImage_),
+                                   defaultImage);
+            }
+            switch (c->phoneNumbers().size()) {
+            case 0:
+                break;
+            case 1:
+            {
+                QString number;
+                QVariant var_n =
+                        c->phoneNumbers().first()->roleData(Qt::DisplayRole);
+                if (var_n.isValid())
+                    number = var_n.value<QString>();
+
+                painter->drawText(QRect(rect.left()+sizeImage_+5,
+                                        rect.top() + rect.height()/2,
+                                        rect.width(), rect.height()/2),
+                                  opt.displayAlignment, number);
+                break;
+            }
+            default:
+                /* more than one, for now don't show any of the contact methods */
+                break;
+            }
+        }
+    }
+}
+
+QSize
+ContactDelegate::sizeHint(const QStyleOptionViewItem &option,
+                          const QModelIndex &index) const
+{
+    QSize result = QStyledItemDelegate::sizeHint(option, index);
+    result.setHeight((result.height()*2)+2);
+    return result;
+}
diff --git a/contactdelegate.h b/contactdelegate.h
new file mode 100644
index 0000000..30d857a
--- /dev/null
+++ b/contactdelegate.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * Copyright (C) 2015 by Savoir-Faire Linux                                *
+ * Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>*
+ *                                                                         *
+ * This program is free software; you can redistribute it and/or modify    *
+ * it under the terms of the GNU General Public License as published by    *
+ * the Free Software Foundation; either version 3 of the License, or       *
+ * (at your option) any later version.                                     *
+ *                                                                         *
+ * This program is distributed in the hope that it will be useful,         *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
+ * GNU General Public License for more details.                            *
+ *                                                                         *
+ * You should have received a copy of the GNU General Public License       *
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ **************************************************************************/
+
+#ifndef CONTACTDELEGATE_H
+#define CONTACTDELEGATE_H
+
+#include <QObject>
+#include <QString>
+#include <QPainter>
+#include <QApplication>
+#include <QStyledItemDelegate>
+
+class ContactDelegate : public QStyledItemDelegate
+{
+    Q_OBJECT
+public:
+    explicit ContactDelegate(QObject *parent = 0);
+
+protected:
+    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+private:
+    constexpr static int sizeImage_ = 49;
+};
+
+#endif // CONTACTDELEGATE_H
diff --git a/images/account.png b/images/account.png
new file mode 100644
index 0000000000000000000000000000000000000000..086b752bb34604e3f576a285d1172f55229f2898
GIT binary patch
literal 444
zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F<YIY)RhkE(~Ds(|LD20|NtR
zfk$L90|SEx7`vU!wgU;46*#7Y^n&rZcRk?@42<rcE{-7?_ufu-^kQ}taGlS#$&jn6
zQ$cV~ll1!uduPu%I+eS)HzvWXiX~BDhiSFyVkaif!bDRK1H+f=d~QbZ|4V!E>fipC
zFIO@iFO)fcaVhg12GtL0T2CX7-@0Qp>wvBSyO_4gbVJ|l&G%>OUz3Or`*_>w%XS0#
zE8ERvEtt~;8PkGhAKB;BpuIpa@cM+PVy|uY|1P+6%f?}<zyhz>n8zG57YRN%xgt#0
zAu(ii+e_0`uGi#^elV|f;h30f{C#T9?abpRC)&1JMjc=+;G4sg`+&uQjW6Yl^#>*!
z=Kcc$6%6lw)SS#-&ibXHI>D>P+-j<2l~KCxvGt9GO)o>GPT#TSF5>JdOQ?xdj`W_Y
zm+7whETeSmneC09z0aD}HkBDMGk<n$o_{8{s5k7u!ef3eAGl<evPDSDynkZx|0~gx
hYZ;Cg$~>?C%-GCl#_xXXf)gkfJYD@<);T3K0RYc{t5*O3

literal 0
HcmV?d00001

diff --git a/images/sort-variant.png b/images/sort-variant.png
new file mode 100644
index 0000000000000000000000000000000000000000..1f926cc16ebe28805c7862f30048fbcbc3a8d2b6
GIT binary patch
literal 191
zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4mJh`hH$2z?F<YIY)RhkE(~Ds(|LD20|NtR
zfk$L90|SEx7`vU!wgU;46*#7Y^n&rZcRk?@3=CeLE{-7?_ugJT$jP9<!|YJ{e{Lyr
zph(xZchMRrwU;t5JPB3bE+?C(n%(VJ>c!Y_M``+wdHa7Pu!}I9c>7E!KJr@Z`S%S>
b3=Bsk6@{3^9B0OwfgIxL>gTe~DWM4fmcBJl

literal 0
HcmV?d00001

diff --git a/windowscontactbackend.cpp b/windowscontactbackend.cpp
index 95a7680..f8adb26 100644
--- a/windowscontactbackend.cpp
+++ b/windowscontactbackend.cpp
@@ -134,11 +134,12 @@ WindowsContactBackend::loadRun()
                     else if (name == "Photo") {
                         //FIXME: It seems to be possible to have multiple photo...
                         reader.readNext();
-                        if (reader.name().toString() == "Value") {
+                        if (reader.name().toString() == "Url") {
                             QString photoValue = reader.readElementText();
-                            QByteArray byteArray;
-                            byteArray.append(photoValue);
-                            p->setPhoto(byteArray);
+                            QImage photo;
+                            photo.load(photoValue);
+                            p->setPhoto(photo.scaled(sizePhoto_,sizePhoto_, Qt::KeepAspectRatio,
+                                                     Qt::SmoothTransformation));
                         }
                     }
                     else if (name == "EmailAddress") {
diff --git a/windowscontactbackend.h b/windowscontactbackend.h
index a2a3550..c804a06 100644
--- a/windowscontactbackend.h
+++ b/windowscontactbackend.h
@@ -24,6 +24,7 @@
 #include <QDir>
 #include <QXmlStreamReader>
 #include <QtConcurrent/QtConcurrent>
+#include <QImage>
 
 #include "person.h"
 #include "collectioninterface.h"
@@ -49,6 +50,7 @@ private:
     bool loadRun();
 private:
     CollectionMediator<Person>*  mediator_;
+    constexpr static int sizePhoto_ = 50;
 };
 
 class WindowsContactEditor : public CollectionEditor<Person>
-- 
GitLab