added various sizes in icons cache so that we do not always allocate the largest sizes

This commit is contained in:
csoler 2019-06-04 11:49:26 +02:00
parent e66fb923fb
commit 94cbe65142
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
18 changed files with 107 additions and 64 deletions

View File

@ -322,8 +322,8 @@ void ChatLobbyWidget::lobbyTreeWidgetCustomPopupMenu(QPoint)
QPixmap pixmap ; QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap)) if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap, GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(*it) ; pixmap = GxsIdDetails::makeDefaultIcon(*it,GxsIdDetails::SMALL) ;
QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(subscribeChatLobbyAs())); QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(subscribeChatLobbyAs()));
action->setData(QString::fromStdString((*it).toStdString())) ; action->setData(QString::fromStdString((*it).toStdString())) ;

View File

@ -270,8 +270,8 @@ void CreateCircleDialog::addMember(const RsGxsIdGroup &idGroup)
QPixmap pixmap ; QPixmap pixmap ;
if(idGroup.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idGroup.mImage.mData, idGroup.mImage.mSize, pixmap)) if(idGroup.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idGroup.mImage.mData, idGroup.mImage.mSize, pixmap, GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(idGroup.mMeta.mGroupId)); pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(idGroup.mMeta.mGroupId),GxsIdDetails::SMALL);
if (idGroup.mPgpKnown){ if (idGroup.mPgpKnown){
RsPeerDetails details; RsPeerDetails details;
@ -331,8 +331,8 @@ void CreateCircleDialog::addCircle(const RsGxsCircleDetails &cirDetails)
QPixmap pixmap ; QPixmap pixmap ;
if(gxs_details.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(gxs_details.mAvatar.mData, gxs_details.mAvatar.mSize, pixmap)) if(gxs_details.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(gxs_details.mAvatar.mData, gxs_details.mAvatar.mSize, pixmap, GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(gxs_details.mId); pixmap = GxsIdDetails::makeDefaultIcon(gxs_details.mId,GxsIdDetails::SMALL);
addMember(keyId, idtype, nickname, QIcon(pixmap)); addMember(keyId, idtype, nickname, QIcon(pixmap));
@ -814,8 +814,8 @@ void CreateCircleDialog::loadIdentities(uint32_t token)
QPixmap pixmap ; QPixmap pixmap ;
if(idGroup.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idGroup.mImage.mData, idGroup.mImage.mSize, pixmap)) if(idGroup.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idGroup.mImage.mData, idGroup.mImage.mSize, pixmap, GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(idGroup.mMeta.mGroupId)) ; pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(idGroup.mMeta.mGroupId),GxsIdDetails::SMALL) ;
if (idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility) if (idGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility)
{ {

View File

@ -183,11 +183,11 @@ void IdDetailsDialog::insertIdDetails(uint32_t token)
QPixmap pixmap; QPixmap pixmap;
if(data.mImage.mSize > 0 && GxsIdDetails::loadPixmapFromData(data.mImage.mData, data.mImage.mSize, pixmap)) if(data.mImage.mSize > 0 && GxsIdDetails::loadPixmapFromData(data.mImage.mData, data.mImage.mSize, pixmap, GxsIdDetails::LARGE))
ui->avatarLabel->setPixmap(pixmap); ui->avatarLabel->setPixmap(pixmap);
else else
{ {
pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(data.mMeta.mGroupId)) ; pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(data.mMeta.mGroupId),GxsIdDetails::LARGE) ;
ui->avatarLabel->setPixmap(pixmap) ; // we need to use the default pixmap here, generated from the ID ui->avatarLabel->setPixmap(pixmap) ; // we need to use the default pixmap here, generated from the ID
} }

View File

@ -752,8 +752,8 @@ void IdDialog::loadCircleGroupMeta(const uint32_t &token)
QPixmap pixmap ; QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap)) if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(it->first) ; pixmap = GxsIdDetails::makeDefaultIcon(it->first,GxsIdDetails::SMALL) ;
if(has_id) if(has_id)
subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ; subitem->setText(CIRCLEGROUP_CIRCLE_COL_GROUPNAME, QString::fromUtf8(idd.mNickname.c_str())) ;
@ -1551,8 +1551,8 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
QPixmap pixmap ; QPixmap pixmap ;
if(data.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(data.mImage.mData, data.mImage.mSize, pixmap)) if(data.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(data.mImage.mData, data.mImage.mSize, pixmap,GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(data.mMeta.mGroupId)) ; pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(data.mMeta.mGroupId),GxsIdDetails::SMALL) ;
item->setIcon(RSID_COL_NICKNAME, QIcon(pixmap)); item->setIcon(RSID_COL_NICKNAME, QIcon(pixmap));
@ -1797,8 +1797,8 @@ void IdDialog::insertIdDetails(uint32_t token)
QPixmap pixmap ; QPixmap pixmap ;
if(data.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(data.mImage.mData, data.mImage.mSize, pixmap)) if(data.mImage.mSize == 0 || !GxsIdDetails::loadPixmapFromData(data.mImage.mData, data.mImage.mSize, pixmap,GxsIdDetails::LARGE))
pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(data.mMeta.mGroupId)) ; pixmap = GxsIdDetails::makeDefaultIcon(RsGxsId(data.mMeta.mGroupId),GxsIdDetails::LARGE) ;
#ifdef ID_DEBUG #ifdef ID_DEBUG
std::cerr << "Setting header frame image : " << pixmap.width() << " x " << pixmap.height() << std::endl; std::cerr << "Setting header frame image : " << pixmap.width() << " x " << pixmap.height() << std::endl;
@ -2470,8 +2470,8 @@ void IdDialog::IdListCustomPopupMenu( QPoint )
QPixmap pixmap ; QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap)) if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(*it) ; pixmap = GxsIdDetails::makeDefaultIcon(*it,GxsIdDetails::SMALL) ;
QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity())); QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity()));
action->setData(QString::fromStdString((*it).toStdString())) ; action->setData(QString::fromStdString((*it).toStdString())) ;

View File

@ -258,7 +258,7 @@ void IdEditDialog::loadExistingId(uint32_t token)
QPixmap avatar; QPixmap avatar;
if (mEditGroup.mImage.mSize > 0) if (mEditGroup.mImage.mSize > 0)
GxsIdDetails::loadPixmapFromData(mEditGroup.mImage.mData, mEditGroup.mImage.mSize, avatar); GxsIdDetails::loadPixmapFromData(mEditGroup.mImage.mData, mEditGroup.mImage.mSize, avatar,GxsIdDetails::LARGE);
setAvatar(avatar); setAvatar(avatar);

View File

@ -467,8 +467,8 @@ void PeopleDialog::iw_AddButtonClickedExt()
QPixmap pixmap ; QPixmap pixmap ;
if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap)) if(idd.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(idd.mAvatar.mData, idd.mAvatar.mSize, pixmap,GxsIdDetails::SMALL))
pixmap = GxsIdDetails::makeDefaultIcon(*it) ; pixmap = GxsIdDetails::makeDefaultIcon(*it,GxsIdDetails::SMALL) ;
QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity())); QAction *action = mnu->addAction(QIcon(pixmap), QString("%1 (%2)").arg(QString::fromUtf8(idd.mNickname.c_str()), QString::fromStdString((*it).toStdString())), this, SLOT(chatIdentity()));
action->setData(QString::fromStdString((*it).toStdString()) + ";" + QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString())) ; action->setData(QString::fromStdString((*it).toStdString()) + ";" + QString::fromStdString(dest->groupInfo().mMeta.mGroupId.toStdString())) ;

View File

@ -165,7 +165,7 @@ void PostedDialog::loadGroupSummaryToken(const uint32_t &token, std::list<RsGrou
if (group.mGroupImage.mData != NULL) { if (group.mGroupImage.mData != NULL) {
QPixmap image; QPixmap image;
GxsIdDetails::loadPixmapFromData(group.mGroupImage.mData, group.mGroupImage.mSize, image); GxsIdDetails::loadPixmapFromData(group.mGroupImage.mData, group.mGroupImage.mSize, image,GxsIdDetails::ORIGINAL);
postedData->mIcon[group.mMeta.mGroupId] = image; postedData->mIcon[group.mMeta.mGroupId] = image;
} }

View File

@ -164,7 +164,7 @@ bool PostedGroupDialog::service_loadGroup(uint32_t token, Mode /*mode*/, RsGroup
if (group.mGroupImage.mData) { if (group.mGroupImage.mData) {
QPixmap pixmap; QPixmap pixmap;
if (GxsIdDetails::loadPixmapFromData(group.mGroupImage.mData, group.mGroupImage.mSize, pixmap)) if (GxsIdDetails::loadPixmapFromData(group.mGroupImage.mData, group.mGroupImage.mSize, pixmap,GxsIdDetails::ORIGINAL))
setLogo(pixmap); setLogo(pixmap);
} else { } else {

View File

@ -256,7 +256,7 @@ void PostedItem::fill()
if(mPost.mImage.mData != NULL) if(mPost.mImage.mData != NULL)
{ {
QPixmap pixmap; QPixmap pixmap;
GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap); GxsIdDetails::loadPixmapFromData(mPost.mImage.mData, mPost.mImage.mSize, pixmap,GxsIdDetails::ORIGINAL);
// Wiping data - as its been passed to thumbnail. // Wiping data - as its been passed to thumbnail.
QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); QPixmap sqpixmap = pixmap.scaled(desired_width,desired_height, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);

View File

@ -41,7 +41,7 @@ void AvatarDefs::getOwnAvatar(QPixmap &avatar, const QString& defaultImage)
} }
/* load image */ /* load image */
GxsIdDetails::loadPixmapFromData(data, size, avatar) ; GxsIdDetails::loadPixmapFromData(data, size, avatar,GxsIdDetails::ORIGINAL) ;
free(data); free(data);
} }
@ -58,7 +58,7 @@ void AvatarDefs::getAvatarFromSslId(const RsPeerId& sslId, QPixmap &avatar, cons
} }
/* load image */ /* load image */
GxsIdDetails::loadPixmapFromData(data, size, avatar) ; GxsIdDetails::loadPixmapFromData(data, size, avatar, GxsIdDetails::LARGE) ;
free(data); free(data);
} }
@ -77,8 +77,8 @@ void AvatarDefs::getAvatarFromGxsId(const RsGxsId& gxsId, QPixmap &avatar, const
/* load image */ /* load image */
if(details.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(details.mAvatar.mData, details.mAvatar.mSize, avatar)) if(details.mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(details.mAvatar.mData, details.mAvatar.mSize, avatar,GxsIdDetails::LARGE))
avatar = GxsIdDetails::makeDefaultIcon(gxsId); avatar = GxsIdDetails::makeDefaultIcon(gxsId,GxsIdDetails::LARGE);
} }
void AvatarDefs::getAvatarFromGpgId(const RsPgpId& gpgId, QPixmap &avatar, const QString& defaultImage) void AvatarDefs::getAvatarFromGpgId(const RsPgpId& gpgId, QPixmap &avatar, const QString& defaultImage)

View File

@ -45,8 +45,8 @@ AvatarDialog::AvatarDialog(QWidget *parent) :
updateInterface(); updateInterface();
} }
const int AvatarDialog::RS_AVATAR_IMAGE_W = 128; const int AvatarDialog::RS_AVATAR_DEFAULT_IMAGE_W = 64;
const int AvatarDialog::RS_AVATAR_IMAGE_H = 128; const int AvatarDialog::RS_AVATAR_DEFAULT_IMAGE_H = 64;
AvatarDialog::~AvatarDialog() AvatarDialog::~AvatarDialog()
{ {
@ -55,7 +55,7 @@ AvatarDialog::~AvatarDialog()
void AvatarDialog::changeAvatar() void AvatarDialog::changeAvatar()
{ {
QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Avatar"), RS_AVATAR_IMAGE_W,RS_AVATAR_IMAGE_H); QPixmap img = misc::getOpenThumbnailedPicture(this, tr("Load Avatar"), RS_AVATAR_DEFAULT_IMAGE_W,RS_AVATAR_DEFAULT_IMAGE_H);
if (img.isNull()) if (img.isNull())
return; return;

View File

@ -35,8 +35,8 @@ class AvatarDialog : public QDialog
Q_OBJECT Q_OBJECT
public: public:
static const int RS_AVATAR_IMAGE_W ; static const int RS_AVATAR_DEFAULT_IMAGE_W ;
static const int RS_AVATAR_IMAGE_H ; static const int RS_AVATAR_DEFAULT_IMAGE_H ;
AvatarDialog(QWidget *parent = 0); AvatarDialog(QWidget *parent = 0);
~AvatarDialog(); ~AvatarDialog();

View File

@ -135,7 +135,7 @@ void GxsChannelGroupItem::fill()
if (mGroup.mImage.mData != NULL) { if (mGroup.mImage.mData != NULL) {
QPixmap chanImage; QPixmap chanImage;
GxsIdDetails::loadPixmapFromData(mGroup.mImage.mData, mGroup.mImage.mSize, chanImage); GxsIdDetails::loadPixmapFromData(mGroup.mImage.mData, mGroup.mImage.mSize, chanImage,GxsIdDetails::ORIGINAL);
ui->logoLabel->setPixmap(QPixmap(chanImage)); ui->logoLabel->setPixmap(QPixmap(chanImage));
} }

View File

@ -393,7 +393,7 @@ void GxsChannelPostItem::fill()
if(mPost.mThumbnail.mData != NULL) if(mPost.mThumbnail.mData != NULL)
{ {
QPixmap thumbnail; QPixmap thumbnail;
GxsIdDetails::loadPixmapFromData(mPost.mThumbnail.mData, mPost.mThumbnail.mSize, thumbnail); GxsIdDetails::loadPixmapFromData(mPost.mThumbnail.mData, mPost.mThumbnail.mSize, thumbnail,GxsIdDetails::ORIGINAL);
// Wiping data - as its been passed to thumbnail. // Wiping data - as its been passed to thumbnail.
ui->logoLabel->setPixmap(thumbnail); ui->logoLabel->setPixmap(thumbnail);
} }

View File

@ -138,7 +138,7 @@ void PostedGroupItem::fill()
if (mGroup.mGroupImage.mData != NULL) { if (mGroup.mGroupImage.mData != NULL) {
QPixmap postedImage; QPixmap postedImage;
GxsIdDetails::loadPixmapFromData(mGroup.mGroupImage.mData, mGroup.mGroupImage.mSize, postedImage); GxsIdDetails::loadPixmapFromData(mGroup.mGroupImage.mData, mGroup.mGroupImage.mSize, postedImage,GxsIdDetails::ORIGINAL);
ui->logoLabel->setPixmap(QPixmap(postedImage)); ui->logoLabel->setPixmap(QPixmap(postedImage));
} else { } else {
ui->logoLabel->setPixmap(QPixmap(":/images/posted_64.png")); ui->logoLabel->setPixmap(QPixmap(":/images/posted_64.png"));

View File

@ -68,10 +68,10 @@
uint32_t GxsIdDetails::mImagesAllocated = 0; uint32_t GxsIdDetails::mImagesAllocated = 0;
time_t GxsIdDetails::mLastIconCacheCleaning = time(NULL); time_t GxsIdDetails::mLastIconCacheCleaning = time(NULL);
std::map<RsGxsId,std::pair<time_t,QPixmap> > GxsIdDetails::mDefaultIconCache ; std::map<RsGxsId,std::pair<time_t,QPixmap>[4] > GxsIdDetails::mDefaultIconCache ;
#define ICON_CACHE_STORAGE_TIME 600 #define ICON_CACHE_STORAGE_TIME 60
#define DELAY_BETWEEN_ICON_CACHE_CLEANING 300 #define DELAY_BETWEEN_ICON_CACHE_CLEANING 30
void ReputationItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const void ReputationItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{ {
@ -459,7 +459,7 @@ static bool findTagIcon(int tag_class, int /*tag_type*/, QIcon &icon)
* Bring the source code from this adaptation: * Bring the source code from this adaptation:
* http://francisshanahan.com/identicon5/test.html * http://francisshanahan.com/identicon5/test.html
*/ */
const QPixmap GxsIdDetails::makeDefaultIcon(const RsGxsId& id) const QPixmap GxsIdDetails::makeDefaultIcon(const RsGxsId& id, AvatarSize size)
{ {
checkCleanImagesCache(); checkCleanImagesCache();
@ -471,17 +471,28 @@ const QPixmap GxsIdDetails::makeDefaultIcon(const RsGxsId& id)
// now look for the icon // now look for the icon
auto it = mDefaultIconCache.find(id); auto& it = mDefaultIconCache[id];
if(it != mDefaultIconCache.end()) if(it[(int)size].second.width() > 0)
{ {
it->second.first = now; it[(int)size].first = now;
return it->second.second; return it[(int)size].second;
} }
QPixmap image = drawIdentIcon(QString::fromStdString(id.toStdString()),64*3, true); int S =0;
mDefaultIconCache[id] = std::make_pair(now,image); switch(size)
{
case SMALL: S = 16*3 ; break;
default:
case MEDIUM: S = 32*3 ; break;
case ORIGINAL:
case LARGE: S = 64*3 ; break;
}
QPixmap image = drawIdentIcon(QString::fromStdString(id.toStdString()),S,true);
it[(int)size] = std::make_pair(now,image);
return image; return image;
} }
@ -498,13 +509,26 @@ void GxsIdDetails::checkCleanImagesCache()
int nb_deleted = 0; int nb_deleted = 0;
for(auto it(mDefaultIconCache.begin());it!=mDefaultIconCache.end();) for(auto it(mDefaultIconCache.begin());it!=mDefaultIconCache.end();)
if(it->second.first + ICON_CACHE_STORAGE_TIME < now && it->second.second.isDetached())
{ {
bool all_empty = true ;
for(int i=0;i<4;++i)
if(it->second[i].first + ICON_CACHE_STORAGE_TIME < now && it->second[i].second.isDetached())
{
it->second[i].second = QPixmap();
std::cerr << "Deleting pixmap " << it->first << " size " << i << std::endl;
it = mDefaultIconCache.erase(it); it = mDefaultIconCache.erase(it);
++nb_deleted; ++nb_deleted;
} }
else
all_empty = false;
if(all_empty)
it = mDefaultIconCache.erase(it);
else else
++it; ++it;
}
mLastIconCacheCleaning = now; mLastIconCacheCleaning = now;
std::cerr << "(II) Removed " << nb_deleted << " unused icons. Cache contains " << mDefaultIconCache.size() << " icons"<< std::endl; std::cerr << "(II) Removed " << nb_deleted << " unused icons. Cache contains " << mDefaultIconCache.size() << " icons"<< std::endl;
@ -512,7 +536,7 @@ void GxsIdDetails::checkCleanImagesCache()
} }
bool GxsIdDetails::loadPixmapFromData(const unsigned char *data,size_t data_len,QPixmap& pixmap) bool GxsIdDetails::loadPixmapFromData(const unsigned char *data,size_t data_len,QPixmap& pixmap, AvatarSize size)
{ {
// The trick below converts the data into an Id that can be read in the image cache. Because this method is mainly dedicated to loading // The trick below converts the data into an Id that can be read in the image cache. Because this method is mainly dedicated to loading
// avatars, we could also use the GxsId as id, but the avatar may change in time, so we actually need to make the id from the data itself. // avatars, we could also use the GxsId as id, but the avatar may change in time, so we actually need to make the id from the data itself.
@ -531,12 +555,12 @@ bool GxsIdDetails::loadPixmapFromData(const unsigned char *data,size_t data_len,
// now look for the icon // now look for the icon
time_t now = time(NULL); time_t now = time(NULL);
auto it = mDefaultIconCache.find(id); auto& it = mDefaultIconCache[id];
if(it != mDefaultIconCache.end()) if(it[(int)size].second.width() > 0)
{ {
it->second.first = now; it[(int)size].first = now;
pixmap = it->second.second; pixmap = it[(int)size].second;
return true; return true;
} }
@ -546,11 +570,23 @@ bool GxsIdDetails::loadPixmapFromData(const unsigned char *data,size_t data_len,
// This resize is here just to prevent someone to explicitely add a huge blank image to screw up the UI // This resize is here just to prevent someone to explicitely add a huge blank image to screw up the UI
if(pixmap.width() != AvatarDialog::RS_AVATAR_IMAGE_W || pixmap.height() != AvatarDialog::RS_AVATAR_IMAGE_H) int wanted_S=0;
pixmap = pixmap.scaled(AvatarDialog::RS_AVATAR_IMAGE_W,AvatarDialog::RS_AVATAR_IMAGE_H,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
mDefaultIconCache[id] = std::make_pair(now,pixmap); switch(size)
{
case ORIGINAL: wanted_S = 0 ;break;
case SMALL: wanted_S = 32 ;break;
default:
case MEDIUM: wanted_S = 64 ;break;
case LARGE: wanted_S = 128 ;break;
}
if(wanted_S > 0)
pixmap = pixmap.scaled(wanted_S,wanted_S,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
mDefaultIconCache[id][(int)size] = std::make_pair(now,pixmap);
std::cerr << "Allocated new icon " << id << " size " << (int)size << std::endl;
return true; return true;
} }
/** /**

View File

@ -74,6 +74,13 @@ public:
GxsIdDetails(); GxsIdDetails();
virtual ~GxsIdDetails(); virtual ~GxsIdDetails();
enum AvatarSize {
SMALL = 0x00,
MEDIUM = 0x01,
LARGE = 0x02,
ORIGINAL= 0x03
};
static void initialize(); static void initialize();
static void cleanup(); static void cleanup();
@ -104,8 +111,8 @@ public:
// These two methods use a cache so as to minimize the memory impact of avatars. // These two methods use a cache so as to minimize the memory impact of avatars.
static const QPixmap makeDefaultIcon(const RsGxsId& id); static const QPixmap makeDefaultIcon(const RsGxsId& id, AvatarSize size = MEDIUM);
static bool loadPixmapFromData(const unsigned char *data,size_t data_len,QPixmap& pix); static bool loadPixmapFromData(const unsigned char *data, size_t data_len, QPixmap& pix, AvatarSize size = MEDIUM);
static void checkCleanImagesCache(); static void checkCleanImagesCache();
/* Processing */ /* Processing */
@ -162,7 +169,7 @@ protected:
QMap<QObject*,CallbackData>::iterator mPendingDataIterator; QMap<QObject*,CallbackData>::iterator mPendingDataIterator;
static uint32_t mImagesAllocated; static uint32_t mImagesAllocated;
static std::map<RsGxsId,std::pair<time_t,QPixmap> > mDefaultIconCache; static std::map<RsGxsId,std::pair<time_t,QPixmap>[4] > mDefaultIconCache;
static time_t mLastIconCacheCleaning; static time_t mLastIconCacheCleaning;
int mCheckTimerId; int mCheckTimerId;

View File

@ -160,8 +160,8 @@ QVariant GxsIdRSTreeWidgetItem::data(int column, int role) const
return RSTreeWidgetItem::data(column, role); return RSTreeWidgetItem::data(column, role);
else if( rsReputations->overallReputationLevel(mId) == RsReputationLevel::LOCALLY_NEGATIVE ) else if( rsReputations->overallReputationLevel(mId) == RsReputationLevel::LOCALLY_NEGATIVE )
pix = QPixmap(BANNED_IMAGE); pix = QPixmap(BANNED_IMAGE);
else if ( mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(mAvatar.mData, mAvatar.mSize, pix) ) else if ( mAvatar.mSize == 0 || !GxsIdDetails::loadPixmapFromData(mAvatar.mData, mAvatar.mSize, pix,GxsIdDetails::LARGE) )
pix = GxsIdDetails::makeDefaultIcon(mId); pix = GxsIdDetails::makeDefaultIcon(mId,GxsIdDetails::LARGE);
int S = QFontMetricsF(font(column)).height(); int S = QFontMetricsF(font(column)).height();