Commit 7a166e48 authored by Alexandre Lision's avatar Alexandre Lision

delegates: adapt to new LRC interfaces API

Issue: #79656
Change-Id: I6d63c8fda34d931ee3650f82288c950a7c858303
parent 7f8351be
......@@ -39,6 +39,7 @@
#import <personmodel.h>
#import <contactmethod.h>
#import <numbercategorymodel.h>
#import <globalinstances.h>
#import "QNSTreeController.h"
#import "delegates/ImageManipulationDelegate.h"
......@@ -243,7 +244,7 @@ public:
if(!qIdx.parent().isValid()) {
pCell.title = qIdx.data(Qt::DisplayRole).toString().toNSString();
Person* p = qvariant_cast<Person*>(qIdx.data((int)Person::Role::Object));
QVariant photo = ImageManipulationDelegate::instance()->contactPhoto(p, QSize(35,35));
QVariant photo = GlobalInstances::pixmapManipulator().contactPhoto(p, QSize(35,35));
[pCell setPersonImage:QtMac::toNSImage(qvariant_cast<QPixmap>(photo))];
} else {
pCell.title = qIdx.data(Qt::DisplayRole).toString().toNSString();
......
......@@ -42,6 +42,7 @@
#import <callmodel.h>
#import <contactmethod.h>
#import <categorizedcontactmodel.h>
#import <globalinstances.h>
#import "backends/AddressBookBackend.h"
#import "QNSTreeController.h"
......@@ -79,7 +80,6 @@ public:
-(void) awakeFromNib
{
new ImageManipulationDelegate();
NSLog(@"INIT PersonsVC");
contactProxyModel = new ReachablePersonModel(CategorizedContactModel::instance());
contactProxyModel->setSortRole(static_cast<int>(Qt::DisplayRole));
......@@ -216,7 +216,7 @@ public:
pCell.title = qIdx.data(Qt::DisplayRole).toString().toNSString();
if(((NSTreeNode*)item).indexPath.length == 2) {
Person* p = qvariant_cast<Person*>(qIdx.data((int)Person::Role::Object));
QVariant photo = ImageManipulationDelegate::instance()->contactPhoto(p, QSize(35,35));
QVariant photo = GlobalInstances::pixmapManipulator().contactPhoto(p, QSize(35,35));
[pCell setPersonImage:QtMac::toNSImage(qvariant_cast<QPixmap>(photo))];
}
}
......
/*
* Copyright (C) 2015 Savoir-Faire Linux Inc.
* Copyright (C) 2015 Savoir-faire Linux Inc.
* Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
......@@ -27,31 +27,42 @@
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef IMAGEMANIPULATION_H
#define IMAGEMANIPULATION_H
#import <QuartzCore/QuartzCore.h>
#import <delegates/pixmapmanipulationdelegate.h>
#import <interfaces/pixmapmanipulatori.h>
#import <call.h>
class Person;
class QPixmap;
class ImageManipulationDelegate : public PixmapManipulationDelegate {
namespace Interfaces {
public:
ImageManipulationDelegate();
QVariant contactPhoto(Person* c, const QSize& size, bool displayPresence = true) override;
virtual QByteArray toByteArray(const QVariant& pxm) override;
virtual QVariant personPhoto(const QByteArray& data, const QString& type = "PNG") override;
class ImageManipulationDelegate : public PixmapManipulatorI {
private:
//Helper
QPixmap drawDefaultUserPixmap(const QSize& size, bool displayPresence, bool isPresent);
CGImageRef resizeCGImage(CGImageRef image, const QSize& size);
public:
ImageManipulationDelegate();
QVariant contactPhoto(Person* c, const QSize& size, bool displayPresence = true) override;
virtual QByteArray toByteArray(const QVariant& pxm) override;
virtual QVariant personPhoto(const QByteArray& data, const QString& type = "PNG") override;
QVariant callPhoto(Call* c, const QSize& size, bool displayPresence = true) override;
QVariant callPhoto(const ContactMethod* n, const QSize& size, bool displayPresence = true) override;
};
/* TODO: the following methods return an empty QVariant/QByteArray */
QVariant numberCategoryIcon(const QVariant& p, const QSize& size, bool displayPresence = false, bool isPresent = false) override;
QVariant securityIssueIcon(const QModelIndex& index) override;
QVariant collectionIcon(const CollectionInterface* interface, PixmapManipulatorI::CollectionIconHint hint = PixmapManipulatorI::CollectionIconHint::NONE) const override;
QVariant securityLevelIcon(const SecurityEvaluationModel::SecurityLevel level) const override;
QVariant historySortingCategoryIcon(const CategorizedHistoryModel::SortedProxy::Categories cat) const override;
QVariant contactSortingCategoryIcon(const CategorizedContactModel::SortedProxy::Categories cat) const override;
QVariant userActionIcon(const UserActionElement& state) const override;
private:
//Helper
QPixmap drawDefaultUserPixmap(const QSize& size, bool displayPresence, bool isPresent);
CGImageRef resizeCGImage(CGImageRef image, const QSize& size);
};
} // namespace Interfaces
#endif // IMAGEMANIPULATION_H
......@@ -47,114 +47,183 @@
#import <person.h>
#import <contactmethod.h>
ImageManipulationDelegate::ImageManipulationDelegate() : PixmapManipulationDelegate()
{
namespace Interfaces {
}
ImageManipulationDelegate::ImageManipulationDelegate()
{
QVariant ImageManipulationDelegate::contactPhoto(Person* c, const QSize& size, bool displayPresence) {
const int radius = (size.height() > 35) ? 7 : 5;
}
QVariant ImageManipulationDelegate::contactPhoto(Person* c, const QSize& size, bool displayPresence) {
const int radius = (size.height() > 35) ? 7 : 5;
QPixmap pxm;
if (c->photo().isValid()) {
QPixmap contactPhoto((qvariant_cast<QPixmap>(c->photo())).scaledToWidth(size.height()-6));
pxm = QPixmap(size);
pxm.fill(Qt::transparent);
QPainter painter(&pxm);
//Clear the pixmap
painter.setCompositionMode(QPainter::CompositionMode_Clear);
painter.fillRect(0,0,size.width(),size.height(),QBrush(Qt::white));
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
//Add corner radius to the Pixmap
QRect pxRect = contactPhoto.rect();
QBitmap mask(pxRect.size());
QPainter customPainter(&mask);
customPainter.setRenderHint (QPainter::Antialiasing, true );
customPainter.fillRect (pxRect , Qt::white );
customPainter.setBackground (Qt::black );
customPainter.setBrush (Qt::black );
customPainter.drawRoundedRect(pxRect,radius,radius);
contactPhoto.setMask(mask);
painter.drawPixmap(3,3,contactPhoto);
painter.setBrush(Qt::NoBrush);
painter.setPen(Qt::white);
painter.setRenderHint (QPainter::Antialiasing, true );
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.drawRoundedRect(3,3,pxm.height()-6,pxm.height()-6,radius,radius);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
}
else {
pxm = drawDefaultUserPixmap(size, false, false);
}
return pxm;
}
QVariant
ImageManipulationDelegate::callPhoto(Call* c, const QSize& size, bool displayPresence)
{
return callPhoto(c->peerContactMethod(), size, displayPresence);
}
QVariant
ImageManipulationDelegate::callPhoto(const ContactMethod* n, const QSize& size, bool displayPresence)
{
if (n->contact()) {
return contactPhoto(n->contact(), size, displayPresence);
} else {
return drawDefaultUserPixmap(size, false, false);
}
}
QVariant ImageManipulationDelegate::personPhoto(const QByteArray& data, const QString& type)
{
QImage image;
//For now, ENCODING is only base64 and image type PNG or JPG
const bool ret = image.loadFromData(QByteArray::fromBase64(data),type.toLatin1());
if (!ret)
qDebug() << "vCard image loading failed";
QPixmap pxm;
if (c->photo().isValid()) {
QPixmap contactPhoto((qvariant_cast<QPixmap>(c->photo())).scaledToWidth(size.height()-6));
pxm = QPixmap(size);
return QPixmap::fromImage(image);
}
QByteArray ImageManipulationDelegate::toByteArray(const QVariant& pxm)
{
//Preparation of our QPixmap
QByteArray bArray;
QBuffer buffer(&bArray);
buffer.open(QIODevice::WriteOnly);
//PNG ?
(qvariant_cast<QPixmap>(pxm)).save(&buffer, "PNG");
buffer.close();
return bArray;
}
QPixmap ImageManipulationDelegate::drawDefaultUserPixmap(const QSize& size, bool displayPresence, bool isPresent) {
QPixmap pxm(size);
pxm.fill(Qt::transparent);
QPainter painter(&pxm);
//Clear the pixmap
painter.setCompositionMode(QPainter::CompositionMode_Clear);
painter.fillRect(0,0,size.width(),size.height(),QBrush(Qt::white));
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
//Add corner radius to the Pixmap
QRect pxRect = contactPhoto.rect();
QBitmap mask(pxRect.size());
QPainter customPainter(&mask);
customPainter.setRenderHint (QPainter::Antialiasing, true );
customPainter.fillRect (pxRect , Qt::white );
customPainter.setBackground (Qt::black );
customPainter.setBrush (Qt::black );
customPainter.drawRoundedRect(pxRect,radius,radius);
contactPhoto.setMask(mask);
painter.drawPixmap(3,3,contactPhoto);
painter.setBrush(Qt::NoBrush);
painter.setPen(Qt::white);
painter.setRenderHint (QPainter::Antialiasing, true );
painter.setCompositionMode(QPainter::CompositionMode_SourceIn);
painter.drawRoundedRect(3,3,pxm.height()-6,pxm.height()-6,radius,radius);
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
// create the image somehow, load from file, draw into it...
auto sourceImgRef = CGImageSourceCreateWithData((CFDataRef)[[NSImage imageNamed:@"NSUser"] TIFFRepresentation], NULL);
auto imgRef = CGImageSourceCreateImageAtIndex(sourceImgRef, 0, NULL);
auto finalImgRef = resizeCGImage(imgRef, size);
painter.drawPixmap(3,3,QtMac::fromCGImageRef(finalImgRef));
CFRelease(sourceImgRef);
CFRelease(imgRef);
CFRelease(finalImgRef);
return pxm;
}
CGImageRef ImageManipulationDelegate::resizeCGImage(CGImageRef image, const QSize& size) {
// create context, keeping original image properties
CGColorSpaceRef colorspace = CGImageGetColorSpace(image);
CGContextRef context = CGBitmapContextCreate(NULL, size.width(), size.height(),
CGImageGetBitsPerComponent(image),
size.width() * CGImageGetBitsPerComponent(image),
colorspace,
CGImageGetAlphaInfo(image));
if(context == NULL)
return nil;
// draw image to context (resizing it)
CGContextDrawImage(context, CGRectMake(0, 0, size.width(), size.height()), image);
// extract resulting image from context
CGImageRef imgRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
return imgRef;
}
QVariant
ImageManipulationDelegate::numberCategoryIcon(const QVariant& p, const QSize& size, bool displayPresence, bool isPresent)
{
Q_UNUSED(p)
Q_UNUSED(size)
Q_UNUSED(displayPresence)
Q_UNUSED(isPresent)
return QVariant();
}
QVariant
ImageManipulationDelegate::securityIssueIcon(const QModelIndex& index)
{
Q_UNUSED(index)
return QVariant();
}
QVariant
ImageManipulationDelegate::collectionIcon(const CollectionInterface* interface, PixmapManipulatorI::CollectionIconHint hint) const
{
Q_UNUSED(interface)
Q_UNUSED(hint)
return QVariant();
}
QVariant
ImageManipulationDelegate::securityLevelIcon(const SecurityEvaluationModel::SecurityLevel level) const
{
Q_UNUSED(level)
return QVariant();
}
QVariant
ImageManipulationDelegate::historySortingCategoryIcon(const CategorizedHistoryModel::SortedProxy::Categories cat) const
{
Q_UNUSED(cat)
return QVariant();
}
QVariant
ImageManipulationDelegate::contactSortingCategoryIcon(const CategorizedContactModel::SortedProxy::Categories cat) const
{
Q_UNUSED(cat)
return QVariant();
}
else {
pxm = drawDefaultUserPixmap(size, false, false);
QVariant
ImageManipulationDelegate::userActionIcon(const UserActionElement& state) const
{
Q_UNUSED(state)
return QVariant();
}
return pxm;
}
QVariant ImageManipulationDelegate::personPhoto(const QByteArray& data, const QString& type)
{
QImage image;
//For now, ENCODING is only base64 and image type PNG or JPG
const bool ret = image.loadFromData(QByteArray::fromBase64(data),type.toLatin1());
if (!ret)
qDebug() << "vCard image loading failed";
return QPixmap::fromImage(image);
}
QByteArray ImageManipulationDelegate::toByteArray(const QVariant& pxm)
{
//Preparation of our QPixmap
QByteArray bArray;
QBuffer buffer(&bArray);
buffer.open(QIODevice::WriteOnly);
//PNG ?
(qvariant_cast<QPixmap>(pxm)).save(&buffer, "PNG");
buffer.close();
return bArray;
}
QPixmap ImageManipulationDelegate::drawDefaultUserPixmap(const QSize& size, bool displayPresence, bool isPresent) {
QPixmap pxm(size);
pxm.fill(Qt::transparent);
QPainter painter(&pxm);
// create the image somehow, load from file, draw into it...
auto sourceImgRef = CGImageSourceCreateWithData((CFDataRef)[[NSImage imageNamed:@"NSUser"] TIFFRepresentation], NULL);
auto imgRef = CGImageSourceCreateImageAtIndex(sourceImgRef, 0, NULL);
auto finalImgRef = resizeCGImage(imgRef, size);
painter.drawPixmap(3,3,QtMac::fromCGImageRef(finalImgRef));
CFRelease(sourceImgRef);
CFRelease(imgRef);
CFRelease(finalImgRef);
return pxm;
}
CGImageRef ImageManipulationDelegate::resizeCGImage(CGImageRef image, const QSize& size) {
// create context, keeping original image properties
CGColorSpaceRef colorspace = CGImageGetColorSpace(image);
CGContextRef context = CGBitmapContextCreate(NULL, size.width(), size.height(),
CGImageGetBitsPerComponent(image),
size.width() * CGImageGetBitsPerComponent(image),
colorspace,
CGImageGetAlphaInfo(image));
if(context == NULL)
return nil;
// draw image to context (resizing it)
CGContextDrawImage(context, CGRectMake(0, 0, size.width(), size.height()), image);
// extract resulting image from context
CGImageRef imgRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
return imgRef;
}
} // namespace Interfaces
......@@ -29,9 +29,13 @@
*/
#import <AppKit/NSApplication.h> // NSApplicationMain
#import <qapplication.h>
#import <globalinstances.h>
#import <memory>
#import <QDebug>
#import <QDir>
#import "delegates/ImageManipulationDelegate.h"
int main(int argc, const char *argv[]) {
QDir dir(QString::fromUtf8(argv[0]));
......@@ -44,6 +48,9 @@ int main(int argc, const char *argv[]) {
QApplication* app = new QApplication(argc, const_cast<char**>(argv));
app->setAttribute(Qt::AA_MacPluginApplication);
GlobalInstances::setPixmapManipulator(std::unique_ptr<Interfaces::ImageManipulationDelegate>(new Interfaces::ImageManipulationDelegate()));
return NSApplicationMain(argc, argv);
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment