added avatar to GxsId tooltip (see in forums). Removed thread data race due to multiple threads accessing the static data member image_cache, causing avatars to not show up randomly. I do not have a clean solution yet on how to restore this cache

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7911 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2015-02-04 23:05:56 +00:00
parent 52901c1ddb
commit 5ae5d4f0a1
3 changed files with 63 additions and 41 deletions

View file

@ -60,7 +60,7 @@ const int kRecognTagType_Dev_Patcher = 4;
const int kRecognTagType_Dev_Developer = 5; const int kRecognTagType_Dev_Developer = 5;
/* The global object */ /* The global object */
GxsIdDetails *GxsIdDetails::mInstance = NULL; GxsIdDetails *GxsIdDetails::mInstance = NULL ;
GxsIdDetails::GxsIdDetails() GxsIdDetails::GxsIdDetails()
: QObject() : QObject()
@ -207,13 +207,13 @@ bool GxsIdDetails::process(const RsGxsId &id, GxsIdDetailsCallbackFunction callb
} }
details.mId = id; details.mId = id;
callback(GXS_ID_DETAILS_TYPE_LOADING, details, object, data);
/* Add id to the pending list */ /* Add id to the pending list */
if (!mInstance) { if (!mInstance) {
mInstance = new GxsIdDetails; mInstance = new GxsIdDetails;
mInstance->moveToThread(qApp->thread()); mInstance->moveToThread(qApp->thread());
} }
callback(GXS_ID_DETAILS_TYPE_LOADING, details, object, data);
CallbackData pendingData; CallbackData pendingData;
pendingData.mId = id; pendingData.mId = id;
@ -338,18 +338,25 @@ 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
*/ */
QImage GxsIdDetails::makeDefaultIcon(const RsGxsId& id) QImage GxsIdDetails::makeDefaultIconLocal_locked(const RsGxsId& id)
{ {
static std::map<RsGxsId,QImage> image_cache ; QMutexLocker lock(&mMutex2);
std::map<RsGxsId,QImage>::const_iterator it = image_cache.find(id) ; std::map<RsGxsId,QImage>::const_iterator it = image_cache.find(id) ;
if(it != image_cache.end()) if(it != image_cache.end())
return it->second ; return it->second ;
image_cache[id] = drawIdentIcon(QString::fromStdString(id.toStdString()),64*3, true); image_cache[id] = drawIdentIcon(QString::fromStdString(id.toStdString()),64*3, true);
return image_cache[id] ; return image_cache[id] ;
}
QImage GxsIdDetails::makeDefaultIcon(const RsGxsId& id)
{
// if(mInstance != NULL)
// return mInstance->makeDefaultIconLocal_locked(id) ;
// else
return drawIdentIcon(QString::fromStdString(id.toStdString()),64*3, true);
} }
/** /**
@ -846,26 +853,26 @@ QString GxsIdDetails::getComment(const RsIdentityDetails &details)
{ {
QString comment; QString comment;
comment = QString("%1: %2\n%3: %4").arg(QApplication::translate("GxsIdDetails", "Identity name"), comment = QString("%1:%2<br/>%3:%4").arg(QApplication::translate("GxsIdDetails", "Identity&nbsp;name"),
QString::fromUtf8(details.mNickname.c_str()), QString::fromUtf8(details.mNickname.c_str()),
QApplication::translate("GxsIdDetails", "Identity Id"), QApplication::translate("GxsIdDetails", "Identity&nbsp;Id"),
QString::fromStdString(details.mId.toStdString())); QString::fromStdString(details.mId.toStdString()));
if (details.mPgpLinked) if (details.mPgpLinked)
{ {
comment += QString("\n%1: %2 ").arg(QApplication::translate("GxsIdDetails", "Authentication"), QApplication::translate("GxsIdDetails", "signed by")); comment += QString("<br/>%1:%2 ").arg(QApplication::translate("GxsIdDetails", "Authentication"), QApplication::translate("GxsIdDetails", "Signed&nbsp;by"));
if (details.mPgpKnown) if (details.mPgpKnown)
{ {
/* look up real name */ /* look up real name */
std::string authorName = rsPeers->getGPGName(details.mPgpId); std::string authorName = rsPeers->getGPGName(details.mPgpId);
comment += QString("%1 [%2]").arg(QString::fromUtf8(authorName.c_str()), QString::fromStdString(details.mPgpId.toStdString())); comment += QString("%1&nbsp;[%2]").arg(QString::fromUtf8(authorName.c_str()), QString::fromStdString(details.mPgpId.toStdString()));
} }
else else
comment += QApplication::translate("GxsIdDetails", "unknown Key"); comment += QApplication::translate("GxsIdDetails", "unknown Key");
} }
else else
comment += QString("\n%1: %2").arg(QApplication::translate("GxsIdDetails", "Authentication"), QApplication::translate("GxsIdDetails", "anonymous")); comment += QString("<br/>%1:&nbsp;%2").arg(QApplication::translate("GxsIdDetails", "Authentication"), QApplication::translate("GxsIdDetails", "anonymous"));
return comment; return comment;
} }

View file

@ -80,6 +80,7 @@ signals:
protected: protected:
void connectObject_locked(QObject *object, bool doConnect); void connectObject_locked(QObject *object, bool doConnect);
QImage makeDefaultIconLocal_locked(const RsGxsId& id);
/* Timer */ /* Timer */
virtual void timerEvent(QTimerEvent *event); virtual void timerEvent(QTimerEvent *event);
@ -122,10 +123,12 @@ protected:
/* Pending data */ /* Pending data */
QList<CallbackData> mPendingData; QList<CallbackData> mPendingData;
int mCheckTimerId; int mCheckTimerId;
std::map<RsGxsId,QImage> image_cache ;
/* Thread safe */ /* Thread safe */
QMutex mMutex; QMutex mMutex;
QMutex mMutex2;
}; };
#endif #endif

View file

@ -23,6 +23,7 @@
#include "GxsIdTreeWidgetItem.h" #include "GxsIdTreeWidgetItem.h"
#include "GxsIdDetails.h" #include "GxsIdDetails.h"
#include "util/HandleRichText.h"
/** Constructor */ /** Constructor */
GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidget *parent) GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidget *parent)
@ -43,40 +44,51 @@ void GxsIdRSTreeWidgetItem::init()
static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/) static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/)
{ {
GxsIdRSTreeWidgetItem *item = dynamic_cast<GxsIdRSTreeWidgetItem*>(object); GxsIdRSTreeWidgetItem *item = dynamic_cast<GxsIdRSTreeWidgetItem*>(object);
if (!item) { if (!item) {
return; return;
} }
QString toolTip; QString toolTip;
QList<QIcon> icons; QList<QIcon> icons;
switch (type) { switch (type) {
case GXS_ID_DETAILS_TYPE_EMPTY: case GXS_ID_DETAILS_TYPE_EMPTY:
case GXS_ID_DETAILS_TYPE_FAILED: case GXS_ID_DETAILS_TYPE_FAILED:
break; break;
case GXS_ID_DETAILS_TYPE_LOADING: case GXS_ID_DETAILS_TYPE_LOADING:
icons.push_back(GxsIdDetails::getLoadingIcon(details.mId)); icons.push_back(GxsIdDetails::getLoadingIcon(details.mId));
break; break;
case GXS_ID_DETAILS_TYPE_DONE: case GXS_ID_DETAILS_TYPE_DONE:
toolTip = GxsIdDetails::getComment(details); toolTip = GxsIdDetails::getComment(details);
GxsIdDetails::getIcons(details, icons); GxsIdDetails::getIcons(details, icons);
break; break;
} }
int column = item->idColumn(); int column = item->idColumn();
item->setText(column, GxsIdDetails::getNameForType(type, details)); item->setText(column, GxsIdDetails::getNameForType(type, details));
item->setToolTip(column, toolTip); item->setData(column, Qt::UserRole, QString::fromStdString(details.mId.toStdString()));
item->setData(column, Qt::UserRole, QString::fromStdString(details.mId.toStdString()));
QIcon combinedIcon; QIcon combinedIcon;
if (!icons.empty()) { if (!icons.empty()) {
GxsIdDetails::GenerateCombinedIcon(combinedIcon, icons); GxsIdDetails::GenerateCombinedIcon(combinedIcon, icons);
} }
item->setIcon(column, combinedIcon); item->setIcon(column, combinedIcon);
QImage pix ;
if(details.mAvatar.mSize == 0 || !pix.loadFromData(details.mAvatar.mData, details.mAvatar.mSize, "PNG"))
pix = GxsIdDetails::makeDefaultIcon(details.mId);
QString embeddedImage ;
if(RsHtml::makeEmbeddedImage(pix.scaled(QSize(64,64),Qt::KeepAspectRatio,Qt::SmoothTransformation),embeddedImage,128*128))
toolTip = "<table><tr><td>"+embeddedImage+"</td><td>" +toolTip+ "</td></table>" ;
item->setToolTip(column, toolTip);
} }
void GxsIdRSTreeWidgetItem::setId(const RsGxsId &id, int column) void GxsIdRSTreeWidgetItem::setId(const RsGxsId &id, int column)