Merge pull request #188 from csoler/v0.6-SecuredTunnelService

V0.6 secured tunnel service. Please reports bugs to me (I have tested with valgrind and as many configurations as possible, but the multi-service gathering into GXS tunnels shared for each GXS id pair is not a totally simple thing, so I expect to have missed a few issues).
This commit is contained in:
Cyril Soler 2015-12-05 10:28:16 -05:00
commit 0ac76d621e
40 changed files with 3394 additions and 1458 deletions

View file

@ -1004,8 +1004,9 @@ void IdDialog::chatIdentity()
RsGxsId from_gxs_id(action->data().toString().toStdString());
uint32_t error_code ;
DistantChatPeerId did ;
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, error_code))
if(!rsMsgs->initiateDistantChatConnexion(RsGxsId(keyId), from_gxs_id, did, error_code))
QMessageBox::information(NULL, tr("Distant chat cannot work"), QString("%1 %2: %3").arg(tr("Distant chat refused with this person.")).arg(tr("Error code")).arg(error_code)) ;
}

View file

@ -96,7 +96,7 @@ void ChatDialog::init(ChatId id, const QString &title)
if (cd == NULL) {
if(id.isGxsId())
if(id.isDistantChatId())
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // force open for distant chat
if (chatflags & RS_CHAT_OPEN) {
@ -104,12 +104,16 @@ void ChatDialog::init(ChatId id, const QString &title)
ChatLobbyDialog* cld = new ChatLobbyDialog(id.toLobbyId());
cld->init();
cd = cld;
} else if(id.isGxsId()) {
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog();
QString peer_name = pdcd->getPeerName(id) ;
pdcd->init(id.toGxsId(), tr("Talking to")+" "+peer_name) ;
}
else if(id.isDistantChatId())
{
PopupDistantChatDialog* pdcd = new PopupDistantChatDialog(id.toDistantChatId());
pdcd->init(id.toDistantChatId());
cd = pdcd;
} else {
}
else
{
RsPeerDetails sslDetails;
if (rsPeers->getPeerDetails(id.toPeerId(), sslDetails)) {
PopupChatDialog* pcd = new PopupChatDialog();
@ -168,7 +172,7 @@ void ChatDialog::init(ChatId id, const QString &title)
if(msg.chat_id.isBroadcast())
return; // broadcast is not handled by a chat dialog
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isGxsId()))
if(msg.incoming && (msg.chat_id.isPeerId() || msg.chat_id.isDistantChatId()))
// play sound when recv a message
SoundManager::play(SOUND_NEW_CHAT_MESSAGE);
@ -334,8 +338,8 @@ void ChatDialog::setPeerStatus(uint32_t status)
RsPeerId vpid;
if(mChatId.isPeerId())
vpid = mChatId.toPeerId();
if(mChatId.isGxsId())
vpid = RsPeerId(mChatId.toGxsId());
if(mChatId.isDistantChatId())
vpid = RsPeerId(mChatId.toDistantChatId());
cw->updateStatus(QString::fromStdString(vpid.toStdString()), status);
}
}

View file

@ -562,8 +562,9 @@ void ChatLobbyDialog::distantChatParticipant()
rsMsgs->getIdentityForChatLobby(lobbyId, own_id);
uint32_t error_code ;
DistantChatPeerId tunnel_id;
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,error_code))
if(! rsMsgs->initiateDistantChatConnexion(gxs_id,own_id,tunnel_id,error_code))
{
QString error_str ;
switch(error_code)

View file

@ -109,7 +109,7 @@ void ChatUserNotify::chatMessageReceived(ChatMessage msg)
if(!msg.chat_id.isBroadcast()
&&( ChatDialog::getExistingChat(msg.chat_id)
|| (Settings->getChatFlags() & RS_CHAT_OPEN)
|| msg.chat_id.isGxsId()))
|| msg.chat_id.isDistantChatId()))
{
ChatDialog::chatMessageReceived(msg);
}

View file

@ -255,7 +255,7 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
RsPeerId ownId = rsPeers->getOwnId();
setName(QString::fromUtf8(rsPeers->getPeerName(ownId).c_str()));
if(chatId.isPeerId() || chatId.isGxsId())
if(chatId.isPeerId() || chatId.isDistantChatId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PRIVATE);
if(chatId.isBroadcast() || chatId.isLobbyId())
chatStyle.setStyleFromSettings(ChatStyle::TYPE_PUBLIC);
@ -334,7 +334,8 @@ void ChatWidget::init(const ChatId &chat_id, const QString &title)
continue;
QString name;
if (chatId.isLobbyId() || chatId.isGxsId()) {
if (chatId.isLobbyId() || chatId.isDistantChatId())
{
RsIdentityDetails details;
if (rsIdentity->getIdDetails(RsGxsId(historyIt->peerName), details))
name = QString::fromUtf8(details.mNickname.c_str());
@ -366,7 +367,7 @@ ChatWidget::ChatType ChatWidget::chatType()
// but maybe it is good to have separate types in libretroshare and gui
if(chatId.isPeerId())
return CHATTYPE_PRIVATE;
if(chatId.isGxsId())
if(chatId.isDistantChatId())
return CHATTYPE_DISTANT;
if(chatId.isLobbyId())
return CHATTYPE_LOBBY;
@ -1522,77 +1523,83 @@ void ChatWidget::updateStatus(const QString &peer_id, int status)
// make virtual peer id from gxs id in case of distant chat
RsPeerId vpid;
if(chatId.isGxsId())
vpid = RsPeerId(chatId.toGxsId());
if(chatId.isDistantChatId())
vpid = RsPeerId(chatId.toDistantChatId());
else
vpid = chatId.toPeerId();
/* set font size for status */
if (peer_id.toStdString() == vpid.toStdString()) {
// the peers status has changed
if (peer_id.toStdString() == vpid.toStdString())
{
// the peers status has changed
QString peerName ;
if(chatId.isGxsId())
{
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(chatId.toGxsId(),details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(chatId.toGxsId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
QString peerName ;
if(chatId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
RsIdentityDetails details ;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
if(rsMsgs->getDistantChatStatus(chatId.toDistantChatId(),dcpinfo))
if(rsIdentity->getIdDetails(dcpinfo.to_id,details))
peerName = QString::fromUtf8( details.mNickname.c_str() ) ;
else
peerName = QString::fromStdString(dcpinfo.to_id.toStdString()) ;
else
peerName = QString::fromStdString(chatId.toDistantChatId().toStdString()) ;
}
else
peerName = QString::fromUtf8(rsPeers->getPeerName(chatId.toPeerId()).c_str());
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
break;
// is scrollbar at the end?
QScrollBar *scrollbar = ui->textBrowser->verticalScrollBar();
bool atEnd = (scrollbar->value() == scrollbar->maximum());
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
switch (status) {
case RS_STATUS_OFFLINE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("appears to be Offline.") +"\n" + tr("Messages you send will be delivered after Friend is again Online"));
break;
case RS_STATUS_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_INACTIVE:
ui->infoFrame->setVisible(true);
ui->infoLabel->setText(peerName + " " + tr("is Idle and may not reply"));
break;
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
case RS_STATUS_ONLINE:
ui->infoFrame->setVisible(false);
break;
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
case RS_STATUS_AWAY:
ui->infoLabel->setText(peerName + " " + tr("is Away and may not reply"));
ui->infoFrame->setVisible(true);
break;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
case RS_STATUS_BUSY:
ui->infoLabel->setText(peerName + " " + tr("is Busy and may not reply"));
ui->infoFrame->setVisible(true);
break;
}
peerStatus = status;
ui->titleLabel->setText(peerName);
ui->statusLabel->setText(QString("(%1)").arg(StatusDefs::name(status)));
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
peerStatus = status;
emit infoChanged(this);
emit statusChanged(status);
if (atEnd) {
// scroll to the end
scrollbar->setValue(scrollbar->maximum());
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
emit infoChanged(this);
emit statusChanged(status);
return;
}
// Notify all ChatWidgetHolder
foreach (ChatWidgetHolder *chatWidgetHolder, mChatWidgetHolder) {
chatWidgetHolder->updateStatus(status);
}
return;
}
// ignore status change
}

View file

@ -43,9 +43,11 @@ PopupDistantChatDialog::~PopupDistantChatDialog()
delete _update_timer ;
}
PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags flags)
PopupDistantChatDialog::PopupDistantChatDialog(const DistantChatPeerId& tunnel_id,QWidget *parent, Qt::WindowFlags flags)
: PopupChatDialog(parent,flags)
{
_tunnel_id = tunnel_id ;
_status_label = new QToolButton ;
_update_timer = new QTimer ;
@ -61,97 +63,98 @@ PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WindowFlags
updateDisplay() ;
}
void PopupDistantChatDialog::init(const RsGxsId &gxs_id,const QString & title)
void PopupDistantChatDialog::init(const DistantChatPeerId &peer_id)
{
_pid = gxs_id ;
PopupChatDialog::init(ChatId(gxs_id), title) ;
_tunnel_id = peer_id;
DistantChatPeerInfo tinfo;
if(!rsMsgs->getDistantChatStatus(_tunnel_id,tinfo))
return ;
RsIdentityDetails iddetails ;
if(rsIdentity->getIdDetails(tinfo.to_id,iddetails))
PopupChatDialog::init(ChatId(peer_id), QString::fromUtf8(iddetails.mNickname.c_str())) ;
else
PopupChatDialog::init(ChatId(peer_id), QString::fromStdString(tinfo.to_id.toStdString())) ;
RsGxsId own_gxs_id ;
uint32_t status ;
// do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
// Do not use setOwnId, because we don't want the user to change the GXS avatar from the chat window
// it will not be transmitted.
if(rsMsgs->getDistantChatStatus(gxs_id,status,&own_gxs_id))
ui.ownAvatarWidget->setId(ChatId(own_gxs_id));
ui.ownAvatarWidget->setOwnId() ; // sets the flag
ui.ownAvatarWidget->setId(ChatId(peer_id)) ; // sets the actual Id
}
void PopupDistantChatDialog::updateDisplay()
{
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
if(RsAutoUpdatePage::eventsLocked()) // we need to do that by end, because it's not possible to derive from both PopupChatDialog and RsAutoUpdatePage
return ; // which both derive from QObject. Signals-slot connexions won't work anymore.
if(!isVisible())
return ;
if(!isVisible())
return ;
//std::cerr << "Checking tunnel..." ;
// make sure about the tunnel status
//
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
rsMsgs->getDistantChatStatus(_pid,status) ;
//std::cerr << "Checking tunnel..." ;
// make sure about the tunnel status
//
ui.avatarWidget->setId(ChatId(_pid));
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
ui.avatarWidget->setId(ChatId(_tunnel_id));
QString msg;
switch(status)
{
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRY_LED)) ;
msg = tr("Hash Error. No tunnel.");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
switch(tinfo.status)
{
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRY_LED)) ;
msg = tr("Chat remotely closed. Please close this window.");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
msg = QObject::tr("Tunnel is pending...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: //std::cerr << "Tunnel is ok. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_YEL_LED)) ;
msg = QObject::tr("Secured tunnel established. Waiting for ACK...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRN_LED)) ;
msg = QObject::tr("Secured tunnel is working. You can talk!");
_status_label->setToolTip(msg) ;
getChatWidget()->unblockSending();
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
}
getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setIcon(QIcon(IMAGE_RED_LED)) ;
msg = QObject::tr("Tunnel is pending...");
_status_label->setToolTip(msg) ;
getChatWidget()->updateStatusString("%1", msg, true);
getChatWidget()->blockSending(msg);
setPeerStatus(RS_STATUS_OFFLINE) ;
break ;
case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
_status_label->setIcon(QIcon(IMAGE_GRN_LED)) ;
msg = QObject::tr("Secured tunnel is working. You can talk!");
_status_label->setToolTip(msg) ;
getChatWidget()->unblockSending();
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
}
}
void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
{
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
//std::cerr << "Closing window => closing distant chat for hash " << _pid << std::endl;
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
rsMsgs->getDistantChatStatus(_pid,status) ;
DistantChatPeerInfo tinfo ;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
if(status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
if(tinfo.status != RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED)
{
QString msg = tr("Closing this window will end the conversation, notify the peer and remove the encrypted tunnel.") ;
if(QMessageBox::Ok == QMessageBox::critical(NULL,tr("Kill the tunnel?"),msg, QMessageBox::Ok | QMessageBox::Cancel))
rsMsgs->closeDistantChatConnexion(_pid) ;
rsMsgs->closeDistantChatConnexion(_tunnel_id) ;
else
{
e->ignore() ;
@ -166,23 +169,26 @@ void PopupDistantChatDialog::closeEvent(QCloseEvent *e)
QString PopupDistantChatDialog::getPeerName(const ChatId &id) const
{
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(id.toGxsId(),details))
if(rsIdentity->getIdDetails(tinfo.to_id,details))
return QString::fromUtf8( details.mNickname.c_str() ) ;
else
return QString::fromStdString(id.toGxsId().toStdString()) ;
return QString::fromStdString(tinfo.to_id.toStdString()) ;
}
QString PopupDistantChatDialog::getOwnName() const
{
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
RsGxsId from_gxs_id ;
DistantChatPeerInfo tinfo;
rsMsgs->getDistantChatStatus(_pid,status,&from_gxs_id) ;
rsMsgs->getDistantChatStatus(_tunnel_id,tinfo) ;
RsIdentityDetails details ;
if(rsIdentity->getIdDetails(from_gxs_id,details))
if(rsIdentity->getIdDetails(tinfo.own_id,details))
return QString::fromUtf8( details.mNickname.c_str() ) ;
else
return QString::fromStdString(from_gxs_id.toStdString()) ;
return QString::fromStdString(tinfo.own_id.toStdString()) ;
}

View file

@ -22,6 +22,7 @@
#pragma once
#include <retroshare/rsgxstunnel.h>
#include "PopupChatDialog.h"
class QTimer ;
@ -33,11 +34,11 @@ class PopupDistantChatDialog: public PopupChatDialog
protected:
/** Default constructor */
PopupDistantChatDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
PopupDistantChatDialog(const DistantChatPeerId &tunnel_id, QWidget *parent = 0, Qt::WindowFlags flags = 0);
/** Default destructor */
virtual ~PopupDistantChatDialog();
virtual void init(const RsGxsId &gxs_id, const QString &title);
virtual void init(const DistantChatPeerId& peer_id);
virtual void closeEvent(QCloseEvent *e) ;
virtual QString getPeerName(const ChatId &id) const ;
@ -48,7 +49,7 @@ class PopupDistantChatDialog: public PopupChatDialog
private:
QTimer *_update_timer ;
RsGxsId _pid ;
DistantChatPeerId _tunnel_id ;
QToolButton *_status_label ;
friend class ChatDialog;

View file

@ -124,8 +124,6 @@ void AvatarWidget::setFrameType(FrameType type)
void AvatarWidget::setId(const ChatId &id)
{
mId = id;
// mPgpId = rsPeers->getGPGId(id) ;
// mFlag.isGpg = false ;
setPixmap(QPixmap());
@ -133,15 +131,12 @@ void AvatarWidget::setId(const ChatId &id)
setEnabled(false);
}
if(mId.isGxsId())
std::cerr << "(EE) AvatarWidget should not be set to a GXS id." << std::endl;
refreshAvatarImage();
refreshStatus();
}
void AvatarWidget::setOwnId(const RsGxsId& own_gxs_id)
{
mFlag.isOwnId = true;
setId(ChatId(own_gxs_id));
}
void AvatarWidget::setOwnId()
{
mFlag.isOwnId = true;
@ -181,7 +176,7 @@ void AvatarWidget::refreshStatus()
rsStatus->getOwnStatus(statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
else if(mId.isDistantChatId())
status = RS_STATUS_ONLINE ;
else
{
@ -198,11 +193,15 @@ void AvatarWidget::refreshStatus()
rsStatus->getStatus(mId.toPeerId(), statusInfo);
status = statusInfo.status ;
}
else if(mId.isGxsId())
{
if(!rsMsgs->getDistantChatStatus(mId.toGxsId(),status))
status = RS_STATUS_OFFLINE ;
}
else if(mId.isDistantChatId())
{
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
status = dcpinfo.status ;
else
std::cerr << "(EE) cannot get distant chat status for ID=" << mId.toDistantChatId() << std::endl;
}
else
{
std::cerr << "Unhandled chat id type in AvatarWidget::refreshStatus()" << std::endl;
@ -235,10 +234,11 @@ void AvatarWidget::updateStatus(int status)
void AvatarWidget::updateAvatar(const QString &peerId)
{
if(mId.isPeerId() && mId.toPeerId() == RsPeerId(peerId.toStdString()))
refreshAvatarImage() ;
if(mId.isGxsId() && mId.toGxsId() == RsGxsId(peerId.toStdString()))
refreshAvatarImage() ;
refreshAvatarImage() ;
else if(mId.isDistantChatId() && mId.toDistantChatId() == DistantChatPeerId(peerId.toStdString()))
refreshAvatarImage() ;
else
std::cerr << "(EE) cannot update avatar. mId has unhandled type." << std::endl;
}
void AvatarWidget::refreshAvatarImage()
{
@ -262,12 +262,29 @@ void AvatarWidget::refreshAvatarImage()
setPixmap(avatar);
return;
}
else if (mId.isGxsId())
// else if (mId.isGxsId())
// {
// QPixmap avatar;
//
// AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
// setPixmap(avatar);
// return;
// }
else if (mId.isDistantChatId())
{
QPixmap avatar;
AvatarDefs::getAvatarFromGxsId(mId.toGxsId(), avatar, defaultAvatar);
setPixmap(avatar);
return;
QPixmap avatar;
DistantChatPeerInfo dcpinfo ;
if(rsMsgs->getDistantChatStatus(mId.toDistantChatId(),dcpinfo))
{
if(mFlag.isOwnId)
AvatarDefs::getAvatarFromGxsId(dcpinfo.own_id, avatar, defaultAvatar);
else
AvatarDefs::getAvatarFromGxsId(dcpinfo.to_id, avatar, defaultAvatar);
setPixmap(avatar);
return;
}
}
else
std::cerr << "WARNING: unhandled situation in AvatarWidget::refreshAvatarImage()" << std::endl;

View file

@ -51,7 +51,6 @@ public:
void setFrameType(FrameType type);
void setId(const ChatId& id) ;
void setOwnId();
void setOwnId(const RsGxsId&);
void setDefaultAvatar(const QString &avatar_file_name);
protected:

View file

@ -116,7 +116,7 @@ ImHistoryBrowser::ImHistoryBrowser(const ChatId &chatId, QTextEdit *edit, QWidge
ui.filterLineEdit->showFilterIcon();
// embed smileys ?
if (m_chatId.isPeerId() || m_chatId.isGxsId()) {
if (m_chatId.isPeerId() || m_chatId.isDistantChatId()) {
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_PrivatChat", true).toBool();
} else {
embedSmileys = Settings->valueFromGroup("Chat", "Emoteicons_GroupChat", true).toBool();
@ -275,7 +275,7 @@ void ImHistoryBrowser::fillItem(QListWidgetItem *itemWidget, HistoryMsg& msg)
QString messageText = RsHtml().formatText(NULL, QString::fromUtf8(msg.message.c_str()), formatTextFlag);
QString name;
if (m_chatId.isLobbyId() || m_chatId.isGxsId()) {
if (m_chatId.isLobbyId() || m_chatId.isDistantChatId()) {
RsIdentityDetails details;
if (rsIdentity->getIdDetails(RsGxsId(msg.peerName), details))
name = QString::fromUtf8(details.mNickname.c_str());

View file

@ -112,7 +112,7 @@ bool RsharePeerSettings::getSettingsIdOfPeerId(const ChatId& chatId, std::string
m_SslToGpg[peerId] = settingsId ;
return true;
}
if(chatId.isGxsId() || chatId.isLobbyId() || chatId.isBroadcast())
if(chatId.isDistantChatId() || chatId.isLobbyId() || chatId.isBroadcast())
{
settingsId = chatId.toStdString();
return true;

View file

@ -1,6 +1,7 @@
#include <QObject>
#include <retroshare/rsturtle.h>
#include <retroshare/rspeers.h>
#include <retroshare/rsgxstunnel.h>
#include "TurtleRouterDialog.h"
#include <QPainter>
#include <QStylePainter>
@ -216,3 +217,156 @@ QTreeWidgetItem *TurtleRouterDialog::findParentHashItem(const std::string& hash)
else
return items.front() ;
}
//=======================================================================================================================//
GxsTunnelsDialog::GxsTunnelsDialog(QWidget *parent)
: RsAutoUpdatePage(2000,parent)
{
// setupUi(this) ;
m_bProcessSettings = false;
float fontHeight = QFontMetricsF(font()).height();
float fact = fontHeight/14.0;
maxWidth = 200 ;
maxHeight = 200 ;
// load settings
processSettings(true);
}
GxsTunnelsDialog::~GxsTunnelsDialog()
{
// save settings
processSettings(false);
}
void GxsTunnelsDialog::processSettings(bool bLoad)
{
m_bProcessSettings = true;
Settings->beginGroup(QString("TurtleRouterStatistics"));
if (bLoad) {
// load settings
} else {
// save settings
}
Settings->endGroup();
m_bProcessSettings = false;
}
void GxsTunnelsDialog::updateDisplay()
{
// Request info about ongoing tunnels
std::vector<RsGxsTunnelService::GxsTunnelInfo> tunnel_infos ;
rsGxsTunnel->getTunnelsInfo(tunnel_infos) ;
// // Tunnel information
//
// GxsTunnelId tunnel_id ; // GXS Id we're talking to
// RsGxsId destination_gxs_id ; // GXS Id we're talking to
// RsGxsId source_gxs_id ; // GXS Id we're using to talk
// uint32_t tunnel_status ; // active, requested, DH pending, etc.
// uint32_t total_size_sent ; // total bytes sent through that tunnel since openned (including management).
// uint32_t total_size_received ; // total bytes received through that tunnel since openned (including management).
// // Data packets
// uint32_t pending_data_packets; // number of packets not acknowledged by other side, still on their way. Should be 0 unless something bad happens.
// uint32_t total_data_packets_sent ; // total number of data packets sent (does not include tunnel management)
// uint32_t total_data_packets_received ; // total number of data packets received (does not include tunnel management)
// now draw the shit
QPixmap tmppixmap(maxWidth, maxHeight);
tmppixmap.fill(Qt::transparent);
//setFixedHeight(maxHeight);
QPainter painter(&tmppixmap);
painter.initFrom(this);
// extracts the height of the fonts in pixels. This is used to calibrate the size of the objects to draw.
float fontHeight = QFontMetricsF(font()).height();
float fact = fontHeight/14.0;
//maxHeight = 500*fact ;
int cellx = 6*fact ;
int celly = (10+4)*fact ;
int ox=5*fact,oy=5*fact ;
painter.setPen(QColor::fromRgb(0,0,0)) ;
painter.drawText(ox+2*cellx,oy+celly,tr("Authenticated tunnels:")) ; oy += celly ;
for(uint32_t i=0;i<tunnel_infos.size();++i)
{
// std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl;
// draw...
painter.drawText(ox+4*cellx,oy+celly,tr("Tunnel ID: %1").arg(QString::fromStdString(tunnel_infos[i].tunnel_id.toStdString()))) ; oy += celly ;
painter.drawText(ox+6*cellx,oy+celly,tr("from: %1").arg(QString::fromStdString(tunnel_infos[i].source_gxs_id.toStdString()))) ; oy += celly ;
painter.drawText(ox+6*cellx,oy+celly,tr("to: %1").arg(QString::fromStdString(tunnel_infos[i].destination_gxs_id.toStdString()))) ; oy += celly ;
painter.drawText(ox+6*cellx,oy+celly,tr("status: %1").arg(QString::number(tunnel_infos[i].tunnel_status))) ; oy += celly ;
painter.drawText(ox+6*cellx,oy+celly,tr("total sent: %1 bytes").arg(QString::number(tunnel_infos[i].total_size_sent))) ; oy += celly ;
painter.drawText(ox+6*cellx,oy+celly,tr("total recv: %1 bytes").arg(QString::number(tunnel_infos[i].total_size_received))) ; oy += celly ;
// painter.drawLine(0,oy,maxWidth,oy) ;
// oy += celly ;
}
// update the pixmap
//
pixmap = tmppixmap;
maxHeight = std::max(oy,10*celly);
}
QString GxsTunnelsDialog::getPeerName(const RsPeerId &peer_id)
{
static std::map<RsPeerId, QString> names ;
std::map<RsPeerId,QString>::const_iterator it = names.find(peer_id) ;
if( it != names.end())
return it->second ;
else
{
RsPeerDetails detail ;
if(!rsPeers->getPeerDetails(peer_id,detail))
return tr("Unknown Peer");
return (names[peer_id] = QString::fromUtf8(detail.name.c_str())) ;
}
}
QString GxsTunnelsDialog::speedString(float f)
{
if(f < 1.0f)
return QString("0 B/s") ;
if(f < 1024.0f)
return QString::number((int)f)+" B/s" ;
return QString::number(f/1024.0,'f',2) + " KB/s";
}
void GxsTunnelsDialog::paintEvent(QPaintEvent */*event*/)
{
QStylePainter(this).drawPixmap(0, 0, pixmap);
}
void GxsTunnelsDialog::resizeEvent(QResizeEvent *event)
{
QRect TaskGraphRect = geometry();
maxWidth = TaskGraphRect.width();
maxHeight = TaskGraphRect.height() ;
QWidget::resizeEvent(event);
update();
}

View file

@ -3,6 +3,7 @@
#include <retroshare/rsturtle.h>
#include <retroshare/rstypes.h>
#include "ui_TurtleRouterDialog.h"
#include "ui_TurtleRouterStatistics.h"
#include "RsAutoUpdatePage.h"
@ -35,3 +36,30 @@ class TurtleRouterDialog: public RsAutoUpdatePage, public Ui::TurtleRouterDialog
QTreeWidgetItem *top_level_t_requests ;
} ;
class GxsTunnelsDialog: public RsAutoUpdatePage
{
Q_OBJECT
public:
GxsTunnelsDialog(QWidget *parent = NULL) ;
~GxsTunnelsDialog();
// Cache for peer names.
static QString getPeerName(const RsPeerId &peer_id) ;
protected:
virtual void paintEvent(QPaintEvent *);
virtual void resizeEvent(QResizeEvent *event);
private:
void processSettings(bool bLoad);
bool m_bProcessSettings;
static QString speedString(float f);
virtual void updateDisplay() ;
int maxWidth ;
int maxHeight ;
QPixmap pixmap;
} ;

View file

@ -195,8 +195,8 @@ TurtleRouterStatistics::TurtleRouterStatistics(QWidget *parent)
_tunnel_statistics_F->setFrameStyle(QFrame::NoFrame);
_tunnel_statistics_F->setFocusPolicy(Qt::NoFocus);
routertabWidget->addTab(new TurtleRouterDialog(),QString(tr("Tunnel Requests")));
routertabWidget->addTab(new TurtleRouterDialog(),QString(tr("Anonymous tunnels")));
routertabWidget->addTab(new GxsTunnelsDialog(),QString(tr("Authenticated tunnels")));
float fontHeight = QFontMetricsF(font()).height();
float fact = fontHeight/14.0;