diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp
index 7bf571b07..47e2da3fc 100644
--- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp
+++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.cpp
@@ -100,6 +100,8 @@ void GxsForumMsgItem::setup()
ui->titleLabel->setText(tr("Loading"));
ui->subjectLabel->clear();
ui->timestamplabel->clear();
+ ui->parentNameLabel->clear();
+ ui->nameLabel->clear();
/* general ones */
connect(ui->expandButton, SIGNAL(clicked()), this, SLOT(toggle()));
@@ -294,6 +296,8 @@ void GxsForumMsgItem::fill()
}
}
+ ui->nameLabel->setId(mMessage.mMeta.mAuthorId);
+
// ui->avatar->setId(msg.srcId, true);
// if (rsPeers->getPeerName(msg.srcId) != "") {
@@ -323,6 +327,8 @@ void GxsForumMsgItem::fill()
ui->parentSubLabel->setText(linkParent.toHtml());
ui->parentMsgLabel->setText(RsHtml().formatText(NULL, QString::fromUtf8(mParentMessage.mMsg.c_str()), RSHTML_FORMATTEXT_EMBED_SMILEYS | RSHTML_FORMATTEXT_EMBED_LINKS));
+ ui->parentNameLabel->setId(mParentMessage.mMeta.mAuthorId);
+
// if (rsPeers->getPeerName(msgParent.srcId) !="")
// {
// RetroShareLink linkMessage;
diff --git a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui
index 30f3b3a82..5562d340f 100644
--- a/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui
+++ b/retroshare-gui/src/gui/feeds/GxsForumMsgItem.ui
@@ -336,7 +336,7 @@
-
-
+
75
@@ -461,7 +461,7 @@
-
-
+
75
@@ -604,6 +604,11 @@
gui/common/AvatarWidget.h
1
+
+ GxsIdLabel
+ QLabel
+
+
diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp
index 84f2a7d9f..4fafda71d 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp
+++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.cpp
@@ -56,8 +56,6 @@ GxsIdChooser::GxsIdChooser(QWidget *parent)
mDefaultId.clear() ;
mDefaultIdName.clear();
- mTimer = NULL;
- mTimerCount = 0;
/* Enable sort with own role */
QSortFilterProxyModel *proxy = new QSortFilterProxyModel(this);
@@ -120,64 +118,34 @@ void GxsIdChooser::loadIds(uint32_t chooserFlags, RsGxsId defId)
mFirstLoad = true;
}
-bool GxsIdChooser::makeIdDesc(const RsGxsId &gxsId, QString &desc)
+static void loadPrivateIdsCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/)
{
- std::list icons;
- QString comment ;
- if (!GxsIdDetails::MakeIdDesc(gxsId, false, desc, icons,comment)) {
- if (mTimerCount > MAX_TRY) {
- desc = QString("%1 ... [").arg(tr("Not found"));
- desc += QString::fromStdString(gxsId.toStdString().substr(0,5));
- desc += "...]";
- }
- return false;
- }
- return true;
-}
-
-void GxsIdChooser::addPrivateId(const RsGxsId &gxsId, bool replace)
-{
- QString str;
- bool found = makeIdDesc(gxsId, str);
- if (!found) {
- /* Add to pending id's */
- mPendingId.push_back(gxsId);
- if (replace && mTimerCount <= MAX_TRY) {
- /* Retry */
- return;
- }
- }
-
- QString id = QString::fromStdString(gxsId.toStdString());
-
- if (replace) {
- /* Find and replace text of exisiting item */
- int index = findData(id);
- if (index >= 0) {
- setItemText(index, str);
- setItemData(index, QString("%1_%2").arg(found ? "1" : "2").arg(str), ROLE_SORT);
- setItemData(index, found ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE);
- model()->sort(0);
+ GxsIdChooser *chooser = dynamic_cast(object);
+ if (!chooser) {
return;
- }
- //If not found create a new item.
- }
+ }
- /* Add new item */
- addItem(str, id);
- setItemData(count() - 1, QString("%1_%2").arg(found ? "1" : "2").arg(str), ROLE_SORT);
- setItemData(count() - 1, found ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE);
- model()->sort(0);
+ QString text = GxsIdDetails::getNameForType(type, details);
+ QString id = QString::fromStdString(details.mId.toStdString());
+
+ /* Find and replace text of exisiting item */
+ int index = chooser->findData(id);
+ if (index >= 0) {
+ chooser->setItemText(index, text);
+ } else {
+ /* Add new item */
+ chooser->addItem(text, id);
+ index = chooser->count() - 1;
+ }
+
+ chooser->setItemData(index, QString("%1_%2").arg((type == GXS_ID_DETAILS_TYPE_DONE) ? "1" : "2").arg(text), ROLE_SORT);
+ chooser->setItemData(index, (type == GXS_ID_DETAILS_TYPE_DONE) ? TYPE_FOUND_ID : TYPE_UNKNOWN_ID, ROLE_TYPE);
+ chooser->model()->sort(0);
}
void GxsIdChooser::loadPrivateIds(uint32_t token)
{
- mPendingId.clear();
if (mFirstLoad) { clear();}
- mTimerCount = 0;
- if (mTimer) {
- delete(mTimer);
- }
std::list ids;
//rsIdentity->getOwnIds(ids);
@@ -245,17 +213,7 @@ void GxsIdChooser::loadPrivateIds(uint32_t token)
for(std::list::iterator it = ids.begin(); it != ids.end(); ++it) {
/* add to Chooser */
- addPrivateId(*it, !mFirstLoad);
- }
-
- if (!mPendingId.empty()) {
- /* Create and start timer to load pending id's */
- mTimerCount = 0;
- mTimer = new QTimer();
- mTimer->setSingleShot(true);
- mTimer->setInterval(500);
- connect(mTimer, SIGNAL(timeout()), this, SLOT(timer()));
- mTimer->start();
+ GxsIdDetails::process(*it, loadPrivateIdsCallback, this);
}
setDefaultItem();
@@ -327,41 +285,6 @@ void GxsIdChooser::myCurrentIndexChanged(int index)
setToolTip("");
}
}
-
-void GxsIdChooser::timer()
-{
- ++mTimerCount;
-
- QList pendingId = mPendingId;
- mPendingId.clear();
-
- /* Process pending id's */
- while (!pendingId.empty()) {
- RsGxsId id = pendingId.front();
- pendingId.pop_front();
-
- addPrivateId(id, true);
- }
-
- setDefaultItem();
-
- if (mPendingId.empty()) {
- /* All pending id's processed */
- delete(mTimer);
- mTimer = NULL;
- mTimerCount = 0;
- } else {//if (mPendingId.empty())
- if (mTimerCount <= MAX_TRY) {
- /* Restart timer */
- mTimer->start();
- } else {//if (mTimerCount <= MAX_TRY)
- delete(mTimer);
- mTimer = NULL;
- mTimerCount = 0;
- mPendingId.clear();
- }
- }
- }
void GxsIdChooser::updateDisplay(bool complete)
{
diff --git a/retroshare-gui/src/gui/gxs/GxsIdChooser.h b/retroshare-gui/src/gui/gxs/GxsIdChooser.h
index 8d416992d..b92d04129 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdChooser.h
+++ b/retroshare-gui/src/gui/gxs/GxsIdChooser.h
@@ -72,14 +72,11 @@ protected:
private slots:
void fillDisplay(bool complete);
- void timer();
void myCurrentIndexChanged(int index);
private:
void requestIdList() ;
void loadPrivateIds(uint32_t token);
- void addPrivateId(const RsGxsId &gxsId, bool replace);
- bool makeIdDesc(const RsGxsId &gxsId, QString &desc);
void insertIdList(uint32_t token);
void setDefaultItem();
@@ -89,10 +86,6 @@ private:
bool mFirstLoad;
QPushButton* addNewCxsId;
- QList mPendingId;
- QTimer *mTimer;
- unsigned int mTimerCount;
-
TokenQueue *mIdQueue;
RsGxsUpdateBroadcastBase *mBase;
};
diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp
index 867ee9c91..57a3310fb 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp
+++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.cpp
@@ -21,6 +21,11 @@
*
*/
+#include
+#include
+#include
+#include
+
#include
#include "GxsIdDetails.h"
@@ -28,9 +33,6 @@
#include
#include
-#include
-#include
-
/* Images for tag icons */
#define IMAGE_LOADING ":/images/folder-draft.png"
@@ -44,6 +46,9 @@
#define IMAGE_DEV_PATCHER ":/images/tags/dev-patcher.png"
#define IMAGE_DEV_DEVELOPER ":/images/tags/developer.png"
+#define TIMER_INTERVAL 1000
+#define MAX_ATTEMPTS 10
+
static const int IconSize = 20;
const int kRecognTagClass_DEVELOPMENT = 1;
@@ -54,8 +59,190 @@ const int kRecognTagType_Dev_Translator = 3;
const int kRecognTagType_Dev_Patcher = 4;
const int kRecognTagType_Dev_Developer = 5;
+/* The global object */
+GxsIdDetails *GxsIdDetails::mInstance = NULL;
-static bool findTagIcon(int tag_class, int tag_type, QIcon &icon)
+GxsIdDetails::GxsIdDetails()
+ : QObject()
+{
+ mCheckTimerId = 0;
+
+ connect(this, SIGNAL(startTimerFromThread()), this, SLOT(doStartTimer()));
+}
+
+GxsIdDetails::~GxsIdDetails()
+{
+}
+
+void GxsIdDetails::objectDestroyed(QObject *object)
+{
+ if (!object) {
+ return;
+ }
+
+ QMutexLocker lock(&mMutex);
+
+ /* Object is about to be destroyed, remove it from pending list */
+ QList::iterator dataIt;
+ for (dataIt = mPendingData.begin(); dataIt != mPendingData.end(); ) {
+ CallbackData &pendingData = *dataIt;
+
+ if (pendingData.mObject == object) {
+ dataIt = mPendingData.erase(dataIt);
+ continue;
+ }
+
+ ++dataIt;
+ }
+}
+
+void GxsIdDetails::connectObject_locked(QObject *object, bool doConnect)
+{
+ if (!object) {
+ return;
+ }
+
+ /* Search Object in pending list */
+ QList::iterator dataIt;
+ for (dataIt = mPendingData.begin(); dataIt != mPendingData.end(); ++dataIt) {
+ if (dataIt->mObject == object) {
+ /* Object still/already in pending list */
+ return;
+ }
+ }
+
+ if (doConnect) {
+ connect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
+ } else {
+ disconnect(object, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));
+ }
+}
+
+void GxsIdDetails::timerEvent(QTimerEvent *event)
+{
+ if (event->timerId() == mCheckTimerId) {
+ /* Stop timer */
+ killTimer(mCheckTimerId);
+ mCheckTimerId = 0;
+
+ if (rsIdentity) {
+ QMutexLocker lock(&mMutex);
+
+ if (!mPendingData.empty()) {
+ /* Check pending id's */
+ QList::iterator dataIt;
+ for (dataIt = mPendingData.begin(); dataIt != mPendingData.end(); ) {
+ CallbackData &pendingData = *dataIt;
+
+ RsIdentityDetails details;
+ if (rsIdentity->getIdDetails(pendingData.mId, details)) {
+ /* Got details */
+ pendingData.mCallback(GXS_ID_DETAILS_TYPE_DONE, details, pendingData.mObject, pendingData.mData);
+
+ QObject *object = pendingData.mObject;
+ dataIt = mPendingData.erase(dataIt);
+ connectObject_locked(object, false);
+
+ continue;
+ }
+
+ if (++pendingData.mAttempt > MAX_ATTEMPTS) {
+ /* Max attempts reached, stop trying */
+ details.mId = pendingData.mId;
+ pendingData.mCallback(GXS_ID_DETAILS_TYPE_FAILED, details, pendingData.mObject, pendingData.mData);
+
+ QObject *object = pendingData.mObject;
+ dataIt = mPendingData.erase(dataIt);
+ connectObject_locked(object, false);
+
+ continue;
+ }
+
+ ++dataIt;
+ }
+ }
+ }
+
+ QMutexLocker lock(&mMutex);
+
+ if (mPendingData.empty()) {
+ /* All done */
+ mInstance = NULL;
+ deleteLater();
+ } else {
+ /* Start timer */
+ doStartTimer();
+ }
+ }
+
+ QObject::timerEvent(event);
+}
+
+void GxsIdDetails::doStartTimer()
+{
+ if (mCheckTimerId) {
+ /* Timer is running */
+ return;
+ }
+
+ mCheckTimerId = startTimer(TIMER_INTERVAL);
+}
+
+bool GxsIdDetails::process(const RsGxsId &id, GxsIdDetailsCallbackFunction callback, QObject *object, const QVariant &data)
+{
+ if (!callback) {
+ return false;
+ }
+
+ RsIdentityDetails details;
+ if (id.isNull()) {
+ callback(GXS_ID_DETAILS_TYPE_EMPTY, details, object, data);
+ return true;
+ }
+
+ /* Try to get the information */
+ if (rsIdentity && rsIdentity->getIdDetails(id, details)) {
+ callback(GXS_ID_DETAILS_TYPE_DONE, details, object, data);
+ return true;
+ }
+
+ details.mId = id;
+ callback(GXS_ID_DETAILS_TYPE_LOADING, details, object, data);
+
+ /* Add id to the pending list */
+ if (!mInstance) {
+ mInstance = new GxsIdDetails;
+ mInstance->moveToThread(qApp->thread());
+ }
+
+ CallbackData pendingData;
+ pendingData.mId = id;
+ pendingData.mCallback = callback;
+ pendingData.mObject = object;
+ pendingData.mData = data;
+
+ {
+ QMutexLocker lock(&mInstance->mMutex);
+
+ /* Connect signal "destroy" */
+ mInstance->connectObject_locked(object, true);
+
+ mInstance->mPendingData.push_back(pendingData);
+ }
+
+ /* Start timer */
+ if (QThread::currentThread() == qApp->thread()) {
+ /* Start timer directly */
+ mInstance->doStartTimer();
+ } else {
+ /* Send signal to start timer in main thread */
+ emit mInstance->startTimerFromThread();
+ }
+
+ return true;
+}
+
+static bool findTagIcon(int tag_class, int /*tag_type*/, QIcon &icon)
{
switch(tag_class)
{
@@ -72,158 +259,220 @@ static bool findTagIcon(int tag_class, int tag_type, QIcon &icon)
QImage GxsIdDetails::makeDefaultIcon(const RsGxsId& id)
{
- static std::map image_cache ;
+ static std::map image_cache ;
- std::map::const_iterator it = image_cache.find(id) ;
+ std::map::const_iterator it = image_cache.find(id) ;
- if(it != image_cache.end())
- return it->second ;
+ if(it != image_cache.end())
+ return it->second ;
- int S = 128 ;
- QImage pix(S,S,QImage::Format_RGB32) ;
+ int S = 128 ;
+ QImage pix(S,S,QImage::Format_RGB32) ;
- uint64_t n = reinterpret_cast(id.toByteArray())[0] ;
+ uint64_t n = reinterpret_cast(id.toByteArray())[0] ;
- uint8_t a[8] ;
- for(int i=0;i<8;++i)
- {
- a[i] = n&0xff ;
- n >>= 8 ;
- }
- QColor val[16] = {
- QColor::fromRgb( 255, 110, 180),
- QColor::fromRgb( 238, 92, 66),
- QColor::fromRgb( 255, 127, 36),
- QColor::fromRgb( 255, 193, 193),
- QColor::fromRgb( 127, 255, 212),
- QColor::fromRgb( 0, 255, 255),
- QColor::fromRgb( 224, 255, 255),
- QColor::fromRgb( 199, 21, 133),
- QColor::fromRgb( 50, 205, 50),
- QColor::fromRgb( 107, 142, 35),
- QColor::fromRgb( 30, 144, 255),
- QColor::fromRgb( 95, 158, 160),
- QColor::fromRgb( 143, 188, 143),
- QColor::fromRgb( 233, 150, 122),
- QColor::fromRgb( 151, 255, 255),
- QColor::fromRgb( 162, 205, 90),
- };
-
- int c1 = (a[0]^a[1]) & 0xf ;
- int c2 = (a[1]^a[2]) & 0xf ;
- int c3 = (a[2]^a[3]) & 0xf ;
- int c4 = (a[3]^a[4]) & 0xf ;
-
- for(int i=0;i
> 4) + sin( (2*M_PI*i/(float)S) * k1 * f) * cos( (2*M_PI*j/(float)S) * k2 * f) * (a[k1+k2] >> 4) ;
- res2 += cos( (2*M_PI*i/(float)S) * k2 * f) * (a[k1+2] & 0xf) + sin( (2*M_PI*j/(float)S) * k1 * f) * (a[k2+1] >> 4) + sin( (2*M_PI*i/(float)S) * k2 * f) * cos( (2*M_PI*j/(float)S) * k1 * f) * (a[k1^k2] >> 4) ;
- }
-
- uint32_t q = 0 ;
- if(res1 >= 0.0f) q += val[c1].rgb() ; else q += val[c2].rgb() ;
- if(res2 >= 0.0f) q += val[c3].rgb() ; else q += val[c4].rgb() ;
-
- pix.setPixel( i, j, q) ;
- pix.setPixel( S-1-i, j, q) ;
- pix.setPixel( S-1-i, S-1-j, q) ;
- pix.setPixel( i, S-1-j, q) ;
- }
-
- image_cache[id] = pix.scaled(64,64,Qt::KeepAspectRatio,Qt::SmoothTransformation) ;
-
- return image_cache[id] ;
-}
-
-
-static bool CreateIdIcon(const RsGxsId &id, QIcon &idIcon)
-{
- QPixmap image(IconSize, IconSize);
- QPainter painter(&image);
-
- painter.fillRect(0, 0, IconSize, IconSize, Qt::black);
-
- int len = id.SIZE_IN_BYTES;
- for(int i = 0; i> 4 ;
- painter.fillRect(x, y, x+1, y+1, Qt::green);
+ a[i] = n&0xff ;
+ n >>= 8 ;
}
- idIcon = QIcon(image);
- return true;
+ QColor val[16] = {
+ QColor::fromRgb( 255, 110, 180),
+ QColor::fromRgb( 238, 92, 66),
+ QColor::fromRgb( 255, 127, 36),
+ QColor::fromRgb( 255, 193, 193),
+ QColor::fromRgb( 127, 255, 212),
+ QColor::fromRgb( 0, 255, 255),
+ QColor::fromRgb( 224, 255, 255),
+ QColor::fromRgb( 199, 21, 133),
+ QColor::fromRgb( 50, 205, 50),
+ QColor::fromRgb( 107, 142, 35),
+ QColor::fromRgb( 30, 144, 255),
+ QColor::fromRgb( 95, 158, 160),
+ QColor::fromRgb( 143, 188, 143),
+ QColor::fromRgb( 233, 150, 122),
+ QColor::fromRgb( 151, 255, 255),
+ QColor::fromRgb( 162, 205, 90),
+ };
+
+ int c1 = (a[0]^a[1]) & 0xf ;
+ int c2 = (a[1]^a[2]) & 0xf ;
+ int c3 = (a[2]^a[3]) & 0xf ;
+ int c4 = (a[3]^a[4]) & 0xf ;
+
+ for(int i=0;i> 4) + sin( (2*M_PI*i/(float)S) * k1 * f) * cos( (2*M_PI*j/(float)S) * k2 * f) * (a[k1+k2] >> 4) ;
+ res2 += cos( (2*M_PI*i/(float)S) * k2 * f) * (a[k1+2] & 0xf) + sin( (2*M_PI*j/(float)S) * k1 * f) * (a[k2+1] >> 4) + sin( (2*M_PI*i/(float)S) * k2 * f) * cos( (2*M_PI*j/(float)S) * k1 * f) * (a[k1^k2] >> 4) ;
+ }
+
+ uint32_t q = 0 ;
+ if(res1 >= 0.0f) q += val[c1].rgb() ; else q += val[c2].rgb() ;
+ if(res2 >= 0.0f) q += val[c3].rgb() ; else q += val[c4].rgb() ;
+
+ pix.setPixel( i, j, q) ;
+ pix.setPixel( S-1-i, j, q) ;
+ pix.setPixel( S-1-i, S-1-j, q) ;
+ pix.setPixel( i, S-1-j, q) ;
+ }
+
+ image_cache[id] = pix.scaled(64,64,Qt::KeepAspectRatio,Qt::SmoothTransformation) ;
+
+ return image_cache[id] ;
}
-bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, std::list &icons,QString& comment)
+//static bool CreateIdIcon(const RsGxsId &id, QIcon &idIcon)
+//{
+// QPixmap image(IconSize, IconSize);
+// QPainter painter(&image);
+
+// painter.fillRect(0, 0, IconSize, IconSize, Qt::black);
+
+// int len = id.SIZE_IN_BYTES;
+// for(int i = 0; i> 4 ;
+// painter.fillRect(x, y, x+1, y+1, Qt::green);
+// }
+// idIcon = QIcon(image);
+// return true;
+//}
+
+QString GxsIdDetails::getLoadingText(const RsGxsId &id)
+{
+ return QString("%1... %2").arg(QApplication::translate("GxsIdDetails", "Loading"), QString::fromStdString(id.toStdString().substr(0, 5)));
+}
+
+QString GxsIdDetails::getFailedText(const RsGxsId &id)
+{
+ return QString("%1 ...[%2]").arg(QApplication::translate("GxsIdDetails", "Not found"), QString::fromStdString(id.toStdString().substr(0, 5)));
+}
+
+QString GxsIdDetails::getEmptyIdText()
+{
+ return QApplication::translate("GxsIdDetails", "No Signature");
+}
+
+QString GxsIdDetails::getNameForType(GxsIdDetailsType type, const RsIdentityDetails &details)
+{
+ switch (type) {
+ case GXS_ID_DETAILS_TYPE_EMPTY:
+ return getEmptyIdText();
+
+ case GXS_ID_DETAILS_TYPE_LOADING:
+ return getLoadingText(details.mId);
+
+ case GXS_ID_DETAILS_TYPE_DONE:
+ return getName(details);
+
+ case GXS_ID_DETAILS_TYPE_FAILED:
+ return getFailedText(details.mId);
+ }
+
+ return "";
+}
+
+QIcon GxsIdDetails::getLoadingIcon(const RsGxsId &/*id*/)
+{
+ return QIcon(IMAGE_LOADING);
+}
+
+bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, QList &icons, QString& comment)
{
RsIdentityDetails details;
-
+
if (!rsIdentity->getIdDetails(id, details))
{
- // std::cerr << "GxsIdTreeWidget::MakeIdDesc() FAILED TO GET ID " << id;
+ // std::cerr << "GxsIdTreeWidget::MakeIdDesc() FAILED TO GET ID " << id;
//std::cerr << std::endl;
- str = QObject::tr("Loading... ") + QString::fromStdString(id.toStdString().substr(0,5));
+ str = getLoadingText(id);
if (!doIcons)
{
- QIcon baseIcon = QIcon(IMAGE_LOADING);
- icons.push_back(baseIcon);
+ icons.push_back(getLoadingIcon(id));
}
return false;
}
- str = QString::fromUtf8(details.mNickname.c_str());
+ str = getName(details);
- std::list::iterator it;
- for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); ++it)
+ comment += getComment(details);
+
+ if (doIcons)
+ getIcons(details, icons);
+
+// Cyril: I disabled these three which I believe to have been put for testing purposes.
+//
+// icons.push_back(QIcon(IMAGE_ANON));
+// icons.push_back(QIcon(IMAGE_ANON));
+// icons.push_back(QIcon(IMAGE_ANON));
+
+// std::cerr << "GxsIdTreeWidget::MakeIdDesc() ID Ok. Comment: " << comment.toStdString() ;
+// std::cerr << std::endl;
+
+ return true;
+}
+
+QString GxsIdDetails::getName(const RsIdentityDetails &details)
+{
+ QString name = QString::fromUtf8(details.mNickname.c_str());
+
+ std::list::const_iterator it;
+ for (it = details.mRecognTags.begin(); it != details.mRecognTags.end(); ++it)
{
- str += " (";
- str += QString::number(it->tag_class);
- str += ":";
- str += QString::number(it->tag_type);
- str += ")";
+ name += QString(" (%1 %2)").arg(it->tag_class).arg(it->tag_type);
}
- comment += "Identity name: " + QString::fromUtf8(details.mNickname.c_str()) + "\n";
- comment += "Identity Id : " + QString::fromStdString(id.toStdString()) + "\n";
+ return name;
+}
+
+QString GxsIdDetails::getComment(const RsIdentityDetails &details)
+{
+ QString comment;
+
+ comment = QString("%1: %2\n%3: %4").arg(QApplication::translate("GxsIdDetails", "Identity name"),
+ QString::fromUtf8(details.mNickname.c_str()),
+ QApplication::translate("GxsIdDetails", "Identity Id"),
+ QString::fromStdString(details.mId.toStdString()));
if (details.mPgpLinked)
{
- comment += "Authentication: signed by " ;
+ comment += QString("\n%1: %2 ").arg(QApplication::translate("GxsIdDetails", "Authentication"), QApplication::translate("GxsIdDetails", "signed by"));
if (details.mPgpKnown)
{
/* look up real name */
std::string authorName = rsPeers->getGPGName(details.mPgpId);
- comment += QString::fromUtf8(authorName.c_str());
- comment += " [";
- comment += QString::fromStdString(details.mPgpId.toStdString()) ;
- comment += "]";
+ comment += QString("%1 [%2]").arg(QString::fromUtf8(authorName.c_str()), QString::fromStdString(details.mPgpId.toStdString()));
}
else
- comment += QObject::tr("unknown Key") ;
+ comment += QApplication::translate("GxsIdDetails", "unknown Key");
}
else
- comment += "Authentication: anonymous" ;
+ comment += QString("\n%1: %2").arg(QApplication::translate("GxsIdDetails", "Authentication"), QApplication::translate("GxsIdDetails", "anonymous"));
- if (!doIcons)
- return true;
+ return comment;
+}
- QPixmap pix ;
- pix.convertFromImage( makeDefaultIcon(id) );
- QIcon idIcon( pix ) ;
- //CreateIdIcon(id, idIcon);
+void GxsIdDetails::getIcons(const RsIdentityDetails &details, QList &icons)
+{
+ QPixmap pix ;
+ pix.convertFromImage(makeDefaultIcon(details.mId));
+ QIcon idIcon(pix);
+ //CreateIdIcon(id, idIcon);
icons.push_back(idIcon);
// ICON Logic.
@@ -240,7 +489,8 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, std
icons.push_back(baseIcon);
// Add In RecognTags Icons.
- for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); ++it)
+ std::list::const_iterator it;
+ for (it = details.mRecognTags.begin(); it != details.mRecognTags.end(); ++it)
{
QIcon tagIcon;
if (findTagIcon(it->tag_class, it->tag_type, tagIcon))
@@ -248,34 +498,22 @@ bool GxsIdDetails::MakeIdDesc(const RsGxsId &id, bool doIcons, QString &str, std
icons.push_back(tagIcon);
}
}
-
-// Cyril: I disabled these three which I believe to have been put for testing purposes.
-//
-// icons.push_back(QIcon(IMAGE_ANON));
-// icons.push_back(QIcon(IMAGE_ANON));
-// icons.push_back(QIcon(IMAGE_ANON));
-
-// std::cerr << "GxsIdTreeWidget::MakeIdDesc() ID Ok. Comment: " << comment.toStdString() ;
-// std::cerr << std::endl;
-
- return true;
}
-bool GxsIdDetails::GenerateCombinedIcon(QIcon &outIcon, std::list &icons)
+bool GxsIdDetails::GenerateCombinedIcon(QIcon &outIcon, const QList &icons)
{
int count = icons.size();
QPixmap image(IconSize * count, IconSize);
QPainter painter(&image);
painter.fillRect(0, 0, IconSize * count, IconSize, Qt::transparent);
- std::list::iterator it;
+ QList::const_iterator it;
int i = 0;
for(it = icons.begin(); it != icons.end(); ++it, ++i)
{
- it->paint(&painter, IconSize * i, 0, IconSize, IconSize);
+ it->paint(&painter, IconSize * i, 0, IconSize, IconSize);
}
outIcon = QIcon(image);
return true;
}
-
diff --git a/retroshare-gui/src/gui/gxs/GxsIdDetails.h b/retroshare-gui/src/gui/gxs/GxsIdDetails.h
index f1b2d7cbc..81666510b 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdDetails.h
+++ b/retroshare-gui/src/gui/gxs/GxsIdDetails.h
@@ -24,21 +24,96 @@
#ifndef _GXS_ID_DETAILS_H
#define _GXS_ID_DETAILS_H
+#include
+#include
+#include
#include
#include
+
#include
-#include
-namespace GxsIdDetails
+class QLabel;
+
+enum GxsIdDetailsType
{
+ GXS_ID_DETAILS_TYPE_EMPTY,
+ GXS_ID_DETAILS_TYPE_LOADING,
+ GXS_ID_DETAILS_TYPE_DONE,
+ GXS_ID_DETAILS_TYPE_FAILED
+};
- bool MakeIdDesc(const RsGxsId &id, bool doIcons,
- QString &desc, std::list &icons,QString& comment);
+typedef void (*GxsIdDetailsCallbackFunction)(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &data);
- bool GenerateCombinedIcon(QIcon &outIcon, std::list &icons);
+class GxsIdDetails : public QObject
+{
+ Q_OBJECT
- QImage makeDefaultIcon(const RsGxsId& id);
+public:
+ GxsIdDetails();
+ virtual ~GxsIdDetails();
-} // namespace GxsIdDetails.
+ /* Information */
+ static bool MakeIdDesc(const RsGxsId &id, bool doIcons, QString &desc, QList &icons, QString& comment);
+
+ static QString getName(const RsIdentityDetails &details);
+ static QString getComment(const RsIdentityDetails &details);
+ static void getIcons(const RsIdentityDetails &details, QList &icons);
+
+ static QString getEmptyIdText();
+ static QString getLoadingText(const RsGxsId &id);
+ static QString getFailedText(const RsGxsId &id);
+
+ static QString getNameForType(GxsIdDetailsType type, const RsIdentityDetails &details);
+
+ static QIcon getLoadingIcon(const RsGxsId &id);
+
+ static bool GenerateCombinedIcon(QIcon &outIcon, const QList &icons);
+
+ static QImage makeDefaultIcon(const RsGxsId& id);
+
+ /* Processing */
+ static bool process(const RsGxsId &id, GxsIdDetailsCallbackFunction callback, QObject *object, const QVariant &data = QVariant());
+
+signals:
+ void startTimerFromThread();
+
+protected:
+ void connectObject_locked(QObject *object, bool doConnect);
+
+ /* Timer */
+ virtual void timerEvent(QTimerEvent *event);
+
+private slots:
+ void objectDestroyed(QObject *object);
+ void doStartTimer();
+
+protected:
+ class CallbackData
+ {
+ public:
+ CallbackData()
+ {
+ mAttempt = 0;
+ mCallback = 0;
+ mObject = NULL;
+ }
+
+ public:
+ int mAttempt;
+ RsGxsId mId;
+ GxsIdDetailsCallbackFunction mCallback;
+ QObject *mObject;
+ QVariant mData;
+ };
+
+ static GxsIdDetails *mInstance;
+
+ /* Pending data */
+ QList mPendingData;
+ int mCheckTimerId;
+
+ /* Thread safe */
+ QMutex mMutex;
+};
#endif
diff --git a/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp b/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp
index ee94909b0..cefd478ec 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp
+++ b/retroshare-gui/src/gui/gxs/GxsIdLabel.cpp
@@ -24,34 +24,42 @@
#include "GxsIdLabel.h"
#include "GxsIdDetails.h"
-#include
-
-#include
-
-#include
-
/** Constructor */
GxsIdLabel::GxsIdLabel(QWidget *parent)
-:QLabel(parent), mTimer(NULL), mCount(0)
+ : QLabel(parent)
{
- mTimer = new QTimer(this);
- mTimer->setSingleShot(true);
- connect(mTimer, SIGNAL(timeout()), this, SLOT(loadId()));
+}
- return;
+static void fillLabelCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/)
+{
+ QLabel *label = dynamic_cast(object);
+ if (!label) {
+ return;
+ }
+
+ label->setText(GxsIdDetails::getNameForType(type, details));
+
+ QString toolTip;
+
+ switch (type) {
+ case GXS_ID_DETAILS_TYPE_EMPTY:
+ case GXS_ID_DETAILS_TYPE_LOADING:
+ case GXS_ID_DETAILS_TYPE_FAILED:
+ break;
+
+ case GXS_ID_DETAILS_TYPE_DONE:
+ toolTip = GxsIdDetails::getComment(details);
+ break;
+ }
+
+ label->setToolTip(toolTip);
}
void GxsIdLabel::setId(const RsGxsId &id)
{
mId = id;
- if (mId.isNull())
- {
- setText("No Signature");
- }
- else
- {
- loadId();
- }
+
+ GxsIdDetails::process(mId, fillLabelCallback, this);
}
bool GxsIdLabel::getId(RsGxsId &id)
@@ -59,32 +67,3 @@ bool GxsIdLabel::getId(RsGxsId &id)
id = mId;
return true;
}
-
-#define MAX_ATTEMPTS 3
-
-void GxsIdLabel::loadId()
-{
- mCount++;
-
- /* try and get details - if not there ... set callback */
- QString desc;
- QString comment ;
- std::list icons;
- bool loaded = GxsIdDetails::MakeIdDesc(mId, false, desc, icons,comment);
-
- setText(desc);
- setToolTip(comment);
-
- if (loaded)
- {
- return;
- }
-
- if (mCount < MAX_ATTEMPTS)
- {
- /* timer event to try again */
- mTimer->setInterval(mCount * 1000);
- mTimer->start();
- }
-}
-
diff --git a/retroshare-gui/src/gui/gxs/GxsIdLabel.h b/retroshare-gui/src/gui/gxs/GxsIdLabel.h
index 95b9ea9af..12a0376c9 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdLabel.h
+++ b/retroshare-gui/src/gui/gxs/GxsIdLabel.h
@@ -21,17 +21,15 @@
*
*/
-
#ifndef _GXS_ID_LABEL_H
#define _GXS_ID_LABEL_H
-#include
#include
#include
class GxsIdLabel : public QLabel
{
- Q_OBJECT
+ Q_OBJECT
public:
GxsIdLabel(QWidget *parent = NULL);
@@ -39,15 +37,8 @@ public:
void setId(const RsGxsId &id);
bool getId(RsGxsId &id);
-private slots:
- void loadId();
-
private:
-
- QTimer *mTimer;
RsGxsId mId;
- int mCount;
};
#endif
-
diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidget.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidget.cpp
index 7728e6a23..38fc03bf3 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidget.cpp
+++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidget.cpp
@@ -36,7 +36,7 @@ static void paintGxsId( QPainter * painter,
{
QString desc;
QString comment;
- std::list icons;
+ QList icons;
if (!GxsIdDetails::MakeIdDesc(id, true, desc, icons,comment))
{
/* flag for reloading */
@@ -45,11 +45,9 @@ static void paintGxsId( QPainter * painter,
const QRect &rect = option.rect;
int x = rect.left();
int y = rect.top();
- int height = rect.height();
- int width = rect.width();
- std::list::iterator it;
+ QList::iterator it;
const int IconSize = 15;
int i = 0;
for(it = icons.begin(); it != icons.end(); ++it, ++i)
diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp
index 2f8fad8a5..52998d836 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp
+++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.cpp
@@ -24,23 +24,15 @@
#include "GxsIdTreeWidgetItem.h"
#include "GxsIdDetails.h"
-#include "rshare.h"
-
-#include
-
-#include
-
-#define MAX_ATTEMPTS 5
-
/** Constructor */
GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidget *parent)
-: QObject(NULL), RSTreeWidgetItem(compareRole, parent), mCount(0), mColumn(0)
+ : QObject(NULL), RSTreeWidgetItem(compareRole, parent), mColumn(0)
{
init();
}
GxsIdRSTreeWidgetItem::GxsIdRSTreeWidgetItem(const RSTreeWidgetItemCompareRole *compareRole, QTreeWidgetItem *parent)
-: QObject(NULL), RSTreeWidgetItem(compareRole, parent), mCount(0), mColumn(0)
+ : QObject(NULL), RSTreeWidgetItem(compareRole, parent), mColumn(0)
{
init();
}
@@ -49,6 +41,44 @@ void GxsIdRSTreeWidgetItem::init()
{
}
+static void fillGxsIdRSTreeWidgetItemCallback(GxsIdDetailsType type, const RsIdentityDetails &details, QObject *object, const QVariant &/*data*/)
+{
+ GxsIdRSTreeWidgetItem *item = dynamic_cast(object);
+ if (!item) {
+ return;
+ }
+
+ QString toolTip;
+ QList icons;
+
+ switch (type) {
+ case GXS_ID_DETAILS_TYPE_EMPTY:
+ case GXS_ID_DETAILS_TYPE_FAILED:
+ break;
+
+ case GXS_ID_DETAILS_TYPE_LOADING:
+ icons.push_back(GxsIdDetails::getLoadingIcon(details.mId));
+ break;
+
+ case GXS_ID_DETAILS_TYPE_DONE:
+ toolTip = GxsIdDetails::getComment(details);
+ GxsIdDetails::getIcons(details, icons);
+ break;
+ }
+
+ int column = item->idColumn();
+
+ item->setText(column, GxsIdDetails::getNameForType(type, details));
+ item->setToolTip(column, toolTip);
+ item->setData(column, Qt::UserRole, QString::fromStdString(details.mId.toStdString()));
+
+ QIcon combinedIcon;
+ if (!icons.empty()) {
+ GxsIdDetails::GenerateCombinedIcon(combinedIcon, icons);
+ }
+ item->setIcon(column, combinedIcon);
+}
+
void GxsIdRSTreeWidgetItem::setId(const RsGxsId &id, int column)
{
//std::cerr << " GxsIdRSTreeWidgetItem::setId(" << id << "," << column << ")";
@@ -56,14 +86,8 @@ void GxsIdRSTreeWidgetItem::setId(const RsGxsId &id, int column)
mId = id;
mColumn = column;
- if (mId.isNull())
- {
- setText(mColumn, "No Signature");
- }
- else
- {
- loadId();
- }
+
+ GxsIdDetails::process(mId, fillGxsIdRSTreeWidgetItemCallback, this);
}
bool GxsIdRSTreeWidgetItem::getId(RsGxsId &id)
@@ -71,127 +95,3 @@ bool GxsIdRSTreeWidgetItem::getId(RsGxsId &id)
id = mId;
return true;
}
-
-void GxsIdRSTreeWidgetItem::loadId()
-{
- disconnect(rApp, SIGNAL(secondTick()), this, SLOT(loadId()));
-
- //std::cerr << " GxsIdRSTreeWidgetItem::loadId() Id: " << mId << ", mCount: " << mCount;
- //std::cerr << std::endl;
-
- mCount++;
-
- /* try and get details - if not there ... set callback */
- QString desc;
- QString comment ;
- std::list icons;
- bool loaded = GxsIdDetails::MakeIdDesc(mId, true, desc, icons,comment);
- QIcon combinedIcon;
- if (!icons.empty())
- {
- GxsIdDetails::GenerateCombinedIcon(combinedIcon, icons);
- setIcon(mColumn, combinedIcon);
- }
- setToolTip(mColumn,comment) ;
- setText(mColumn, desc);
- setData(mColumn,Qt::UserRole, QString::fromStdString(mId.toStdString()));
-
- if (loaded)
- {
- // std::cerr << " GxsIdRSTreeWidgetItem::loadId() Loaded Okay";
- //std::cerr << std::endl;
- return;
- }
-
- if (mCount < MAX_ATTEMPTS)
- {
- //std::cerr << " GxsIdRSTreeWidgetItem::loadId() Starting Timer for re-try";
- //std::cerr << std::endl;
-
- /* timer event to try again */
- connect(rApp, SIGNAL(secondTick()), this, SLOT(loadId()));
- }
-}
-
-#if 0
-/** Constructor */
-GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(QTreeWidget *parent)
-: QObject(NULL), QTreeWidgetItem(parent), mCount(0), mColumn(0)
-{
- init();
-}
-
-GxsIdTreeWidgetItem::GxsIdTreeWidgetItem(QTreeWidgetItem *parent)
-: QObject(NULL), QTreeWidgetItem(parent), mCount(0), mColumn(0)
-{
- init();
-}
-
-void GxsIdTreeWidgetItem::init()
-{
-}
-
-void GxsIdTreeWidgetItem::setId(const RsGxsId &id, int column)
-{
- std::cerr << " GxsIdTreeWidgetItem::setId(" << id << "," << column << ")";
- std::cerr << std::endl;
-
- mId = id;
- mColumn = column;
- if (mId.isNull())
- {
- setText(mColumn, "No Signature");
- }
- else
- {
- loadId();
- }
-}
-
-bool GxsIdTreeWidgetItem::getId(RsGxsId &id)
-{
- id = mId;
- return true;
-}
-
-void GxsIdTreeWidgetItem::loadId()
-{
- disconnect(rApp, SIGNAL(secondTick()), this, SLOT(loadId()));
-
- std::cerr << " GxsIdTreeWidgetItem::loadId() Id: " << mId << ", mCount: " << mCount;
- std::cerr << std::endl;
-
- mCount++;
-
- /* try and get details - if not there ... set callback */
- QString desc;
- QString comment;
- std::list icons;
- bool loaded = GxsIdDetails::MakeIdDesc(mId, true, desc, icons,comment);
- QIcon combinedIcon;
- if (!icons.empty())
- {
- GxsIdDetails::GenerateCombinedIcon(combinedIcon, icons);
- setIcon(mColumn, combinedIcon);
- }
-
- setText(mColumn, desc);
- setToolTip(mColumn, comment);
-
- if (loaded)
- {
- std::cerr << " GxsIdTreeWidgetItem::loadId() Loaded Okay";
- std::cerr << std::endl;
- return;
- }
-
- if (mCount < MAX_ATTEMPTS)
- {
- std::cerr << " GxsIdTreeWidgetItem::loadId() Starting Timer for re-try";
- std::cerr << std::endl;
-
- /* timer event to try again */
- connect(rApp, SIGNAL(secondTick()), this, SLOT(loadId()));
- }
-}
-#endif
diff --git a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h
index 652b2a852..4f9221645 100644
--- a/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h
+++ b/retroshare-gui/src/gui/gxs/GxsIdTreeWidgetItem.h
@@ -34,7 +34,6 @@
* The tick signal to fill the id cannot be processed when the thread is finished.
***/
-
class GxsIdRSTreeWidgetItem : public QObject, public RSTreeWidgetItem
{
Q_OBJECT
@@ -46,39 +45,13 @@ public:
void setId(const RsGxsId &id, int column);
bool getId(RsGxsId &id);
-private slots:
- void loadId();
+ int idColumn() { return mColumn; }
private:
void init();
RsGxsId mId;
- int mCount;
int mColumn;
};
-#if 0
-class GxsIdTreeWidgetItem : public QObject, public QTreeWidgetItem
-{
- Q_OBJECT
-
-public:
- GxsIdTreeWidgetItem(QTreeWidget *parent = NULL);
- GxsIdTreeWidgetItem(QTreeWidgetItem *parent);
-
- void setId(const RsGxsId &id, int column);
- bool getId(RsGxsId &id);
-
-private slots:
- void loadId();
-
-private:
- void init();
-
- RsGxsId mId;
- int mCount;
- int mColumn;
-};
-#endif
-
#endif