Commit 196545b2 authored by Alexandre Lision's avatar Alexandre Lision

persons: improve caching

The caching implemented in the ImageManipulationDelegate is preventing
the change of anycontact photo at runtime (even the profile one).

This commit monitors the changes on a photo and invalidates the cache
when a changes is detected.
The caching system was also not safe to use because it was building
indexes out of possibily invalid persons.
The BrokerVC and PersonLinkerVC now use the DecorationRole to increase
photo quality.

Change-Id: I1a364bbb0ade130868014a10ec127eff8a7e620b
Tuleap: #697
parent afa56dcf
......@@ -251,9 +251,7 @@ NSInteger const TXT_BUTTON_TAG = 500;
NSTextField* displayName = [result viewWithTag:DISPLAYNAME_TAG];
[displayName setStringValue:qIdx.data(Qt::DisplayRole).toString().toNSString()];
NSImageView* photoView = [result viewWithTag:IMAGE_TAG];
Person* p = qvariant_cast<Person*>(qIdx.data((int)Person::Role::Object));
QVariant photo = GlobalInstances::pixmapManipulator().contactPhoto(p, QSize(40,40));
[photoView setImage:QtMac::toNSImage(qvariant_cast<QPixmap>(photo))];
[photoView setImage:QtMac::toNSImage(qvariant_cast<QPixmap>(qIdx.data(Qt::DecorationRole)))];
return result;
}
......
......@@ -201,24 +201,8 @@ NSInteger const DETAILS_TAG = 300;
NSTableCellView *result = [outlineView makeViewWithIdentifier:@"MainCell" owner:outlineView];
NSImageView* photoView = [result viewWithTag:IMAGE_TAG];
NSTextField* displayName = [result viewWithTag:DISPLAYNAME_TAG];
if (!qIdx.isValid()) {
[photoView setImage:nil];
[displayName setStringValue:qIdx.data(Qt::DisplayRole).toString().toNSString()];
return result;
}
if (auto p = qvariant_cast<Person*>(qIdx.data((int)Person::Role::Object))) {
QVariant photo = GlobalInstances::pixmapManipulator().contactPhoto(p, QSize(35,35));
[photoView setImage:QtMac::toNSImage(qvariant_cast<QPixmap>(photo))];
} else {
QVariant photo = GlobalInstances::pixmapManipulator().contactPhoto(nil, QSize(35,35));
[photoView setImage:QtMac::toNSImage(qvariant_cast<QPixmap>(photo))];
}
[photoView setImage:QtMac::toNSImage(qvariant_cast<QPixmap>(qIdx.data(Qt::DecorationRole)))];
[displayName setStringValue:qIdx.data(Qt::DisplayRole).toString().toNSString()];
return result;
}
......
......@@ -21,6 +21,7 @@
//Qt
#import <QSize>
#import <QPair>
#import <QtGui/qpixmap.h>
//Ring
......@@ -63,7 +64,7 @@ namespace Interfaces {
CGImageRef resizeCGImage(CGImageRef image, const QSize& size);
QHash<QString, QPixmap> m_hDefaultUserPixmap;
QHash<QString, QPixmap> m_hContactsPixmap;
QHash<QString, QPair<QMetaObject::Connection, QPixmap>> m_hContactsPixmap;
/**
* Return a version of size destSize centered of the bigger photo
......
......@@ -45,16 +45,17 @@ namespace Interfaces {
QVariant ImageManipulationDelegate::contactPhoto(Person* c, const QSize& size, bool displayPresence) {
const int radius = size.height() / 2;
auto index = QStringLiteral("%1%2%3").arg(size.width())
.arg(size.height())
.arg(QString::fromUtf8(c->uid()));
if (m_hContactsPixmap.contains(index)) {
return m_hContactsPixmap.value(index);
}
QPixmap pxm;
if (c && c->photo().isValid()) {
// Check cache
auto index = QStringLiteral("%1%2%3").arg(size.width())
.arg(size.height())
.arg(QString::fromUtf8(c->uid()));
if (m_hContactsPixmap.contains(index)) {
return m_hContactsPixmap.value(index).second;
}
QPixmap contactPhoto(qvariant_cast<QPixmap>(c->photo()).scaled(size, Qt::KeepAspectRatioByExpanding,
Qt::SmoothTransformation));
......@@ -89,12 +90,28 @@ namespace Interfaces {
painter.setPen (Qt::black );
painter.setCompositionMode (QPainter::CompositionMode_SourceIn);
painter.drawRoundedRect(0,0,pxm.height(),pxm.height(),radius,radius);
}
else {
pxm = drawDefaultUserPixmap(size);
}
m_hContactsPixmap.insert(index, pxm);
// Save in cache
QPair<QMetaObject::Connection, QPixmap> toInsert;
toInsert.first = QObject::connect(c,
&Person::changed,
[=]() {
if (c) {
auto index = QStringLiteral("%1%2%3").arg(size.width())
.arg(size.height())
.arg(QString::fromUtf8(c->uid()));
if (m_hContactsPixmap.contains(index)) {
QObject::disconnect(m_hContactsPixmap.value(index).first);
m_hContactsPixmap.remove(index);
}
}
});
toInsert.second = pxm;
m_hContactsPixmap.insert(index, toInsert);
} else {
return drawDefaultUserPixmap(size);
}
return pxm;
}
......
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