fixed unread chat cound in FriendsDialog, fix display of status in distant chat (Patch from electron)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7832 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2015-01-10 13:13:41 +00:00
parent 0e2c4266fa
commit 4d26726a88
8 changed files with 131 additions and 52 deletions

View File

@ -239,16 +239,6 @@ void FriendsDialog::processSettings(bool bLoad)
void FriendsDialog::showEvent(QShowEvent *event) void FriendsDialog::showEvent(QShowEvent *event)
{ {
static bool first = true;
if (first) {
// Workaround: now the scroll position is correct calculated
first = false;
/* remove
QScrollBar *scrollbar = ui.msgText->verticalScrollBar();
scrollbar->setValue(scrollbar->maximum());
*/
}
RsAutoUpdatePage::showEvent(event); RsAutoUpdatePage::showEvent(event);
} }
@ -262,6 +252,13 @@ void FriendsDialog::chatMessageReceived(const ChatMessage &msg)
QString name = QString::fromUtf8(rsPeers->getPeerName(msg.broadcast_peer_id).c_str()); QString name = QString::fromUtf8(rsPeers->getPeerName(msg.broadcast_peer_id).c_str());
ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL); ui.chatWidget->addChatMsg(msg.incoming, name, sendTime, recvTime, message, ChatWidget::MSGTYPE_NORMAL);
if(ui.chatWidget->isActive())
{
// clear the chat notify when control returns to the Qt event loop
// we have to do this later, because we don't know if we or the notify receives the chat message first
QMetaObject::invokeMethod(this, "clearChatNotify", Qt::QueuedConnection);
}
} }
} }
@ -319,6 +316,11 @@ void FriendsDialog::loadmypersonalstatus()
} }
} }
void FriendsDialog::clearChatNotify()
{
ChatUserNotify::clearWaitingChat(ChatId::makeBroadcastId());
}
void FriendsDialog::statusmessage() void FriendsDialog::statusmessage()
{ {
StatusMessage statusmsgdialog (this); StatusMessage statusmsgdialog (this);

View File

@ -92,6 +92,8 @@ private slots:
void loadmypersonalstatus(); void loadmypersonalstatus();
void clearChatNotify();
//void newsFeedChanged(int count); //void newsFeedChanged(int count);
signals: signals:

View File

@ -28,10 +28,39 @@
#include <retroshare/rsnotify.h> #include <retroshare/rsnotify.h>
#include <retroshare/rsmsgs.h> #include <retroshare/rsmsgs.h>
static std::map<ChatId, int> waitingChats;
static ChatUserNotify* instance = 0;
/*static*/ void ChatUserNotify::getPeersWithWaitingChat(std::vector<RsPeerId> &peers)
{
for(std::map<ChatId, int>::iterator mit = waitingChats.begin(); mit != waitingChats.end(); ++mit)
{
if(mit->first.isPeerId() && std::find(peers.begin(), peers.end(), mit->first.toPeerId()) == peers.end())
peers.push_back(mit->first.toPeerId());
}
}
/*static*/ void ChatUserNotify::clearWaitingChat(ChatId id)
{
std::map<ChatId, int>::iterator mit = waitingChats.find(id);
if(mit != waitingChats.end())
{
waitingChats.erase(mit);
if(instance)
instance->updateIcon();
}
}
ChatUserNotify::ChatUserNotify(QObject *parent) : ChatUserNotify::ChatUserNotify(QObject *parent) :
UserNotify(parent) UserNotify(parent)
{ {
connect(NotifyQt::getInstance(), SIGNAL(chatMessageReceived(ChatMessage)), this, SLOT(chatMessageReceived(ChatMessage))); connect(NotifyQt::getInstance(), SIGNAL(chatMessageReceived(ChatMessage)), this, SLOT(chatMessageReceived(ChatMessage)));
instance = this;
}
ChatUserNotify::~ChatUserNotify()
{
instance = 0;
} }
bool ChatUserNotify::hasSetting(QString *name, QString *group) bool ChatUserNotify::hasSetting(QString *name, QString *group)
@ -55,7 +84,7 @@ QIcon ChatUserNotify::getMainIcon(bool hasNew)
unsigned int ChatUserNotify::getNewCount() unsigned int ChatUserNotify::getNewCount()
{ {
int sum = 0; int sum = 0;
for(std::map<ChatId, int>::iterator mit = mWaitingChats.begin(); mit != mWaitingChats.end(); ++mit) for(std::map<ChatId, int>::iterator mit = waitingChats.begin(); mit != waitingChats.end(); ++mit)
{ {
sum += mit->second; sum += mit->second;
} }
@ -65,10 +94,8 @@ unsigned int ChatUserNotify::getNewCount()
void ChatUserNotify::iconClicked() void ChatUserNotify::iconClicked()
{ {
ChatDialog *chatDialog = NULL; ChatDialog *chatDialog = NULL;
if (mWaitingChats.empty() == false) { // ChatWidget removes the waiting chat from the list with clearWaitingChat()
chatDialog = ChatDialog::getChat(mWaitingChats.begin()->first, RS_CHAT_OPEN | RS_CHAT_FOCUS); chatDialog = ChatDialog::getChat(waitingChats.begin()->first, RS_CHAT_OPEN | RS_CHAT_FOCUS);
mWaitingChats.erase(mWaitingChats.begin());
}
if (chatDialog == NULL) { if (chatDialog == NULL) {
MainWindow::showWindow(MainWindow::Friends); MainWindow::showWindow(MainWindow::Friends);
@ -78,13 +105,18 @@ void ChatUserNotify::iconClicked()
void ChatUserNotify::chatMessageReceived(ChatMessage msg) void ChatUserNotify::chatMessageReceived(ChatMessage msg)
{ {
if(ChatDialog::getExistingChat(msg.chat_id) || (Settings->getChatFlags() & RS_CHAT_OPEN) || msg.chat_id.isGxsId()) if(!msg.chat_id.isBroadcast()
&&( ChatDialog::getExistingChat(msg.chat_id)
|| (Settings->getChatFlags() & RS_CHAT_OPEN)
|| msg.chat_id.isGxsId()))
{
ChatDialog::chatMessageReceived(msg); ChatDialog::chatMessageReceived(msg);
}
else else
{ {
// this implicitly counts broadcast messages, because broadcast messages are not handled by chat dialog // this implicitly counts broadcast messages, because broadcast messages are not handled by chat dialog
bool found = false; bool found = false;
for(std::map<ChatId, int>::iterator mit = mWaitingChats.begin(); mit != mWaitingChats.end(); ++mit) for(std::map<ChatId, int>::iterator mit = waitingChats.begin(); mit != waitingChats.end(); ++mit)
{ {
if(msg.chat_id.isSameEndpoint(mit->first)) if(msg.chat_id.isSameEndpoint(mit->first))
{ {
@ -93,7 +125,7 @@ void ChatUserNotify::chatMessageReceived(ChatMessage msg)
} }
} }
if(!found) if(!found)
mWaitingChats[msg.chat_id] = 1; waitingChats[msg.chat_id] = 1;
updateIcon(); updateIcon();
} }
} }

View File

@ -25,12 +25,19 @@
#include <retroshare/rsmsgs.h> #include <retroshare/rsmsgs.h>
#include "gui/common/UserNotify.h" #include "gui/common/UserNotify.h"
// this class uses lots of global state
// so only one instance is allowed
// (it does not make sense to have multiple instances of this class anyway)
class ChatUserNotify : public UserNotify class ChatUserNotify : public UserNotify
{ {
Q_OBJECT Q_OBJECT
public: public:
static void getPeersWithWaitingChat(std::vector<RsPeerId>& peers);
static void clearWaitingChat(ChatId id);
ChatUserNotify(QObject *parent = 0); ChatUserNotify(QObject *parent = 0);
~ChatUserNotify();
virtual bool hasSetting(QString *name, QString *group); virtual bool hasSetting(QString *name, QString *group);
@ -42,8 +49,6 @@ private:
virtual QIcon getMainIcon(bool hasNew); virtual QIcon getMainIcon(bool hasNew);
virtual unsigned int getNewCount(); virtual unsigned int getNewCount();
virtual void iconClicked(); virtual void iconClicked();
std::map<ChatId, int> mWaitingChats;
}; };
#endif // CHATUSERNOTIFY_H #endif // CHATUSERNOTIFY_H

View File

@ -46,6 +46,7 @@
#include "gui/common/Emoticons.h" #include "gui/common/Emoticons.h"
#include "util/misc.h" #include "util/misc.h"
#include "util/HandleRichText.h" #include "util/HandleRichText.h"
#include "gui/chat/ChatUserNotify.h"
#include <retroshare/rsstatus.h> #include <retroshare/rsstatus.h>
#include <retroshare/rsidentity.h> #include <retroshare/rsidentity.h>
@ -61,7 +62,7 @@
*****/ *****/
ChatWidget::ChatWidget(QWidget *parent) : ChatWidget::ChatWidget(QWidget *parent) :
QWidget(parent), ui(new Ui::ChatWidget) QWidget(parent), ui(new Ui::ChatWidget), sendingBlocked(false)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -330,6 +331,19 @@ ChatWidget::ChatType ChatWidget::chatType()
return CHATTYPE_UNKNOWN; return CHATTYPE_UNKNOWN;
} }
void ChatWidget::blockSending(QString msg)
{
sendingBlocked = true;
ui->sendButton->setEnabled(false);
ui->sendButton->setToolTip(msg);
}
void ChatWidget::unblockSending()
{
sendingBlocked = false;
updateLenOfChatTextEdit();
}
void ChatWidget::processSettings(bool load) void ChatWidget::processSettings(bool load)
{ {
Settings->beginGroup(QString("ChatWidget")); Settings->beginGroup(QString("ChatWidget"));
@ -486,6 +500,7 @@ bool ChatWidget::eventFilter(QObject *obj, QEvent *event)
newMessages = false; newMessages = false;
emit infoChanged(this); emit infoChanged(this);
focusDialog(); focusDialog();
ChatUserNotify::clearWaitingChat(chatId);
} }
} }
} }
@ -653,6 +668,7 @@ void ChatWidget::showEvent(QShowEvent */*event*/)
newMessages = false; newMessages = false;
emit infoChanged(this); emit infoChanged(this);
focusDialog(); focusDialog();
ChatUserNotify::clearWaitingChat(chatId);
if (firstShow) { if (firstShow) {
// Workaround: now the scroll position is correct calculated // Workaround: now the scroll position is correct calculated
@ -863,6 +879,9 @@ void ChatWidget::updateStatusTyping()
void ChatWidget::updateLenOfChatTextEdit() void ChatWidget::updateLenOfChatTextEdit()
{ {
if(sendingBlocked)
return;
QTextEdit *chatWidget = ui->chatTextEdit; QTextEdit *chatWidget = ui->chatTextEdit;
QString text; QString text;
RsHtml::optimizeHtml(chatWidget, text); RsHtml::optimizeHtml(chatWidget, text);
@ -1448,7 +1467,7 @@ void ChatWidget::updatePeersCustomStateString(const QString& peer_id, const QStr
*/ */
} }
void ChatWidget::updateStatusString(const QString &statusMask, const QString &statusString) void ChatWidget::updateStatusString(const QString &statusMask, const QString &statusString, bool permanent)
{ {
ui->typingLabel->setText(QString(statusMask).arg(tr(statusString.toLatin1()))); // displays info for 5 secs. ui->typingLabel->setText(QString(statusMask).arg(tr(statusString.toLatin1()))); // displays info for 5 secs.
ui->typingpixmapLabel->setPixmap(QPixmap(":images/typing.png") ); ui->typingpixmapLabel->setPixmap(QPixmap(":images/typing.png") );
@ -1459,7 +1478,8 @@ void ChatWidget::updateStatusString(const QString &statusMask, const QString &st
emit infoChanged(this); emit infoChanged(this);
} }
QTimer::singleShot(5000, this, SLOT(resetStatusBar())) ; if(!permanent)
QTimer::singleShot(5000, this, SLOT(resetStatusBar())) ;
} }
void ChatWidget::setName(const QString &name) void ChatWidget::setName(const QString &name)

View File

@ -75,6 +75,10 @@ public:
ChatId getChatId(); ChatId getChatId();
ChatType chatType(); ChatType chatType();
// allow/disallow sendng of messages
void blockSending(QString msg);
void unblockSending();
bool hasNewMessages() { return newMessages; } bool hasNewMessages() { return newMessages; }
bool isTyping() { return typing; } bool isTyping() { return typing; }
@ -84,7 +88,7 @@ public:
void setWelcomeMessage(QString &text); void setWelcomeMessage(QString &text);
void addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType); void addChatMsg(bool incoming, const QString &name, const QDateTime &sendTime, const QDateTime &recvTime, const QString &message, MsgType chatType);
void updateStatusString(const QString &statusMask, const QString &statusString); void updateStatusString(const QString &statusMask, const QString &statusString, bool permanent = false);
void addToolsAction(QAction *action); void addToolsAction(QAction *action);
@ -200,6 +204,8 @@ private:
bool typing; bool typing;
int peerStatus; int peerStatus;
bool sendingBlocked;
time_t lastStatusSendTime; time_t lastStatusSendTime;
ChatStyle chatStyle; ChatStyle chatStyle;

View File

@ -82,36 +82,49 @@ void PopupDistantChatDialog::updateDisplay()
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN; uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
rsMsgs->getDistantChatStatus(_pid,status) ; rsMsgs->getDistantChatStatus(_pid,status) ;
QString msg;
switch(status) switch(status)
{ {
case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl; case RS_DISTANT_CHAT_STATUS_UNKNOWN: //std::cerr << "Unknown hash. Error!" << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_GRY_LED)) ; _status_label->setPixmap(QPixmap(IMAGE_GRY_LED)) ;
_status_label->setToolTip(QObject::tr("Hash error")) ; msg = tr("Hash Error. No tunnel.");
setPeerStatus(RS_STATUS_OFFLINE) ; _status_label->setToolTip(msg) ;
break ; getChatWidget()->updateStatusString("%1", msg, true);
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl; getChatWidget()->blockSending(tr("Can't send message, because there is no tunnel."));
_status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ; setPeerStatus(RS_STATUS_OFFLINE) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ; break ;
case RS_DISTANT_CHAT_STATUS_REMOTELY_CLOSED: std::cerr << "Chat remotely closed. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Distant peer has closed the chat")) ;
QMessageBox::warning(NULL,tr("Distant chat terminated"),tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now.")) ; getChatWidget()->updateStatusString("%1", tr("The person you're talking to has deleted the secured chat tunnel. You may remove the chat window now."), true);
setPeerStatus(RS_STATUS_OFFLINE) ; getChatWidget()->blockSending(tr("Can't send message, because the chat partner deleted the secure tunnel."));
setPeerStatus(RS_STATUS_OFFLINE) ;
break ; break ;
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl; case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: //std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ; _status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ;
_status_label->setToolTip(QObject::tr("Tunnel is pending...")) ; msg = QObject::tr("Tunnel is pending...");
setPeerStatus(RS_STATUS_OFFLINE) ; _status_label->setToolTip(msg) ;
break ; 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; case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: //std::cerr << "Tunnel is ok. " << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_YEL_LED)) ; _status_label->setPixmap(QPixmap(IMAGE_YEL_LED)) ;
_status_label->setToolTip(QObject::tr("Secured tunnel established. Waiting for ACK...")) ; msg = QObject::tr("Secured tunnel established. Waiting for ACK...");
setPeerStatus(RS_STATUS_ONLINE) ; _status_label->setToolTip(msg) ;
break ; 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; case RS_DISTANT_CHAT_STATUS_CAN_TALK: //std::cerr << "Tunnel is ok and data is transmitted." << std::endl;
_status_label->setPixmap(QPixmap(IMAGE_GRN_LED)) ; _status_label->setPixmap(QPixmap(IMAGE_GRN_LED)) ;
_status_label->setToolTip(QObject::tr("Secured tunnel is working. You can talk!")) ; msg = QObject::tr("Secured tunnel is working. You can talk!");
setPeerStatus(RS_STATUS_ONLINE) ; _status_label->setToolTip(msg) ;
break ; getChatWidget()->unblockSending();
setPeerStatus(RS_STATUS_ONLINE) ;
break ;
} }
} }

View File

@ -49,7 +49,7 @@
#include "util/misc.h" #include "util/misc.h"
#include "vmessagebox.h" #include "vmessagebox.h"
#include "util/QtVersion.h" #include "util/QtVersion.h"
#include "gui/chat/ChatUserNotify.h"
#include "gui/connect/ConnectProgressDialog.h" #include "gui/connect/ConnectProgressDialog.h"
#include "FriendList.h" #include "FriendList.h"
@ -598,10 +598,9 @@ void FriendList::insertPeers()
return; return;
} }
// get ids of existing private chat messages // get peers with waiting incoming chats
std::list<RsPeerId> privateChatIds; std::vector<RsPeerId> privateChatIds;
// TODO ChatUserNotify::getPeersWithWaitingChat(privateChatIds);
//rsMsgs->getPrivateChatQueueIds(true, privateChatIds);
// get existing groups // get existing groups
std::list<RsGroupInfo> groupInfoList; std::list<RsGroupInfo> groupInfoList;