Splitted queue of chat messages in chat service into public and private queue.

Reworked the interface of the chat service. So full recomile is needed.
With disabled flags for private chat (RS_CHAT_OPEN_NEW and RS_CHAT_REOPEN), the incoming private chat messages are queued (only for the runtime) until the user shows the private chat dialog.
When a new chat message is available, the icon of the gpg and ssl contact changed in MessengerWindow and PeersDialog and a new tray icon is shown.
Fixed compiler warning.


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3421 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2010-09-01 17:56:15 +00:00
parent 7dd99a0c35
commit 7f837e9778
17 changed files with 597 additions and 329 deletions

View file

@ -227,7 +227,8 @@ const int NOTIFY_LIST_DIRLIST_LOCAL = 9;
const int NOTIFY_LIST_DIRLIST_FRIENDS = 10; const int NOTIFY_LIST_DIRLIST_FRIENDS = 10;
const int NOTIFY_LIST_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection const int NOTIFY_LIST_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection
const int NOTIFY_LIST_MESSAGE_TAGS = 12; const int NOTIFY_LIST_MESSAGE_TAGS = 12;
const int NOTIFY_LIST_CHAT = 13; const int NOTIFY_LIST_PUBLIC_CHAT = 13;
const int NOTIFY_LIST_PRIVATE_CHAT = 14;
const int NOTIFY_TYPE_SAME = 0x01; const int NOTIFY_TYPE_SAME = 0x01;
const int NOTIFY_TYPE_MOD = 0x02; /* general purpose, check all */ const int NOTIFY_TYPE_MOD = 0x02; /* general purpose, check all */

View file

@ -174,8 +174,12 @@ virtual bool resetMessageStandardTagTypes(MsgTagType& tags) = 0;
/****************************************/ /****************************************/
/* Chat */ /* Chat */
virtual bool ChatSend(ChatInfo &ci) = 0; virtual bool sendPublicChat(std::wstring msg) = 0;
virtual bool getNewChat(std::list<ChatInfo> &chats) = 0; virtual bool sendPrivateChat(std::string id, std::wstring msg) = 0;
virtual int getChatQueueCount(bool privateQueue) = 0;
virtual bool getPublicChatQueue(std::list<ChatInfo> &chats) = 0;
virtual bool getPrivateChatQueueIds(std::list<std::string> &ids) = 0;
virtual bool getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats) = 0;
virtual void sendStatusString(const std::string& id,const std::string& status_string) = 0 ; virtual void sendStatusString(const std::string& id,const std::string& status_string) = 0 ;
virtual void sendGroupChatStatusString(const std::string& status_string) = 0 ; virtual void sendGroupChatStatusString(const std::string& status_string) = 0 ;

View file

@ -135,19 +135,16 @@ bool p3Msgs::resetMessageStandardTagTypes(MsgTagType& tags)
/****************************************/ /****************************************/
/****************************************/ /****************************************/
bool p3Msgs::ChatSend(ChatInfo &ci) bool p3Msgs::sendPublicChat(std::wstring msg)
{ {
/* send a message to all for now */ /* send a message to all for now */
if (ci.chatflags & RS_CHAT_PRIVATE) return mChatSrv -> sendPublicChat(msg);
{ }
mChatSrv -> sendPrivateChat(ci.msg, ci.rsid);
} bool p3Msgs::sendPrivateChat(std::string id, std::wstring msg)
else {
{ /* send a message to peer */
/* global */ return mChatSrv -> sendPrivateChat(id, msg);
mChatSrv -> sendChat(ci.msg);
}
return true;
} }
void p3Msgs::sendGroupChatStatusString(const std::string& status_string) void p3Msgs::sendGroupChatStatusString(const std::string& status_string)
@ -159,9 +156,24 @@ void p3Msgs::sendStatusString(const std::string& peer_id,const std::string& stat
mChatSrv->sendStatusString(peer_id,status_string); mChatSrv->sendStatusString(peer_id,status_string);
} }
bool p3Msgs::getNewChat(std::list<ChatInfo> &chats) int p3Msgs::getChatQueueCount(bool privateQueue)
{ {
return mChatSrv->getChatQueue(chats); return mChatSrv->getChatQueueCount(privateQueue);
}
bool p3Msgs::getPublicChatQueue(std::list<ChatInfo> &chats)
{
return mChatSrv->getPublicChatQueue(chats);
}
bool p3Msgs::getPrivateChatQueueIds(std::list<std::string> &ids)
{
return mChatSrv->getPrivateChatQueueIds(ids);
}
bool p3Msgs::getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats)
{
return mChatSrv->getPrivateChatQueue(id, chats);
} }
void p3Msgs::getOwnAvatarData(unsigned char *& data,int& size) void p3Msgs::getOwnAvatarData(unsigned char *& data,int& size)

View file

@ -104,19 +104,38 @@ class p3Msgs: public RsMsgs
virtual std::string getCustomStateString(const std::string& peer_id) ; virtual std::string getCustomStateString(const std::string& peer_id) ;
/****************************************/
/* Chat */
/*! /*!
* sends chat (public and private) * public chat sent to all peers
* @param ci chat info
*/ */
virtual bool ChatSend(ChatInfo &ci); virtual bool sendPublicChat(std::wstring msg);
/*! /*!
* @param chats ref to list of received chats is stored here * chat is sent to specifc peer
* @param id peer to send chat msg to
*/ */
virtual bool getNewChat(std::list<ChatInfo> &chats); virtual bool sendPrivateChat(std::string id, std::wstring msg);
/*!
* returns the count of messages in public or private queue
* @param public or private queue
*/
virtual int getChatQueueCount(bool privateQueue);
/*!
* @param chats ref to list of received public chats is stored here
*/
virtual bool getPublicChatQueue(std::list<ChatInfo> &chats);
/*!
* @param id's of available private chat messages
*/
virtual bool getPrivateChatQueueIds(std::list<std::string> &ids);
/*!
* @param chats ref to list of received private chats is stored here
*/
virtual bool getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats);
/*! /*!
* sends immediate status string to a specific peer, e.g. in a private chat * sends immediate status string to a specific peer, e.g. in a private chat
* @param peer_id peer to send status string to * @param peer_id peer to send status string to

View file

@ -66,7 +66,7 @@ int p3ChatService::status()
/***************** Chat Stuff **********************/ /***************** Chat Stuff **********************/
int p3ChatService::sendChat(std::wstring msg) int p3ChatService::sendPublicChat(std::wstring &msg)
{ {
/* go through all the peers */ /* go through all the peers */
@ -203,7 +203,7 @@ void p3ChatService::sendStatusString( const std::string& id , const std::string&
sendItem(cs); sendItem(cs);
} }
int p3ChatService::sendPrivateChat( std::wstring msg, std::string id) int p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
{ {
// make chat item.... // make chat item....
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
@ -283,7 +283,8 @@ int p3ChatService::sendPrivateChat( std::wstring msg, std::string id)
void p3ChatService::receiveChatQueue() void p3ChatService::receiveChatQueue()
{ {
bool changed = false; bool publicChanged = false;
bool privateChanged = false;
time_t now = time(NULL); time_t now = time(NULL);
RsItem *item ; RsItem *item ;
@ -334,6 +335,7 @@ void p3ChatService::receiveChatQueue()
} }
if ((ci->chatFlags & RS_CHAT_FLAG_PRIVATE) == 0) { if ((ci->chatFlags & RS_CHAT_FLAG_PRIVATE) == 0) {
/* notify public chat message */
std::string message; std::string message;
message.assign(ci->message.begin(), ci->message.end()); message.assign(ci->message.begin(), ci->message.end());
getPqiNotify()->AddFeedItem(RS_FEED_ITEM_CHAT_NEW, ci->PeerId(), message, ""); getPqiNotify()->AddFeedItem(RS_FEED_ITEM_CHAT_NEW, ci->PeerId(), message, "");
@ -343,10 +345,15 @@ void p3ChatService::receiveChatQueue()
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
ci->recvTime = now; ci->recvTime = now;
ilist.push_back(ci); // don't delete the item !!
} /* UNLOCK */
changed = true; if (ci->chatFlags & RS_CHAT_FLAG_PRIVATE) {
privateChanged = true;
privateList.push_back(ci); // don't delete the item !!
} else {
publicChanged = true;
publicList.push_back(ci); // don't delete the item !!
}
} /* UNLOCK */
} }
continue ; continue ;
@ -402,35 +409,121 @@ void p3ChatService::receiveChatQueue()
} }
} }
if (changed) { if (publicChanged) {
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_CHAT, NOTIFY_TYPE_ADD); rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PUBLIC_CHAT, NOTIFY_TYPE_ADD);
}
if (privateChanged) {
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_CHAT, NOTIFY_TYPE_ADD);
} }
} }
bool p3ChatService::getChatQueue(std::list<ChatInfo> &chats) int p3ChatService::getChatQueueCount(bool privateQueue)
{ {
/* get any messages and push them to iface */ RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
if (privateQueue) {
return privateList.size();
}
return publicList.size();
}
bool p3ChatService::getPublicChatQueue(std::list<ChatInfo> &chats)
{
bool changed = false;
{
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
// get the items from the public list.
if (publicList.size() == 0) {
return false;
}
std::list<RsChatMsgItem *>::iterator it;
while (publicList.size()) {
RsChatMsgItem *c = publicList.front();
publicList.pop_front();
ChatInfo ci;
initRsChatInfo(c, ci);
chats.push_back(ci);
changed = true;
delete c;
}
} /* UNLOCKED */
if (changed) {
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PUBLIC_CHAT, NOTIFY_TYPE_DEL);
}
return true;
}
bool p3ChatService::getPrivateChatQueueIds(std::list<std::string> &ids)
{
ids.clear();
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
// get the items from the list. // get the items from the private list.
if (ilist.size() == 0) if (privateList.size() == 0) {
{
return false; return false;
} }
std::list<RsChatMsgItem *>::iterator it; std::list<RsChatMsgItem *>::iterator it;
while (ilist.size()) for (it = privateList.begin(); it != privateList.end(); it++) {
{ RsChatMsgItem *c = *it;
RsChatMsgItem *c = ilist.front();
ilist.pop_front();
ChatInfo ci; if (std::find(ids.begin(), ids.end(), c->PeerId()) == ids.end()) {
initRsChatInfo(c, ci); ids.push_back(c->PeerId());
chats.push_back(ci); }
delete c;
} }
return true;
}
bool p3ChatService::getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats)
{
bool changed = false;
{
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
// get the items from the private list.
if (privateList.size() == 0) {
return false;
}
std::list<RsChatMsgItem *>::iterator it = privateList.begin();
while (it != privateList.end()) {
RsChatMsgItem *c = *it;
if (c->PeerId() == id) {
ChatInfo ci;
initRsChatInfo(c, ci);
chats.push_back(ci);
changed = true;
delete c;
std::list<RsChatMsgItem *>::iterator it1 = it;
it++;
privateList.erase(it1);
continue;
}
it++;
}
} /* UNLOCKED */
if (changed) {
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_CHAT, NOTIFY_TYPE_DEL);
}
return true; return true;
} }

View file

@ -61,13 +61,13 @@ class p3ChatService: public p3Service, public p3Config
/*! /*!
* public chat sent to all peers * public chat sent to all peers
*/ */
int sendChat(std::wstring msg); int sendPublicChat(std::wstring &msg);
/*! /*!
* chat is sent to specifc peer * chat is sent to specifc peer
* @param id peer to send caht msg to * @param id peer to send chat msg to
*/ */
int sendPrivateChat(std::wstring msg, std::string id); int sendPrivateChat(std::string &id, std::wstring &msg);
/*! /*!
* can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs) * can be used to send 'immediate' status msgs, these status updates are meant for immediate use by peer (not saved by rs)
@ -117,9 +117,25 @@ class p3ChatService: public p3Service, public p3Config
/*! /*!
* This retrieves all chat msg items * returns the count of messages in public or private queue
* @param public or private queue
*/ */
bool getChatQueue(std::list<ChatInfo> &chats); int getChatQueueCount(bool privateQueue);
/*!
* This retrieves all public chat msg items
*/
bool getPublicChatQueue(std::list<ChatInfo> &chats);
/*!
* @param id's of available private chat messages
*/
bool getPrivateChatQueueIds(std::list<std::string> &ids);
/*!
* This retrieves all private chat msg items for peer
*/
bool getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats);
/************* from p3Config *******************/ /************* from p3Config *******************/
virtual RsSerialiser *setupSerialiser() ; virtual RsSerialiser *setupSerialiser() ;
@ -163,7 +179,8 @@ class p3ChatService: public p3Service, public p3Config
p3ConnectMgr *mConnMgr; p3ConnectMgr *mConnMgr;
std::list<RsChatMsgItem *> ilist; std::list<RsChatMsgItem *> publicList;
std::list<RsChatMsgItem *> privateList;
AvatarInfo *_own_avatar ; AvatarInfo *_own_avatar ;
std::map<std::string,AvatarInfo *> _avatars ; std::map<std::string,AvatarInfo *> _avatars ;

View file

@ -50,6 +50,7 @@
#include "ChannelFeed.h" #include "ChannelFeed.h"
#include "bwgraph/bwgraph.h" #include "bwgraph/bwgraph.h"
#include "help/browser/helpbrowser.h" #include "help/browser/helpbrowser.h"
#include "chat/PopupChatDialog.h"
#ifdef UNFINISHED #ifdef UNFINISHED
#include "unfinished/ApplicationWindow.h" #include "unfinished/ApplicationWindow.h"
@ -67,6 +68,7 @@
#include <retroshare/rspeers.h> #include <retroshare/rspeers.h>
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
#include <retroshare/rsforums.h> #include <retroshare/rsforums.h>
#include <retroshare/rsnotify.h>
#include "gui/connect/ConnectFriendWizard.h" #include "gui/connect/ConnectFriendWizard.h"
#include "util/rsversion.h" #include "util/rsversion.h"
@ -398,6 +400,11 @@ void MainWindow::createTrayIcon()
trayIconForums = new QSystemTrayIcon(this); trayIconForums = new QSystemTrayIcon(this);
trayIconForums->setIcon(QIcon(":/images/konversation16.png")); trayIconForums->setIcon(QIcon(":/images/konversation16.png"));
connect(trayIconForums, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconForumsClicked(QSystemTrayIcon::ActivationReason))); connect(trayIconForums, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconForumsClicked(QSystemTrayIcon::ActivationReason)));
// Create the tray icon for chat
trayIconChat = new QSystemTrayIcon(this);
trayIconChat->setIcon(QIcon(":/images/chat.png"));
connect(trayIconChat, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayIconChatClicked(QSystemTrayIcon::ActivationReason)));
} }
/*static*/ void MainWindow::installGroupChatNotifier() /*static*/ void MainWindow::installGroupChatNotifier()
@ -503,6 +510,21 @@ void MainWindow::updateStatus()
} }
} }
void MainWindow::privateChatChanged(int type)
{
/* first process the chat messages */
PopupChatDialog::privateChatChanged();
/* than count the chat messages */
int chatCount = rsMsgs->getChatQueueCount(true);
if (chatCount) {
trayIconChat->show();
} else {
trayIconChat->hide();
}
}
void MainWindow::updateHashingInfo(const QString& s) void MainWindow::updateHashingInfo(const QString& s)
{ {
if(s == "") if(s == "")
@ -766,7 +788,6 @@ void MainWindow::closeEvent(QCloseEvent *e)
} }
void MainWindow::updateMenu() void MainWindow::updateMenu()
{ {
toggleVisibilityAction->setText(isVisible() ? tr("Hide") : tr("Show")); toggleVisibilityAction->setText(isVisible() ? tr("Hide") : tr("Show"));
@ -806,6 +827,21 @@ void MainWindow::trayIconForumsClicked(QSystemTrayIcon::ActivationReason e)
} }
} }
void MainWindow::trayIconChatClicked(QSystemTrayIcon::ActivationReason e)
{
if(e == QSystemTrayIcon::Trigger || e == QSystemTrayIcon::DoubleClick) {
PopupChatDialog *pcd = NULL;
std::list<std::string> ids;
if (rsMsgs->getPrivateChatQueueIds(ids) && ids.size()) {
pcd = PopupChatDialog::getPrivateChat(ids.front(), RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS);
}
if (pcd == NULL) {
showWindow(MainWindow::Friends);
}
}
}
void MainWindow::toggleVisibilitycontextmenu() void MainWindow::toggleVisibilitycontextmenu()
{ {
if (isVisible()) if (isVisible())

View file

@ -141,6 +141,7 @@ public slots:
void checkAndSetIdle(int idleTime); void checkAndSetIdle(int idleTime);
void updateMessages(); void updateMessages();
void updateForums(); void updateForums();
void privateChatChanged(int type);
protected: protected:
/** Default Constructor */ /** Default Constructor */
@ -160,6 +161,7 @@ private slots:
void toggleVisibilitycontextmenu(); void toggleVisibilitycontextmenu();
void trayIconMessagesClicked(QSystemTrayIcon::ActivationReason e); void trayIconMessagesClicked(QSystemTrayIcon::ActivationReason e);
void trayIconForumsClicked(QSystemTrayIcon::ActivationReason e); void trayIconForumsClicked(QSystemTrayIcon::ActivationReason e);
void trayIconChatClicked(QSystemTrayIcon::ActivationReason e);
/** Toolbar fns. */ /** Toolbar fns. */
void addFriend(); void addFriend();
@ -223,6 +225,7 @@ private:
QSystemTrayIcon *trayIcon; QSystemTrayIcon *trayIcon;
QSystemTrayIcon *trayIconMessages; QSystemTrayIcon *trayIconMessages;
QSystemTrayIcon *trayIconForums; QSystemTrayIcon *trayIconForums;
QSystemTrayIcon *trayIconChat;
QAction *toggleVisibilityAction, *toolAct; QAction *toggleVisibilityAction, *toolAct;
QMenu *trayMenu; QMenu *trayMenu;

View file

@ -460,6 +460,9 @@ void MessengerWindow::insertPeers()
return; return;
} }
std::list<std::string> privateChatIds;
rsMsgs->getPrivateChatQueueIds(privateChatIds);
rsPeers->getGPGAcceptedList(gpgFriends); rsPeers->getGPGAcceptedList(gpgFriends);
std::string sOwnId = rsPeers->getGPGOwnId(); std::string sOwnId = rsPeers->getGPGOwnId();
@ -546,6 +549,7 @@ void MessengerWindow::insertPeers()
//update the childs (ssl certs) //update the childs (ssl certs)
bool gpg_connected = false; bool gpg_connected = false;
bool gpg_online = false; bool gpg_online = false;
bool gpg_hasPrivateChat = false;
std::list<std::string> sslContacts; std::list<std::string> sslContacts;
rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslContacts); rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslContacts);
for(std::list<std::string>::iterator sslIt = sslContacts.begin(); sslIt != sslContacts.end(); sslIt++) { for(std::list<std::string>::iterator sslIt = sslContacts.begin(); sslIt != sslContacts.end(); sslIt++) {
@ -598,6 +602,7 @@ void MessengerWindow::insertPeers()
/* not displayed, used to find back the item */ /* not displayed, used to find back the item */
//sslItem -> setText(1, QString::fromStdString(sslDetail.autoconnect)); //sslItem -> setText(1, QString::fromStdString(sslDetail.autoconnect));
QIcon sslIcon;
int i; int i;
if (sslDetail.state & RS_PEER_STATE_CONNECTED) { if (sslDetail.state & RS_PEER_STATE_CONNECTED) {
sslItem->setHidden(false); sslItem->setHidden(false);
@ -619,7 +624,7 @@ void MessengerWindow::insertPeers()
#endif // MINIMAL_RSGUI #endif // MINIMAL_RSGUI
/* change color and icon */ /* change color and icon */
sslItem -> setIcon(COLUMN_NAME,(QIcon(":/images/connect_established.png"))); sslIcon = QIcon(":/images/connect_established.png");
QFont font; QFont font;
font.setBold(true); font.setBold(true);
for(i = 0; i < COLUMN_COUNT; i++) { for(i = 0; i < COLUMN_COUNT; i++) {
@ -639,9 +644,9 @@ void MessengerWindow::insertPeers()
} else { } else {
sslItem->setHidden(ui.actionHide_Offline_Friends->isChecked()); sslItem->setHidden(ui.actionHide_Offline_Friends->isChecked());
if (sslDetail.autoconnect !="Offline") { if (sslDetail.autoconnect !="Offline") {
sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_creating.png"))); sslIcon = QIcon(":/images/connect_creating.png");
} else { } else {
sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_no.png"))); sslIcon = QIcon(":/images/connect_no.png");
} }
QFont font; QFont font;
@ -652,6 +657,13 @@ void MessengerWindow::insertPeers()
} }
} }
if (std::find(privateChatIds.begin(), privateChatIds.end(), sslDetail.id) != privateChatIds.end()) {
// private chat is available
sslIcon = QIcon(":/images/chat.png");
gpg_hasPrivateChat = true;
}
sslItem -> setIcon(COLUMN_NAME, sslIcon);
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "PeersDialog::insertPeers() inserting sslItem." << std::endl; std::cerr << "PeersDialog::insertPeers() inserting sslItem." << std::endl;
#endif #endif
@ -663,6 +675,7 @@ void MessengerWindow::insertPeers()
} }
int i = 0; int i = 0;
QIcon gpgIcon;
if (gpg_connected) { if (gpg_connected) {
gpg_item->setHidden(false); gpg_item->setHidden(false);
//gpg_item -> setText(COLUMN_STATE, tr("Online")); // set to online regardless on update //gpg_item -> setText(COLUMN_STATE, tr("Online")); // set to online regardless on update
@ -695,8 +708,7 @@ void MessengerWindow::insertPeers()
QPixmap avatar ; QPixmap avatar ;
avatar.loadFromData(data,size,"PNG") ; avatar.loadFromData(data,size,"PNG") ;
QIcon avatar_icon(avatar); QIcon avatar_icon(avatar);
QSize av_icon_size(32, 32); gpg_item-> setIcon(COLUMN_STATE, avatar_icon);
gpg_item-> setIcon(1, avatar_icon);
delete[] data; delete[] data;
} else { } else {
@ -705,7 +717,7 @@ void MessengerWindow::insertPeers()
switch (it->status) { switch (it->status) {
case RS_STATUS_INACTIVE: case RS_STATUS_INACTIVE:
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_INACTIVE))); gpgIcon = QIcon(IMAGE_INACTIVE);
gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Idle")); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Idle"));
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_INACTIVE)); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_INACTIVE));
@ -716,7 +728,7 @@ void MessengerWindow::insertPeers()
break; break;
case RS_STATUS_ONLINE: case RS_STATUS_ONLINE:
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_ONLINE))); gpgIcon = QIcon(IMAGE_ONLINE);
gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Online")); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Online"));
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE)); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE));
@ -727,7 +739,7 @@ void MessengerWindow::insertPeers()
break; break;
case RS_STATUS_AWAY: case RS_STATUS_AWAY:
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_AWAY))); gpgIcon = QIcon(IMAGE_AWAY);
gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Away")); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Away"));
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_AWAY)); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_AWAY));
@ -738,7 +750,7 @@ void MessengerWindow::insertPeers()
break; break;
case RS_STATUS_BUSY: case RS_STATUS_BUSY:
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_BUSY))); gpgIcon = QIcon(IMAGE_BUSY);
gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Busy")); gpg_item -> setToolTip(COLUMN_NAME, tr("Peer Busy"));
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_BUSY)); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_BUSY));
@ -754,7 +766,7 @@ void MessengerWindow::insertPeers()
#endif // MINIMAL_RSGUI #endif // MINIMAL_RSGUI
} else if (gpg_online) { } else if (gpg_online) {
gpg_item->setHidden(ui.actionHide_Offline_Friends->isChecked()); gpg_item->setHidden(ui.actionHide_Offline_Friends->isChecked());
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_AVAIBLE))); gpgIcon = QIcon(IMAGE_AVAIBLE);
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE)); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE));
//gpg_item -> setText(COLUMN_STATE, tr("Available")); //gpg_item -> setText(COLUMN_STATE, tr("Available"));
QFont font; QFont font;
@ -765,7 +777,7 @@ void MessengerWindow::insertPeers()
} }
} else { } else {
gpg_item->setHidden(ui.actionHide_Offline_Friends->isChecked()); gpg_item->setHidden(ui.actionHide_Offline_Friends->isChecked());
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_OFFLINE))); gpgIcon = QIcon(IMAGE_OFFLINE);
gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_OFFLINE)); gpg_item->setData(COLUMN_NAME, ROLE_SORT, BuildStateSortString(bSortState, gpg_item->text(COLUMN_NAME), PEER_STATE_OFFLINE));
//gpg_item -> setText(COLUMN_STATE, tr("Offline")); //gpg_item -> setText(COLUMN_STATE, tr("Offline"));
QFont font; QFont font;
@ -776,6 +788,12 @@ void MessengerWindow::insertPeers()
} }
} }
if (gpg_hasPrivateChat) {
gpgIcon = QIcon(":/images/chat.png");
}
gpg_item -> setIcon(COLUMN_NAME, gpgIcon);
/* add gpg item to the list. If item is already in the list, it won't be duplicated thanks to Qt */ /* add gpg item to the list. If item is already in the list, it won't be duplicated thanks to Qt */
peertreeWidget->addTopLevelItem(gpg_item); peertreeWidget->addTopLevelItem(gpg_item);

View file

@ -500,6 +500,9 @@ void PeersDialog::insertPeers()
bool bHideUnconnected = ui.action_Hide_Offline_Friends->isChecked(); bool bHideUnconnected = ui.action_Hide_Offline_Friends->isChecked();
std::list<std::string> privateChatIds;
rsMsgs->getPrivateChatQueueIds(privateChatIds);
rsPeers->getGPGAcceptedList(gpgFriends); rsPeers->getGPGAcceptedList(gpgFriends);
//add own gpg id, if we have more than on location (ssl client) //add own gpg id, if we have more than on location (ssl client)
@ -588,6 +591,7 @@ void PeersDialog::insertPeers()
//update the childs (ssl certs) //update the childs (ssl certs)
bool gpg_connected = false; bool gpg_connected = false;
bool gpg_online = false; bool gpg_online = false;
bool gpg_hasPrivateChat = false;
std::list<std::string> sslContacts; std::list<std::string> sslContacts;
rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslContacts); rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslContacts);
for(std::list<std::string>::iterator sslIt = sslContacts.begin(); sslIt != sslContacts.end(); sslIt++) { for(std::list<std::string>::iterator sslIt = sslContacts.begin(); sslIt != sslContacts.end(); sslIt++) {
@ -641,12 +645,13 @@ void PeersDialog::insertPeers()
sslItem -> setData(COLUMN_STATE, ROLE_SORT, sText); sslItem -> setData(COLUMN_STATE, ROLE_SORT, sText);
/* change color and icon */ /* change color and icon */
QIcon sslIcon;
int i; int i;
if (sslDetail.state & RS_PEER_STATE_CONNECTED) { if (sslDetail.state & RS_PEER_STATE_CONNECTED) {
sslItem->setHidden(false); sslItem->setHidden(false);
gpg_connected = true; gpg_connected = true;
sslItem -> setIcon(COLUMN_NAME,(QIcon(":/images/connect_established.png"))); sslIcon = QIcon(":/images/connect_established.png");
sslItem -> setIcon(COLUMN_STATE,(QIcon(":/images/encrypted32.png"))); sslItem -> setIcon(COLUMN_STATE,(QIcon(":/images/encrypted32.png")));
QFont font; QFont font;
font.setBold(true); font.setBold(true);
@ -667,9 +672,9 @@ void PeersDialog::insertPeers()
} else { } else {
sslItem->setHidden(bHideUnconnected); sslItem->setHidden(bHideUnconnected);
if (sslDetail.autoconnect != "Offline") { if (sslDetail.autoconnect != "Offline") {
sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_creating.png"))); sslIcon = QIcon(":/images/connect_creating.png");
} else { } else {
sslItem -> setIcon(COLUMN_NAME, (QIcon(":/images/connect_no.png"))); sslIcon = QIcon(":/images/connect_no.png");
} }
QFont font; QFont font;
@ -680,6 +685,13 @@ void PeersDialog::insertPeers()
} }
} }
if (std::find(privateChatIds.begin(), privateChatIds.end(), sslDetail.id) != privateChatIds.end()) {
// private chat is available
sslIcon = QIcon(":/images/chat.png");
gpg_hasPrivateChat = true;
}
sslItem -> setIcon(COLUMN_NAME, sslIcon);
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "PeersDialog::insertPeers() inserting sslItem." << std::endl; std::cerr << "PeersDialog::insertPeers() inserting sslItem." << std::endl;
#endif #endif
@ -691,9 +703,10 @@ void PeersDialog::insertPeers()
} }
int i = 0; int i = 0;
QIcon gpgIcon;
if (gpg_connected) { if (gpg_connected) {
gpg_item->setHidden(false); gpg_item->setHidden(false);
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_ONLINE))); gpgIcon = QIcon(IMAGE_ONLINE);
gpg_item -> setText(COLUMN_STATE, tr("Online")); gpg_item -> setText(COLUMN_STATE, tr("Online"));
gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE)); gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_ONLINE));
@ -764,7 +777,7 @@ void PeersDialog::insertPeers()
} }
} else if (gpg_online) { } else if (gpg_online) {
gpg_item->setHidden(bHideUnconnected); gpg_item->setHidden(bHideUnconnected);
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_AVAIBLE))); gpgIcon = QIcon(IMAGE_AVAIBLE);
gpg_item -> setText(COLUMN_STATE, tr("Available")); gpg_item -> setText(COLUMN_STATE, tr("Available"));
gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_AVAILABLE)); gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_AVAILABLE));
QFont font; QFont font;
@ -775,7 +788,7 @@ void PeersDialog::insertPeers()
} }
} else { } else {
gpg_item->setHidden(bHideUnconnected); gpg_item->setHidden(bHideUnconnected);
gpg_item -> setIcon(COLUMN_NAME,(QIcon(IMAGE_OFFLINE))); gpgIcon = QIcon(IMAGE_OFFLINE);
gpg_item -> setText(COLUMN_STATE, tr("Offline")); gpg_item -> setText(COLUMN_STATE, tr("Offline"));
gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_OFFLINE)); gpg_item -> setData(COLUMN_STATE, ROLE_SORT, BuildStateSortString(true, gpg_item->text(COLUMN_NAME), PEER_STATE_OFFLINE));
QFont font; QFont font;
@ -786,6 +799,12 @@ void PeersDialog::insertPeers()
} }
} }
if (gpg_hasPrivateChat) {
gpgIcon = QIcon(":/images/chat.png");
}
gpg_item -> setIcon(COLUMN_NAME, gpgIcon);
if (bNew) { if (bNew) {
/* add gpg item to the list */ /* add gpg item to the list */
peertreeWidget->addTopLevelItem(gpg_item); peertreeWidget->addTopLevelItem(gpg_item);
@ -1044,20 +1063,24 @@ void PeersDialog::updatePeersCustomStateString(const QString& peer_id)
void PeersDialog::updatePeersAvatar(const QString& peer_id) void PeersDialog::updatePeersAvatar(const QString& peer_id)
{ {
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "PeersDialog: Got notified of new avatar for peer " << peer_id.toStdString() << std::endl ; std::cerr << "PeersDialog: Got notified of new avatar for peer " << peer_id.toStdString() << std::endl ;
#endif #endif
PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(),rsPeers->getPeerName(peer_id.toStdString()), 0); PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(), 0);
pcd->updatePeerAvatar(peer_id.toStdString()); if (pcd) {
pcd->updatePeerAvatar(peer_id.toStdString());
}
} }
void PeersDialog::updatePeerStatusString(const QString& peer_id,const QString& status_string,bool is_private_chat) void PeersDialog::updatePeerStatusString(const QString& peer_id,const QString& status_string,bool is_private_chat)
{ {
if(is_private_chat) if(is_private_chat)
{ {
PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(),rsPeers->getPeerName(peer_id.toStdString()), 0); PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(peer_id.toStdString(), 0);
pcd->updateStatusString(peer_id, status_string); if (pcd) {
pcd->updateStatusString(peer_id, status_string);
}
} }
else else
{ {
@ -1069,10 +1092,17 @@ void PeersDialog::updatePeerStatusString(const QString& peer_id,const QString& s
} }
} }
void PeersDialog::publicChatChanged(int type)
{
if (type == NOTIFY_TYPE_ADD) {
insertChat();
}
}
void PeersDialog::insertChat() void PeersDialog::insertChat()
{ {
std::list<ChatInfo> newchat; std::list<ChatInfo> newchat;
if (!rsMsgs->getNewChat(newchat)) if (!rsMsgs->getPublicChatQueue(newchat))
{ {
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "no chat available." << std::endl ; std::cerr << "no chat available." << std::endl ;
@ -1085,8 +1115,6 @@ void PeersDialog::insertChat()
QTextEdit *msgWidget = ui.msgText; QTextEdit *msgWidget = ui.msgText;
std::list<ChatInfo>::iterator it; std::list<ChatInfo>::iterator it;
uint chatflags = Settings->getChatFlags();
/* add in lines at the bottom */ /* add in lines at the bottom */
for(it = newchat.begin(); it != newchat.end(); it++) for(it = newchat.begin(); it != newchat.end(); it++)
{ {
@ -1100,10 +1128,7 @@ void PeersDialog::insertChat()
/* are they private? */ /* are they private? */
if (it->chatflags & RS_CHAT_PRIVATE) if (it->chatflags & RS_CHAT_PRIVATE)
{ {
PopupChatDialog *pcd = PopupChatDialog::getPrivateChat(it->rsid, peer_name, chatflags); /* this should not happen */
pcd->addChatMsg(&(*it));
playsound();
QApplication::alert(pcd);
continue; continue;
} }
@ -1192,25 +1217,22 @@ void PeersDialog::sendMsg()
{ {
QTextEdit *lineWidget = ui.lineEdit; QTextEdit *lineWidget = ui.lineEdit;
ChatInfo ci; //ci.msg = lineWidget->Text().toStdWString();
//ci.msg = lineWidget->Text().toStdWString(); std::wstring message = lineWidget->toHtml().toStdWString();
ci.msg = lineWidget->toHtml().toStdWString();
ci.chatflags = RS_CHAT_PUBLIC;
//historyKeeper.addMessage("THIS", "ALL", lineWidget->toHtml() ); //historyKeeper.addMessage("THIS", "ALL", lineWidget->toHtml() );
std::string msg(ci.msg.begin(), ci.msg.end()); #ifdef PEERS_DEBUG
#ifdef PEERS_DEBUG std::string msg(ci.msg.begin(), ci.msg.end());
std::cerr << "PeersDialog::sendMsg(): " << msg << std::endl; std::cerr << "PeersDialog::sendMsg(): " << msg << std::endl;
#endif #endif
rsMsgs -> ChatSend(ci); rsMsgs->sendPublicChat(message);
ui.lineEdit->clear(); ui.lineEdit->clear();
setFont(); setFont();
/* redraw send list */
insertSendList();
/* redraw send list */
insertSendList();
} }
void PeersDialog::insertSendList() void PeersDialog::insertSendList()
@ -1668,64 +1690,35 @@ void PeersDialog::addAttachment(std::string filePath) {
} }
} }
void PeersDialog::fileHashingFinished(AttachFileItem* file) { void PeersDialog::fileHashingFinished(AttachFileItem* file)
std::cerr << "PeersDialog::fileHashingFinished() started." << std::endl; {
std::cerr << "PeersDialog::fileHashingFinished() started." << std::endl;
//check that the file is ok tos end //check that the file is ok tos end
if (file->getState() == AFI_STATE_ERROR) { if (file->getState() == AFI_STATE_ERROR) {
#ifdef PEERS_DEBUG
std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed." << std::endl;
#endif
return;
}
ChatInfo ci;
{
rsiface->lockData(); /* Lock Interface */
const RsConfig &conf = rsiface->getConfig();
ci.rsid = conf.ownId;
rsiface->unlockData(); /* Unlock Interface */
}
//convert fileSize from uint_64 to string for html link
// char fileSizeChar [100];
// sprintf(fileSizeChar, "%lld", file->FileSize());
// std::string fileSize = *(&fileSizeChar);
std::string mesgString = RetroShareLink(QString::fromStdString(file->FileName()),
file->FileSize(),
QString::fromStdString(file->FileHash())).toHtml().toStdString() ;
// std::string mesgString = "<a href='retroshare://file|" + (file->FileName()) + "|" + fileSize + "|" + (file->FileHash()) + "'>"
// + "retroshare://file|" + (file->FileName()) + "|" + fileSize + "|" + (file->FileHash()) + "</a>";
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "PeersDialog::fileHashingFinished mesgString : " << mesgString << std::endl; std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed." << std::endl;
#endif
return;
}
//convert fileSize from uint_64 to string for html link
// char fileSizeChar [100];
// sprintf(fileSizeChar, "%lld", file->FileSize());
// std::string fileSize = *(&fileSizeChar);
std::string mesgString = RetroShareLink(QString::fromStdString(file->FileName()),
file->FileSize(),
QString::fromStdString(file->FileHash())).toHtml().toStdString() ;
// std::string mesgString = "<a href='retroshare://file|" + (file->FileName()) + "|" + fileSize + "|" + (file->FileHash()) + "'>"
// + "retroshare://file|" + (file->FileName()) + "|" + fileSize + "|" + (file->FileHash()) + "</a>";
#ifdef PEERS_DEBUG
std::cerr << "PeersDialog::fileHashingFinished mesgString : " << mesgString << std::endl;
#endif #endif
const char * messageString = mesgString.c_str (); rsMsgs->sendPublicChat(QString::fromStdString(mesgString).toStdWString());
setFont();
//convert char massageString to w_char
wchar_t* message;
size_t requiredSize = mbstowcs(NULL, messageString, 0); // C4996
/* Add one to leave room for the NULL terminator */
message = (wchar_t *)malloc( (requiredSize + 1) * sizeof( wchar_t ));
if (! message) {
std::cerr << ("Memory allocation failure.\n");
}
size_t size = mbstowcs( message, messageString, requiredSize + 1); // C4996
if (size == (size_t) (-1)) {
printf("Couldn't convert string--invalid multibyte character.\n");
}
ci.msg = message;
ci.chatflags = RS_CHAT_PUBLIC;
rsMsgs -> ChatSend(ci);
setFont();
} }
void PeersDialog::anchorClicked (const QUrl& link ) void PeersDialog::anchorClicked (const QUrl& link )

View file

@ -70,6 +70,7 @@ public:
public slots: public slots:
void insertPeers(); void insertPeers();
void publicChatChanged(int type);
void toggleSendItem( QTreeWidgetItem *item, int col ); void toggleSendItem( QTreeWidgetItem *item, int col );
void insertChat(); void insertChat();
@ -173,7 +174,7 @@ private:
class QSpacerItem *spacerItem; class QSpacerItem *spacerItem;
///play the sound when recv a message ///play the sound when recv a message
void playsound(); void playsound();
QString fileName; QString fileName;

View file

@ -65,12 +65,6 @@ void SendLinkDialog::insertHtmlText(std::string msg)
void SendLinkDialog::sendLinktoChat() void SendLinkDialog::sendLinktoChat()
{ {
ChatInfo ci; rsMsgs->sendPublicChat(ui.linkText->toHtml().toStdWString());
ci.msg = ui.linkText->toHtml().toStdWString();
ci.chatflags = RS_CHAT_PUBLIC;
rsMsgs -> ChatSend(ci);
close(); close();
} }

View file

@ -32,6 +32,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QBuffer> #include <QBuffer>
#include <QTextCodec> #include <QTextCodec>
#include <QSound>
#include <sys/stat.h> #include <sys/stat.h>
#include "PopupChatDialog.h" #include "PopupChatDialog.h"
@ -65,6 +66,25 @@
static std::map<std::string, PopupChatDialog *> chatDialogs; static std::map<std::string, PopupChatDialog *> chatDialogs;
// play sound when recv a message
void playsound()
{
Settings->beginGroup("Sound");
Settings->beginGroup("SoundFilePath");
QString OnlineSound = Settings->value("NewChatMessage","").toString();
Settings->endGroup();
Settings->beginGroup("Enable");
bool flag = Settings->value("NewChatMessage",false).toBool();
Settings->endGroup();
Settings->endGroup();
if (!OnlineSound.isEmpty() && flag) {
if (QSound::isAvailable()) {
QSound::play(OnlineSound);
}
}
}
/** Default constructor */ /** Default constructor */
PopupChatDialog::PopupChatDialog(std::string id, std::string name, PopupChatDialog::PopupChatDialog(std::string id, std::string name,
QWidget *parent, Qt::WFlags flags) QWidget *parent, Qt::WFlags flags)
@ -78,6 +98,7 @@ PopupChatDialog::PopupChatDialog(std::string id, std::string name,
Settings->loadWidgetInformation(this); Settings->loadWidgetInformation(this);
this->move(qrand()%100, qrand()%100); //avoid to stack multiple popup chat windows on the same position this->move(qrand()%100, qrand()%100); //avoid to stack multiple popup chat windows on the same position
m_bInsertOnVisible = true;
loadEmoticons(); loadEmoticons();
@ -202,46 +223,49 @@ void PopupChatDialog::processSettings(bool bLoad)
Settings->endGroup(); Settings->endGroup();
} }
/*static*/ PopupChatDialog *PopupChatDialog::getPrivateChat(std::string id, std::string name, uint chatflags) /*static*/ PopupChatDialog *PopupChatDialog::getPrivateChat(std::string id, uint chatflags)
{ {
/* see if it exists already */ /* see if it exists already */
PopupChatDialog *popupchatdialog = NULL; PopupChatDialog *popupchatdialog = NULL;
bool show = false; bool show = false;
if (chatflags & RS_CHAT_REOPEN) if (chatflags & RS_CHAT_REOPEN)
{ {
show = true; show = true;
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "reopen flag so: enable SHOW popupchatdialog()" << std::endl; std::cerr << "reopen flag so: enable SHOW popupchatdialog()" << std::endl;
#endif #endif
} }
std::map<std::string, PopupChatDialog *>::iterator it; std::map<std::string, PopupChatDialog *>::iterator it;
if (chatDialogs.end() != (it = chatDialogs.find(id))) if (chatDialogs.end() != (it = chatDialogs.find(id)))
{ {
/* exists already */ /* exists already */
popupchatdialog = it->second; popupchatdialog = it->second;
} }
else else
{ {
popupchatdialog = new PopupChatDialog(id, name);
chatDialogs[id] = popupchatdialog;
if (chatflags & RS_CHAT_OPEN_NEW) if (chatflags & RS_CHAT_OPEN_NEW)
{ {
#ifdef PEERS_DEBUG RsPeerDetails sslDetails;
if (rsPeers->getPeerDetails(id, sslDetails)) {
popupchatdialog = new PopupChatDialog(id, sslDetails.name + " - " + sslDetails.location);
chatDialogs[id] = popupchatdialog;
#ifdef PEERS_DEBUG
std::cerr << "new chat so: enable SHOW popupchatdialog()" << std::endl; std::cerr << "new chat so: enable SHOW popupchatdialog()" << std::endl;
#endif #endif
show = true; show = true;
}
} }
} }
if (show) if (show && popupchatdialog)
{ {
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "SHOWING popupchatdialog()" << std::endl; std::cerr << "SHOWING popupchatdialog()" << std::endl;
#endif #endif
if (popupchatdialog->isVisible() == false) { if (popupchatdialog->isVisible() == false) {
if (chatflags & RS_CHAT_FOCUS) { if (chatflags & RS_CHAT_FOCUS) {
@ -250,36 +274,36 @@ void PopupChatDialog::processSettings(bool bLoad)
popupchatdialog->showMinimized(); popupchatdialog->showMinimized();
} }
} }
} }
/* now only do these if the window is visible */ /* now only do these if the window is visible */
if (popupchatdialog->isVisible()) if (popupchatdialog && popupchatdialog->isVisible())
{ {
if (chatflags & RS_CHAT_FOCUS) if (chatflags & RS_CHAT_FOCUS)
{ {
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "focus chat flag so: GETFOCUS popupchatdialog()" << std::endl; std::cerr << "focus chat flag so: GETFOCUS popupchatdialog()" << std::endl;
#endif #endif
popupchatdialog->getfocus(); popupchatdialog->getfocus();
} }
else else
{ {
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "no focus chat flag so: FLASH popupchatdialog()" << std::endl; std::cerr << "no focus chat flag so: FLASH popupchatdialog()" << std::endl;
#endif #endif
popupchatdialog->flash(); popupchatdialog->flash();
} }
} }
else else
{ {
#ifdef PEERS_DEBUG #ifdef PEERS_DEBUG
std::cerr << "not visible ... so leave popupchatdialog()" << std::endl; std::cerr << "not visible ... so leave popupchatdialog()" << std::endl;
#endif #endif
} }
return popupchatdialog; return popupchatdialog;
} }
/*static*/ void PopupChatDialog::cleanupChat() /*static*/ void PopupChatDialog::cleanupChat()
@ -294,6 +318,28 @@ void PopupChatDialog::processSettings(bool bLoad)
chatDialogs.clear(); chatDialogs.clear();
} }
/*static*/ void PopupChatDialog::privateChatChanged()
{
std::list<std::string> ids;
if (!rsMsgs->getPrivateChatQueueIds(ids)) {
#ifdef PEERS_DEBUG
std::cerr << "no chat available." << std::endl ;
#endif
return;
}
uint chatflags = Settings->getChatFlags();
std::list<std::string>::iterator id;
for (id = ids.begin(); id != ids.end(); id++) {
PopupChatDialog *pcd = getPrivateChat(*id, chatflags);
if (pcd) {
pcd->insertChatMsgs();
}
}
}
void PopupChatDialog::chatFriend(std::string id) void PopupChatDialog::chatFriend(std::string id)
{ {
if (id.empty()){ if (id.empty()){
@ -316,14 +362,14 @@ void PopupChatDialog::chatFriend(std::string id)
if (rsPeers->getPeerDetails(*it, sslDetails)) { if (rsPeers->getPeerDetails(*it, sslDetails)) {
if (sslDetails.state & RS_PEER_STATE_CONNECTED) { if (sslDetails.state & RS_PEER_STATE_CONNECTED) {
oneLocationConnected = true; oneLocationConnected = true;
getPrivateChat(*it, sslDetails.name + " - " + sslDetails.location, RS_CHAT_REOPEN | RS_CHAT_FOCUS); getPrivateChat(*it, RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS);
} }
} }
} }
} else { } else {
if (detail.state & RS_PEER_STATE_CONNECTED) { if (detail.state & RS_PEER_STATE_CONNECTED) {
oneLocationConnected = true; oneLocationConnected = true;
getPrivateChat(id, detail.name + " - " + detail.location, RS_CHAT_REOPEN | RS_CHAT_FOCUS); getPrivateChat(id, RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS);
} }
} }
@ -426,6 +472,13 @@ void PopupChatDialog::flash()
} }
void PopupChatDialog::showEvent(QShowEvent *event)
{
if (m_bInsertOnVisible) {
insertChatMsgs();
}
}
void PopupChatDialog::closeEvent (QCloseEvent * event) void PopupChatDialog::closeEvent (QCloseEvent * event)
{ {
Settings->saveWidgetInformation(this); Settings->saveWidgetInformation(this);
@ -442,74 +495,95 @@ void PopupChatDialog::updateChat()
} }
void PopupChatDialog::addChatMsg(ChatInfo *ci) void PopupChatDialog::insertChatMsgs()
{ {
if (isVisible() == false) {
m_bInsertOnVisible = true;
return;
}
{ m_bInsertOnVisible = false;
RsPeerDetails detail;
if (!rsPeers->getPeerDetails(dialogId, detail)) std::list<ChatInfo> newchat;
{ if (!rsMsgs->getPrivateChatQueue(dialogId, newchat))
#ifdef CHAT_DEBUG {
std::cerr << "WARNING CANNOT GET PEER INFO!!!!" << std::endl; #ifdef PEERS_DEBUG
std::cerr << "no chat for " << dialogId << " available." << std::endl ;
#endif #endif
} return;
}
} std::list<ChatInfo>::iterator it;
for(it = newchat.begin(); it != newchat.end(); it++) {
QString timestamp = "[" + QDateTime::currentDateTime().toString("hh:mm:ss") + "]"; /* are they public? */
QString name = QString::fromStdString(rsPeers->getPeerName(ci->rsid)); if ((it->chatflags & RS_CHAT_PRIVATE) == 0) {
QString message = QString::fromStdWString(ci -> msg); /* this should not happen */
continue;
//replace http://, https:// and www. with <a href> links
QRegExp rx("(retroshare://[^ <>]*)|(https?://[^ <>]*)|(www\\.[^ <>]*)");
int count = 0;
int pos = 100; //ignore the first 100 char because of the standard DTD ref
while ( (pos = rx.indexIn(message, pos)) != -1 ) {
//we need to look ahead to see if it's already a well formed link
if (message.mid(pos - 6, 6) != "href=\"" && message.mid(pos - 6, 6) != "href='" && message.mid(pos - 6, 6) != "ttp://" ) {
QString tempMessg = message.left(pos) + "<a href=\"" + rx.cap(count) + "\">" + rx.cap(count) + "</a>" + message.mid(pos + rx.matchedLength(), -1);
message = tempMessg;
}
pos += rx.matchedLength() + 15;
count ++;
} }
addChatMsg(it->rsid, it->msg);
}
playsound();
QApplication::alert(this);
}
void PopupChatDialog::addChatMsg(std::string &id, std::wstring &msg)
{
QString timestamp = "[" + QDateTime::currentDateTime().toString("hh:mm:ss") + "]";
QString name = QString::fromStdString(rsPeers->getPeerName(id));
QString message = QString::fromStdWString(msg);
//replace http://, https:// and www. with <a href> links
QRegExp rx("(retroshare://[^ <>]*)|(https?://[^ <>]*)|(www\\.[^ <>]*)");
int count = 0;
int pos = 100; //ignore the first 100 char because of the standard DTD ref
while ( (pos = rx.indexIn(message, pos)) != -1 ) {
//we need to look ahead to see if it's already a well formed link
if (message.mid(pos - 6, 6) != "href=\"" && message.mid(pos - 6, 6) != "href='" && message.mid(pos - 6, 6) != "ttp://" ) {
QString tempMessg = message.left(pos) + "<a href=\"" + rx.cap(count) + "\">" + rx.cap(count) + "</a>" + message.mid(pos + rx.matchedLength(), -1);
message = tempMessg;
}
pos += rx.matchedLength() + 15;
count ++;
}
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cout << "PopupChatDialog:addChatMsg message : " << message.toStdString() << std::endl; std::cout << "PopupChatDialog:addChatMsg message : " << message.toStdString() << std::endl;
#endif #endif
if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool()) if (Settings->valueFromGroup(QString("Chat"), QString::fromUtf8("Emoteicons_PrivatChat"), true).toBool())
{ {
QHashIterator<QString, QString> i(smileys); QHashIterator<QString, QString> i(smileys);
while(i.hasNext()) while(i.hasNext())
{ {
i.next(); i.next();
foreach(QString code, i.key().split("|")) foreach(QString code, i.key().split("|"))
message.replace(code, "<img src=\"" + i.value() + "\" />"); message.replace(code, "<img src=\"" + i.value() + "\" />");
} }
} }
history /*<< nickColor << color << font << fontSize*/ << timestamp << name << message; history /*<< nickColor << color << font << fontSize*/ << timestamp << name << message;
QString formatMsg = loadEmptyStyle()/*.replace(nickColor) QString formatMsg = loadEmptyStyle()/*.replace(nickColor)
.replace(color) .replace(color)
.replace(font) .replace(font)
.replace(fontSize)*/ .replace(fontSize)*/
.replace("%timestamp%", timestamp) .replace("%timestamp%", timestamp)
.replace("%name%", name) .replace("%name%", name)
.replace("%message%", message); .replace("%message%", message);
if ((ui.textBrowser->verticalScrollBar()->maximum() - 30) < ui.textBrowser->verticalScrollBar()->value() ) {
ui.textBrowser->append(formatMsg + "\n"); if ((ui.textBrowser->verticalScrollBar()->maximum() - 30) < ui.textBrowser->verticalScrollBar()->value() ) {
} else { ui.textBrowser->append(formatMsg + "\n");
//the vertical scroll is not at the bottom, so just update the text, the scroll will stay at the current position } else {
int scroll = ui.textBrowser->verticalScrollBar()->value(); //the vertical scroll is not at the bottom, so just update the text, the scroll will stay at the current position
ui.textBrowser->setHtml(ui.textBrowser->toHtml() + formatMsg + "\n"); int scroll = ui.textBrowser->verticalScrollBar()->value();
ui.textBrowser->verticalScrollBar()->setValue(scroll); ui.textBrowser->setHtml(ui.textBrowser->toHtml() + formatMsg + "\n");
ui.textBrowser->update(); ui.textBrowser->verticalScrollBar()->setValue(scroll);
} ui.textBrowser->update();
resetStatusBar() ; }
resetStatusBar() ;
} }
void PopupChatDialog::checkChat() void PopupChatDialog::checkChat()
@ -527,36 +601,32 @@ void PopupChatDialog::checkChat()
void PopupChatDialog::sendChat() void PopupChatDialog::sendChat()
{ {
QTextEdit *chatWidget = ui.chattextEdit; QTextEdit *chatWidget = ui.chattextEdit;
ChatInfo ci; std::string ownId;
{ {
rsiface->lockData(); /* Lock Interface */ rsiface->lockData(); /* Lock Interface */
const RsConfig &conf = rsiface->getConfig(); const RsConfig &conf = rsiface->getConfig();
ci.rsid = conf.ownId; ownId = conf.ownId;
rsiface->unlockData(); /* Unlock Interface */ rsiface->unlockData(); /* Unlock Interface */
} }
ci.msg = chatWidget->toHtml().toStdWString(); std::wstring msg = chatWidget->toHtml().toStdWString();
ci.chatflags = RS_CHAT_PRIVATE;
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cout << "PopupChatDialog:sendChat " << styleHtm.toStdString() << std::endl; std::cout << "PopupChatDialog:sendChat " << styleHtm.toStdString() << std::endl;
#endif #endif
addChatMsg(&ci); addChatMsg(ownId, msg);
/* put proper destination */ rsMsgs->sendPrivateChat(dialogId, msg);
ci.rsid = dialogId; chatWidget->clear();
setFont();
rsMsgs -> ChatSend(ci); /* redraw send list */
chatWidget ->clear();
setFont();
/* redraw send list */
} }
/** /**
@ -982,53 +1052,48 @@ void PopupChatDialog::addAttachment(std::string filePath,int flag)
void PopupChatDialog::fileHashingFinished(AttachFileItem* file) void PopupChatDialog::fileHashingFinished(AttachFileItem* file)
{ {
std::cerr << "PopupChatDialog::fileHashingFinished() started."; std::cerr << "PopupChatDialog::fileHashingFinished() started.";
std::cerr << std::endl; std::cerr << std::endl;
//check that the file is ok tos end //check that the file is ok tos end
if (file->getState() == AFI_STATE_ERROR) { if (file->getState() == AFI_STATE_ERROR) {
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed."; std::cerr << "PopupChatDialog::fileHashingFinished error file is not hashed.";
#endif #endif
return; return;
} }
ChatInfo ci; std::string ownId;
{ {
rsiface->lockData(); /* Lock Interface */ rsiface->lockData(); /* Lock Interface */
const RsConfig &conf = rsiface->getConfig(); const RsConfig &conf = rsiface->getConfig();
ci.rsid = conf.ownId; ownId = conf.ownId;
rsiface->unlockData(); /* Unlock Interface */
}
QString message;
rsiface->unlockData(); /* Unlock Interface */
}
QString message;
if(file->getPicFlag()==1){ if(file->getPicFlag()==1){
message+="<img src=\"file:///"; message+="<img src=\"file:///";
message+=file->FilePath().c_str(); message+=file->FilePath().c_str();
message+="\" width=\"100\" height=\"100\">"; message+="\" width=\"100\" height=\"100\">";
message+="<br>"; message+="<br>";
} }
message+= RetroShareLink(QString::fromStdString(file->FileName()),file->FileSize(),QString::fromStdString(file->FileHash())).toHtmlSize(); message+= RetroShareLink(QString::fromStdString(file->FileName()),file->FileSize(),QString::fromStdString(file->FileHash())).toHtmlSize();
#ifdef CHAT_DEBUG #ifdef CHAT_DEBUG
std::cerr << "PopupChatDialog::anchorClicked message : " << message.toStdString() << std::endl; std::cerr << "PopupChatDialog::anchorClicked message : " << message.toStdString() << std::endl;
#endif #endif
std::wstring msg = message.toStdWString();
ci.msg = message.toStdWString(); addChatMsg(ownId, msg);
ci.chatflags = RS_CHAT_PRIVATE;
addChatMsg(&ci); rsMsgs->sendPrivateChat(dialogId, msg);
/* put proper destination */
ci.rsid = dialogId;
rsMsgs -> ChatSend(ci);
} }
void PopupChatDialog::anchorClicked (const QUrl& link ) void PopupChatDialog::anchorClicked (const QUrl& link )

View file

@ -36,23 +36,14 @@ class PopupChatDialog : public QMainWindow
Q_OBJECT Q_OBJECT
public: public:
static PopupChatDialog *getPrivateChat(std::string id, std::string name, uint chatflags); static PopupChatDialog *getPrivateChat(std::string id, uint chatflags);
static void cleanupChat(); static void cleanupChat();
static void chatFriend(std::string id); static void chatFriend(std::string id);
static void updateAllAvatars(); static void updateAllAvatars();
static void privateChatChanged();
void updateChat(); void updateChat();
void updatePeerAvatar(const std::string&); void updatePeerAvatar(const std::string&);
void addChatMsg(ChatInfo *ci);
void loadEmoticons();
void loadEmoticons2();
void updateAvatar();
QString loadEmptyStyle();
QPixmap picture;
public slots: public slots:
/** Overloaded QWidget.show */ /** Overloaded QWidget.show */
@ -84,9 +75,20 @@ protected:
~PopupChatDialog(); ~PopupChatDialog();
void closeEvent (QCloseEvent * event); void closeEvent (QCloseEvent * event);
void showEvent (QShowEvent * event);
virtual void dragEnterEvent(QDragEnterEvent *event); virtual void dragEnterEvent(QDragEnterEvent *event);
virtual void dropEvent(QDropEvent *event); virtual void dropEvent(QDropEvent *event);
void insertChatMsgs();
void addChatMsg(std::string &id, std::wstring &msg);
void loadEmoticons();
void loadEmoticons2();
void updateAvatar();
QString loadEmptyStyle();
QPixmap picture;
private slots: private slots:
void addExtraFile(); void addExtraFile();
@ -135,7 +137,9 @@ private:
QStringList history; QStringList history;
QString wholeChat; QString wholeChat;
QString fileName; QString fileName;
bool m_bInsertOnVisible;
/** Qt Designer generated object */ /** Qt Designer generated object */
Ui::PopupChatDialog ui; Ui::PopupChatDialog ui;

View file

@ -226,11 +226,17 @@ void NotifyQt::notifyListChange(int list, int type)
#endif #endif
emit forumsChanged(); // use connect with Qt::QueuedConnection emit forumsChanged(); // use connect with Qt::QueuedConnection
break; break;
case NOTIFY_LIST_CHAT: case NOTIFY_LIST_PUBLIC_CHAT:
#ifdef NOTIFY_DEBUG #ifdef NOTIFY_DEBUG
std::cerr << "received chat changed" << std::endl ; std::cerr << "received public chat changed" << std::endl ;
#endif #endif
emit chatChanged(); emit publicChatChanged(type);
break;
case NOTIFY_LIST_PRIVATE_CHAT:
#ifdef NOTIFY_DEBUG
std::cerr << "received private chat changed" << std::endl ;
#endif
emit privateChatChanged(type);
break; break;
default: default:
break; break;

View file

@ -72,7 +72,8 @@ class NotifyQt: public QObject, public NotifyBase
void diskFull(int,int) const ; void diskFull(int,int) const ;
void peerStatusChanged(const QString& /* peer_id */, int /* status */); void peerStatusChanged(const QString& /* peer_id */, int /* status */);
void peerStatusChangedSummary() const; void peerStatusChangedSummary() const;
void chatChanged() const ; void publicChatChanged(int type) const ;
void privateChatChanged(int type) const ;
public slots: public slots:

View file

@ -181,7 +181,8 @@ int main(int argc, char *argv[])
QObject::connect(notify,SIGNAL(filesPostModChanged(bool)) ,w ,SLOT(postModDirectories(bool) )) ; QObject::connect(notify,SIGNAL(filesPostModChanged(bool)) ,w ,SLOT(postModDirectories(bool) )) ;
QObject::connect(notify,SIGNAL(transfersChanged()) ,w->transfersDialog ,SLOT(insertTransfers() )) ; QObject::connect(notify,SIGNAL(transfersChanged()) ,w->transfersDialog ,SLOT(insertTransfers() )) ;
QObject::connect(notify,SIGNAL(friendsChanged()) ,w->peersDialog ,SLOT(insertPeers() )) ; QObject::connect(notify,SIGNAL(friendsChanged()) ,w->peersDialog ,SLOT(insertPeers() )) ;
QObject::connect(notify,SIGNAL(chatChanged()) ,w->peersDialog ,SLOT(insertChat() )); QObject::connect(notify,SIGNAL(publicChatChanged(int)) ,w->peersDialog ,SLOT(publicChatChanged(int) ));
QObject::connect(notify,SIGNAL(privateChatChanged(int)) ,w ,SLOT(privateChatChanged(int) ));
QObject::connect(notify,SIGNAL(neighborsChanged()) ,w->networkDialog ,SLOT(insertConnect() )) ; QObject::connect(notify,SIGNAL(neighborsChanged()) ,w->networkDialog ,SLOT(insertConnect() )) ;
QObject::connect(notify,SIGNAL(messagesChanged()) ,w->messagesDialog ,SLOT(insertMessages() )) ; QObject::connect(notify,SIGNAL(messagesChanged()) ,w->messagesDialog ,SLOT(insertMessages() )) ;
QObject::connect(notify,SIGNAL(messagesTagsChanged()) ,w->messagesDialog ,SLOT(messagesTagsChanged() )) ; QObject::connect(notify,SIGNAL(messagesTagsChanged()) ,w->messagesDialog ,SLOT(messagesTagsChanged() )) ;