mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Save incoming not read private chat messages in config and delete it after reading.
Added queue for outgoing private offline chat messages. The queue is also saved until the private chat message could be delivered. It does not work in the short time between the shutdown of the peer and the switch of the state to offline for that peer. For this we need a response of the peer. Need recompile. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3517 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
412cf5f928
commit
37fe5ff3a3
@ -216,19 +216,20 @@ class NotifyBase
|
||||
virtual std::string askForPassword(const std::string& /* key_details */ ,bool /* prev_is_bad */ ) { return "" ;}
|
||||
};
|
||||
|
||||
const int NOTIFY_LIST_NEIGHBOURS = 1;
|
||||
const int NOTIFY_LIST_FRIENDS = 2;
|
||||
const int NOTIFY_LIST_SEARCHLIST = 4;
|
||||
const int NOTIFY_LIST_MESSAGELIST = 5;
|
||||
const int NOTIFY_LIST_CHANNELLIST = 6;
|
||||
const int NOTIFY_LIST_TRANSFERLIST = 7;
|
||||
const int NOTIFY_LIST_CONFIG = 8;
|
||||
const int NOTIFY_LIST_DIRLIST_LOCAL = 9;
|
||||
const int NOTIFY_LIST_DIRLIST_FRIENDS = 10;
|
||||
const int NOTIFY_LIST_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection
|
||||
const int NOTIFY_LIST_MESSAGE_TAGS = 12;
|
||||
const int NOTIFY_LIST_PUBLIC_CHAT = 13;
|
||||
const int NOTIFY_LIST_PRIVATE_CHAT = 14;
|
||||
const int NOTIFY_LIST_NEIGHBOURS = 1;
|
||||
const int NOTIFY_LIST_FRIENDS = 2;
|
||||
const int NOTIFY_LIST_SEARCHLIST = 4;
|
||||
const int NOTIFY_LIST_MESSAGELIST = 5;
|
||||
const int NOTIFY_LIST_CHANNELLIST = 6;
|
||||
const int NOTIFY_LIST_TRANSFERLIST = 7;
|
||||
const int NOTIFY_LIST_CONFIG = 8;
|
||||
const int NOTIFY_LIST_DIRLIST_LOCAL = 9;
|
||||
const int NOTIFY_LIST_DIRLIST_FRIENDS = 10;
|
||||
const int NOTIFY_LIST_FORUMLIST_LOCKED = 11; // use connect with Qt::QueuedConnection
|
||||
const int NOTIFY_LIST_MESSAGE_TAGS = 12;
|
||||
const int NOTIFY_LIST_PUBLIC_CHAT = 13;
|
||||
const int NOTIFY_LIST_PRIVATE_INCOMING_CHAT = 14;
|
||||
const int NOTIFY_LIST_PRIVATE_OUTGOING_CHAT = 15;
|
||||
|
||||
const int NOTIFY_TYPE_SAME = 0x01;
|
||||
const int NOTIFY_TYPE_MOD = 0x02; /* general purpose, check all */
|
||||
|
@ -177,10 +177,12 @@ virtual bool resetMessageStandardTagTypes(MsgTagType& tags) = 0;
|
||||
/* Chat */
|
||||
virtual bool sendPublicChat(std::wstring msg) = 0;
|
||||
virtual bool sendPrivateChat(std::string id, std::wstring msg) = 0;
|
||||
virtual int getChatQueueCount(bool privateQueue) = 0;
|
||||
virtual int getPublicChatQueueCount() = 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 int getPrivateChatQueueCount(bool incoming) = 0;
|
||||
virtual bool getPrivateChatQueueIds(bool incoming, std::list<std::string> &ids) = 0;
|
||||
virtual bool getPrivateChatQueue(bool incoming, std::string id, std::list<ChatInfo> &chats) = 0;
|
||||
virtual bool clearPrivateChatQueue(bool incoming, std::string id) = 0;
|
||||
virtual void sendStatusString(const std::string& id,const std::string& status_string) = 0 ;
|
||||
virtual void sendGroupChatStatusString(const std::string& status_string) = 0 ;
|
||||
|
||||
|
@ -156,9 +156,9 @@ void p3Msgs::sendStatusString(const std::string& peer_id,const std::string& stat
|
||||
mChatSrv->sendStatusString(peer_id,status_string);
|
||||
}
|
||||
|
||||
int p3Msgs::getChatQueueCount(bool privateQueue)
|
||||
int p3Msgs::getPublicChatQueueCount()
|
||||
{
|
||||
return mChatSrv->getChatQueueCount(privateQueue);
|
||||
return mChatSrv->getPublicChatQueueCount();
|
||||
}
|
||||
|
||||
bool p3Msgs::getPublicChatQueue(std::list<ChatInfo> &chats)
|
||||
@ -166,14 +166,24 @@ bool p3Msgs::getPublicChatQueue(std::list<ChatInfo> &chats)
|
||||
return mChatSrv->getPublicChatQueue(chats);
|
||||
}
|
||||
|
||||
bool p3Msgs::getPrivateChatQueueIds(std::list<std::string> &ids)
|
||||
int p3Msgs::getPrivateChatQueueCount(bool incoming)
|
||||
{
|
||||
return mChatSrv->getPrivateChatQueueIds(ids);
|
||||
return mChatSrv->getPrivateChatQueueCount(incoming);
|
||||
}
|
||||
|
||||
bool p3Msgs::getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats)
|
||||
bool p3Msgs::getPrivateChatQueueIds(bool incoming, std::list<std::string> &ids)
|
||||
{
|
||||
return mChatSrv->getPrivateChatQueue(id, chats);
|
||||
return mChatSrv->getPrivateChatQueueIds(incoming, ids);
|
||||
}
|
||||
|
||||
bool p3Msgs::getPrivateChatQueue(bool incoming, std::string id, std::list<ChatInfo> &chats)
|
||||
{
|
||||
return mChatSrv->getPrivateChatQueue(incoming, id, chats);
|
||||
}
|
||||
|
||||
bool p3Msgs::clearPrivateChatQueue(bool incoming, std::string id)
|
||||
{
|
||||
return mChatSrv->clearPrivateChatQueue(incoming, id);
|
||||
}
|
||||
|
||||
void p3Msgs::getOwnAvatarData(unsigned char *& data,int& size)
|
||||
|
@ -119,23 +119,35 @@ class p3Msgs: public RsMsgs
|
||||
* returns the count of messages in public or private queue
|
||||
* @param public or private queue
|
||||
*/
|
||||
virtual int getChatQueueCount(bool privateQueue);
|
||||
virtual int getPublicChatQueueCount();
|
||||
|
||||
/*!
|
||||
* @param chats ref to list of received public chats is stored here
|
||||
*/
|
||||
virtual bool getPublicChatQueue(std::list<ChatInfo> &chats);
|
||||
|
||||
/*!
|
||||
* returns the count of messages in private queue
|
||||
* @param public or private queue
|
||||
*/
|
||||
virtual int getPrivateChatQueueCount(bool incoming);
|
||||
|
||||
/*!
|
||||
* @param id's of available private chat messages
|
||||
*/
|
||||
virtual bool getPrivateChatQueueIds(std::list<std::string> &ids);
|
||||
virtual bool getPrivateChatQueueIds(bool incoming, 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);
|
||||
virtual bool getPrivateChatQueue(bool incoming, std::string id, std::list<ChatInfo> &chats);
|
||||
|
||||
/*!
|
||||
* @param clear private chat queue
|
||||
*/
|
||||
virtual bool clearPrivateChatQueue(bool incoming, std::string id);
|
||||
|
||||
/*!
|
||||
* sends immediate status string to a specific peer, e.g. in a private chat
|
||||
* @param peer_id peer to send status string to
|
||||
|
@ -2302,6 +2302,7 @@ int RsServer::StartupRetroShare()
|
||||
#ifndef MINIMAL_LIBRS
|
||||
mConnMgr->addMonitor(msgSrv);
|
||||
mConnMgr->addMonitor(mStatusSrv);
|
||||
mConnMgr->addMonitor(chatSrv);
|
||||
#endif // MINIMAL_LIBRS
|
||||
|
||||
/* must also add the controller as a Monitor...
|
||||
|
@ -56,6 +56,31 @@ std::ostream& RsChatMsgItem::print(std::ostream &out, uint16_t indent)
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& RsPrivateChatMsgConfigItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsPrivateChatMsgConfigItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
out << "peerId: " << configPeerId << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "QblogMs " << chatFlags << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "QblogMs " << configFlags << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "sendTime: " << sendTime << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
|
||||
std::string cnv_message(message.begin(), message.end());
|
||||
out << "msg: " << cnv_message << std::endl;
|
||||
|
||||
printRsItemEnd(out, "RsPrivateChatMsgConfigItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& RsChatStatusItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsChatStatusItem", indent);
|
||||
@ -110,9 +135,10 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
|
||||
switch(getRsItemSubType(rstype))
|
||||
{
|
||||
case RS_PKT_SUBTYPE_DEFAULT: return new RsChatMsgItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_STATUS: return new RsChatStatusItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_DEFAULT: return new RsChatMsgItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG: return new RsPrivateChatMsgConfigItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_STATUS: return new RsChatStatusItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(data,*pktsize) ;
|
||||
default:
|
||||
std::cerr << "Unknown packet type in chat!" << std::endl ;
|
||||
return NULL ;
|
||||
@ -129,6 +155,19 @@ uint32_t RsChatMsgItem::serial_size()
|
||||
return s;
|
||||
}
|
||||
|
||||
uint32_t RsPrivateChatMsgConfigItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
s += GetTlvStringSize(configPeerId);
|
||||
s += 4; /* chatFlags */
|
||||
s += 4; /* configFlags */
|
||||
s += 4; /* sendTime */
|
||||
s += GetTlvWideStringSize(message);
|
||||
s += 4; /* recvTime */
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
uint32_t RsChatStatusItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
@ -198,6 +237,47 @@ bool RsChatMsgItem::serialise(void *data, uint32_t& pktsize)
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsPrivateChatMsgConfigItem::serialise(void *data, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "RsChatSerialiser::serialiseItem() Header: " << ok << std::endl;
|
||||
std::cerr << "RsChatSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_PEERID, configPeerId);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chatFlags);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, configFlags);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, sendTime);
|
||||
ok &= SetTlvWideString(data, tlvsize, &offset, TLV_TYPE_WSTR_MSG, message);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, recvTime);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "RsChatSerialiser::serialiseItem() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsChatStatusItem::serialise(void *data, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
@ -302,6 +382,53 @@ RsChatMsgItem::RsChatMsgItem(void *data,uint32_t size)
|
||||
std::cerr << "Unknown error while deserializing." << std::endl ;
|
||||
}
|
||||
|
||||
RsPrivateChatMsgConfigItem::RsPrivateChatMsgConfigItem(void *data,uint32_t size)
|
||||
: RsChatItem(RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
bool ok = true ;
|
||||
|
||||
/* get mandatory parts first */
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_PEERID, configPeerId);
|
||||
ok &= getRawUInt32(data, rssize, &offset, &chatFlags);
|
||||
ok &= getRawUInt32(data, rssize, &offset, &configFlags);
|
||||
ok &= getRawUInt32(data, rssize, &offset, &sendTime);
|
||||
ok &= GetTlvWideString(data, rssize, &offset, TLV_TYPE_WSTR_MSG, message);
|
||||
ok &= getRawUInt32(data, rssize, &offset, &recvTime);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "Building new chat msg config item." << std::endl ;
|
||||
#endif
|
||||
if (offset != rssize)
|
||||
std::cerr << "Size error while deserializing." << std::endl ;
|
||||
if (!ok)
|
||||
std::cerr << "Unknown error while deserializing." << std::endl ;
|
||||
}
|
||||
|
||||
/* set data from RsChatMsgItem to RsPrivateChatMsgConfigItem */
|
||||
void RsPrivateChatMsgConfigItem::set(RsChatMsgItem *ci, const std::string &peerId, uint32_t confFlags)
|
||||
{
|
||||
PeerId(ci->PeerId());
|
||||
configPeerId = ci->PeerId();
|
||||
chatFlags = ci->chatFlags;
|
||||
configFlags = confFlags;
|
||||
sendTime = ci->sendTime;
|
||||
message = ci->message;
|
||||
recvTime = ci->recvTime;
|
||||
}
|
||||
|
||||
/* get data from RsPrivateChatMsgConfigItem to RsChatMsgItem */
|
||||
void RsPrivateChatMsgConfigItem::get(RsChatMsgItem *ci)
|
||||
{
|
||||
ci->PeerId(configPeerId);
|
||||
ci->chatFlags = chatFlags;
|
||||
//configFlags not used
|
||||
ci->sendTime = sendTime;
|
||||
ci->message = message;
|
||||
ci->recvTime = recvTime;
|
||||
}
|
||||
|
||||
RsChatStatusItem::RsChatStatusItem(void *data,uint32_t size)
|
||||
: RsChatItem(RS_PKT_SUBTYPE_CHAT_STATUS)
|
||||
{
|
||||
|
@ -44,8 +44,11 @@ const uint32_t RS_CHAT_FLAG_PUBLIC = 0x0020;
|
||||
const uint32_t RS_CHAT_FLAG_REQUEST_CUSTOM_STATE = 0x0040;
|
||||
const uint32_t RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE = 0x0080;
|
||||
|
||||
const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ; // default is 0x01
|
||||
const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ; // default is 0x01
|
||||
const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001;
|
||||
|
||||
const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ; // default is 0x01
|
||||
const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ; // default is 0x01
|
||||
const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ; // default is 0x01
|
||||
|
||||
// for defining tags themselves and msg tags
|
||||
const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03;
|
||||
@ -86,7 +89,37 @@ class RsChatMsgItem: public RsChatItem
|
||||
uint32_t sendTime;
|
||||
std::wstring message;
|
||||
/* not serialised */
|
||||
uint32_t recvTime;
|
||||
uint32_t recvTime;
|
||||
};
|
||||
|
||||
/*!
|
||||
* For saving incoming and outgoing chat msgs
|
||||
* @see p3ChatService
|
||||
*/
|
||||
class RsPrivateChatMsgConfigItem: public RsChatItem
|
||||
{
|
||||
public:
|
||||
RsPrivateChatMsgConfigItem() :RsChatItem(RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG) {}
|
||||
RsPrivateChatMsgConfigItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual ~RsPrivateChatMsgConfigItem() {}
|
||||
virtual void clear() {}
|
||||
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
||||
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
||||
|
||||
/* set data from RsChatMsgItem to RsPrivateChatMsgConfigItem */
|
||||
void set(RsChatMsgItem *ci, const std::string &peerId, uint32_t confFlags);
|
||||
/* get data from RsPrivateChatMsgConfigItem to RsChatMsgItem */
|
||||
void get(RsChatMsgItem *ci);
|
||||
|
||||
std::string configPeerId;
|
||||
uint32_t chatFlags;
|
||||
uint32_t configFlags;
|
||||
uint32_t sendTime;
|
||||
std::wstring message;
|
||||
uint32_t recvTime;
|
||||
};
|
||||
|
||||
// This class contains activity info for the sending peer: active, idle, typing, etc.
|
||||
|
@ -203,7 +203,7 @@ void p3ChatService::sendStatusString( const std::string& id , const std::string&
|
||||
sendItem(cs);
|
||||
}
|
||||
|
||||
int p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
|
||||
bool p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
|
||||
{
|
||||
// make chat item....
|
||||
#ifdef CHAT_DEBUG
|
||||
@ -218,6 +218,20 @@ int p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
|
||||
ci->sendTime = time(NULL);
|
||||
ci->message = msg;
|
||||
|
||||
if (!mConnMgr->isOnline(id)) {
|
||||
/* peer is offline, add to outgoing list */
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
privateOutgoingList.push_back(ci);
|
||||
}
|
||||
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD);
|
||||
|
||||
IndicateConfigChanged();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<std::string,AvatarInfo*>::iterator it = _avatars.find(id) ;
|
||||
@ -278,7 +292,7 @@ int p3ChatService::sendPrivateChat(std::string &id, std::wstring &msg)
|
||||
sendItem(cs) ;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void p3ChatService::receiveChatQueue()
|
||||
@ -288,7 +302,7 @@ void p3ChatService::receiveChatQueue()
|
||||
|
||||
time_t now = time(NULL);
|
||||
RsItem *item ;
|
||||
|
||||
|
||||
while(NULL != (item=recvItem()))
|
||||
{
|
||||
#ifdef CHAT_DEBUG
|
||||
@ -348,7 +362,7 @@ void p3ChatService::receiveChatQueue()
|
||||
|
||||
if (ci->chatFlags & RS_CHAT_FLAG_PRIVATE) {
|
||||
privateChanged = true;
|
||||
privateList.push_back(ci); // don't delete the item !!
|
||||
privateIncomingList.push_back(ci); // don't delete the item !!
|
||||
} else {
|
||||
publicChanged = true;
|
||||
publicList.push_back(ci); // don't delete the item !!
|
||||
@ -413,18 +427,16 @@ void p3ChatService::receiveChatQueue()
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PUBLIC_CHAT, NOTIFY_TYPE_ADD);
|
||||
}
|
||||
if (privateChanged) {
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_CHAT, NOTIFY_TYPE_ADD);
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD);
|
||||
|
||||
IndicateConfigChanged(); // only private chat messages are saved
|
||||
}
|
||||
}
|
||||
|
||||
int p3ChatService::getChatQueueCount(bool privateQueue)
|
||||
int p3ChatService::getPublicChatQueueCount()
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
if (privateQueue) {
|
||||
return privateList.size();
|
||||
}
|
||||
|
||||
return publicList.size();
|
||||
}
|
||||
|
||||
@ -462,19 +474,38 @@ bool p3ChatService::getPublicChatQueue(std::list<ChatInfo> &chats)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3ChatService::getPrivateChatQueueIds(std::list<std::string> &ids)
|
||||
int p3ChatService::getPrivateChatQueueCount(bool incoming)
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
if (incoming) {
|
||||
return privateIncomingList.size();
|
||||
}
|
||||
|
||||
return privateOutgoingList.size();
|
||||
}
|
||||
|
||||
bool p3ChatService::getPrivateChatQueueIds(bool incoming, std::list<std::string> &ids)
|
||||
{
|
||||
ids.clear();
|
||||
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::list<RsChatMsgItem *> *list;
|
||||
|
||||
if (incoming) {
|
||||
list = &privateIncomingList;
|
||||
} else {
|
||||
list = &privateOutgoingList;
|
||||
}
|
||||
|
||||
// get the items from the private list.
|
||||
if (privateList.size() == 0) {
|
||||
if (list->size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator it;
|
||||
for (it = privateList.begin(); it != privateList.end(); it++) {
|
||||
for (it = list->begin(); it != list->end(); it++) {
|
||||
RsChatMsgItem *c = *it;
|
||||
|
||||
if (std::find(ids.begin(), ids.end(), c->PeerId()) == ids.end()) {
|
||||
@ -485,34 +516,69 @@ bool p3ChatService::getPrivateChatQueueIds(std::list<std::string> &ids)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3ChatService::getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats)
|
||||
bool p3ChatService::getPrivateChatQueue(bool incoming, const std::string &id, std::list<ChatInfo> &chats)
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::list<RsChatMsgItem *> *list;
|
||||
|
||||
if (incoming) {
|
||||
list = &privateIncomingList;
|
||||
} else {
|
||||
list = &privateOutgoingList;
|
||||
}
|
||||
|
||||
// get the items from the private list.
|
||||
if (list->size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator it;
|
||||
for (it = list->begin(); it != list->end(); it++) {
|
||||
RsChatMsgItem *c = *it;
|
||||
|
||||
if (c->PeerId() == id) {
|
||||
ChatInfo ci;
|
||||
initRsChatInfo(c, ci);
|
||||
chats.push_back(ci);
|
||||
}
|
||||
}
|
||||
|
||||
return (chats.size() > 0);
|
||||
}
|
||||
|
||||
bool p3ChatService::clearPrivateChatQueue(bool incoming, const std::string &id)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::list<RsChatMsgItem *> *list;
|
||||
|
||||
if (incoming) {
|
||||
list = &privateIncomingList;
|
||||
} else {
|
||||
list = &privateOutgoingList;
|
||||
}
|
||||
|
||||
// get the items from the private list.
|
||||
if (privateList.size() == 0) {
|
||||
if (list->size() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator it = privateList.begin();
|
||||
while (it != privateList.end()) {
|
||||
std::list<RsChatMsgItem *>::iterator it = list->begin();
|
||||
while (it != list->end()) {
|
||||
RsChatMsgItem *c = *it;
|
||||
|
||||
if (c->PeerId() == id) {
|
||||
ChatInfo ci;
|
||||
initRsChatInfo(c, ci);
|
||||
chats.push_back(ci);
|
||||
|
||||
changed = true;
|
||||
|
||||
delete c;
|
||||
changed = true;
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator it1 = it;
|
||||
it++;
|
||||
privateList.erase(it1);
|
||||
list->erase(it1);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -521,7 +587,9 @@ bool p3ChatService::getPrivateChatQueue(std::string id, std::list<ChatInfo> &cha
|
||||
} /* UNLOCKED */
|
||||
|
||||
if (changed) {
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_CHAT, NOTIFY_TYPE_DEL);
|
||||
rsicontrol->getNotify().notifyListChange(incoming ? NOTIFY_LIST_PRIVATE_INCOMING_CHAT : NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL);
|
||||
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -833,6 +901,10 @@ bool p3ChatService::loadList(std::list<RsItem*> load)
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
_own_avatar = new AvatarInfo(ai->image_data,ai->image_size) ;
|
||||
|
||||
delete *it;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
RsChatStatusItem *mitem = NULL ;
|
||||
@ -842,9 +914,38 @@ bool p3ChatService::loadList(std::list<RsItem*> load)
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
_custom_status_string = mitem->status_string ;
|
||||
|
||||
delete *it;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
RsPrivateChatMsgConfigItem *citem = NULL ;
|
||||
|
||||
if(NULL != (citem = dynamic_cast<RsPrivateChatMsgConfigItem *>(*it)))
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
if (citem->chatFlags & RS_CHAT_FLAG_PRIVATE) {
|
||||
RsChatMsgItem *ci = new RsChatMsgItem();
|
||||
citem->get(ci);
|
||||
|
||||
if (citem->configFlags & RS_CHATMSG_CONFIGFLAG_INCOMING) {
|
||||
privateIncomingList.push_back(ci);
|
||||
} else {
|
||||
privateOutgoingList.push_back(ci);
|
||||
}
|
||||
} else {
|
||||
// ignore all other items
|
||||
}
|
||||
|
||||
|
||||
delete *it;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// delete unknown items
|
||||
delete *it;
|
||||
}
|
||||
return true;
|
||||
@ -852,7 +953,10 @@ bool p3ChatService::loadList(std::list<RsItem*> load)
|
||||
|
||||
std::list<RsItem*> p3ChatService::saveList(bool& cleanup)
|
||||
{
|
||||
cleanup = true ;
|
||||
cleanup = true;
|
||||
|
||||
mChatMtx.lock(); /****** MUTEX LOCKED *******/
|
||||
|
||||
/* now we create a pqistore, and stream all the msgs into it */
|
||||
|
||||
std::list<RsItem*> list ;
|
||||
@ -871,9 +975,36 @@ std::list<RsItem*> p3ChatService::saveList(bool& cleanup)
|
||||
|
||||
list.push_back(di) ;
|
||||
|
||||
/* save incoming private chat messages */
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator it;
|
||||
for (it = privateIncomingList.begin(); it != privateIncomingList.end(); it++) {
|
||||
RsPrivateChatMsgConfigItem *ci = new RsPrivateChatMsgConfigItem;
|
||||
|
||||
ci->set(*it, (*it)->PeerId(), RS_CHATMSG_CONFIGFLAG_INCOMING);
|
||||
|
||||
list.push_back(ci);
|
||||
}
|
||||
|
||||
/* save outgoing private chat messages */
|
||||
|
||||
for (it = privateOutgoingList.begin(); it != privateOutgoingList.end(); it++) {
|
||||
RsPrivateChatMsgConfigItem *ci = new RsPrivateChatMsgConfigItem;
|
||||
|
||||
ci->set(*it, (*it)->PeerId(), 0);
|
||||
|
||||
list.push_back(ci);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void p3ChatService::saveDone()
|
||||
{
|
||||
/* unlock mutex */
|
||||
mChatMtx.unlock(); /****** MUTEX UNLOCKED *******/
|
||||
}
|
||||
|
||||
RsSerialiser *p3ChatService::setupSerialiser()
|
||||
{
|
||||
RsSerialiser *rss = new RsSerialiser ;
|
||||
@ -882,5 +1013,46 @@ RsSerialiser *p3ChatService::setupSerialiser()
|
||||
return rss ;
|
||||
}
|
||||
|
||||
/*************** pqiMonitor callback ***********************/
|
||||
|
||||
void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||
{
|
||||
std::list<pqipeer>::const_iterator it;
|
||||
for (it = plist.begin(); it != plist.end(); it++) {
|
||||
if (it->state & RS_PEER_S_FRIEND) {
|
||||
if (it->actions & RS_PEER_CONNECTED) {
|
||||
/* send the saved outgoing messages */
|
||||
bool changed = false;
|
||||
|
||||
if (privateOutgoingList.size()) {
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator cit = privateOutgoingList.begin();
|
||||
while (cit != privateOutgoingList.end()) {
|
||||
RsChatMsgItem *c = *cit;
|
||||
|
||||
if (c->PeerId() == it->id) {
|
||||
sendItem(c); // delete item
|
||||
|
||||
changed = true;
|
||||
|
||||
std::list<RsChatMsgItem *>::iterator cit1 = cit;
|
||||
cit++;
|
||||
privateOutgoingList.erase(cit1);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
cit++;
|
||||
}
|
||||
} /* UNLOCKED */
|
||||
|
||||
if (changed) {
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL);
|
||||
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,12 +42,12 @@
|
||||
* This service uses rsnotify (callbacks librs clients (e.g. rs-gui))
|
||||
* @see NotifyBase
|
||||
*/
|
||||
class p3ChatService: public p3Service, public p3Config
|
||||
class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
{
|
||||
public:
|
||||
p3ChatService(p3ConnectMgr *cm);
|
||||
|
||||
/* overloaded */
|
||||
/***** overloaded from p3Service *****/
|
||||
/*!
|
||||
* This retrieves all chat msg items and also (important!)
|
||||
* processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned
|
||||
@ -58,16 +58,20 @@ class p3ChatService: public p3Service, public p3Config
|
||||
virtual int tick();
|
||||
virtual int status();
|
||||
|
||||
/*************** pqiMonitor callback ***********************/
|
||||
virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
|
||||
/*!
|
||||
* public chat sent to all peers
|
||||
*/
|
||||
int sendPublicChat(std::wstring &msg);
|
||||
|
||||
/********* RsMsgs ***********/
|
||||
/*!
|
||||
* chat is sent to specifc peer
|
||||
* @param id peer to send chat msg to
|
||||
*/
|
||||
int sendPrivateChat(std::string &id, std::wstring &msg);
|
||||
bool 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)
|
||||
@ -115,27 +119,37 @@ class p3ChatService: public p3Service, public p3Config
|
||||
*/
|
||||
void getOwnAvatarJpegData(unsigned char *& data,int& size) ;
|
||||
|
||||
|
||||
/*!
|
||||
* returns the count of messages in public or private queue
|
||||
* returns the count of messages in public queue
|
||||
* @param public or private queue
|
||||
*/
|
||||
int getChatQueueCount(bool privateQueue);
|
||||
int getPublicChatQueueCount();
|
||||
|
||||
/*!
|
||||
* This retrieves all public chat msg items
|
||||
*/
|
||||
bool getPublicChatQueue(std::list<ChatInfo> &chats);
|
||||
|
||||
/*!
|
||||
* returns the count of messages in private queue
|
||||
* @param public or private queue
|
||||
*/
|
||||
int getPrivateChatQueueCount(bool incoming);
|
||||
|
||||
/*!
|
||||
* @param id's of available private chat messages
|
||||
*/
|
||||
bool getPrivateChatQueueIds(std::list<std::string> &ids);
|
||||
bool getPrivateChatQueueIds(bool incoming, std::list<std::string> &ids);
|
||||
|
||||
/*!
|
||||
* This retrieves all private chat msg items for peer
|
||||
*/
|
||||
bool getPrivateChatQueue(std::string id, std::list<ChatInfo> &chats);
|
||||
bool getPrivateChatQueue(bool incoming, const std::string &id, std::list<ChatInfo> &chats);
|
||||
|
||||
/*!
|
||||
* @param clear private chat queue
|
||||
*/
|
||||
bool clearPrivateChatQueue(bool incoming, const std::string &id);
|
||||
|
||||
/************* from p3Config *******************/
|
||||
virtual RsSerialiser *setupSerialiser() ;
|
||||
@ -144,6 +158,7 @@ class p3ChatService: public p3Service, public p3Config
|
||||
* chat msg items and custom status are saved
|
||||
*/
|
||||
virtual std::list<RsItem*> saveList(bool& cleanup) ;
|
||||
virtual void saveDone();
|
||||
virtual bool loadList(std::list<RsItem*> load) ;
|
||||
|
||||
private:
|
||||
@ -180,7 +195,8 @@ class p3ChatService: public p3Service, public p3Config
|
||||
p3ConnectMgr *mConnMgr;
|
||||
|
||||
std::list<RsChatMsgItem *> publicList;
|
||||
std::list<RsChatMsgItem *> privateList;
|
||||
std::list<RsChatMsgItem *> privateIncomingList;
|
||||
std::list<RsChatMsgItem *> privateOutgoingList;
|
||||
|
||||
AvatarInfo *_own_avatar ;
|
||||
std::map<std::string,AvatarInfo *> _avatars ;
|
||||
|
@ -308,6 +308,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags flags)
|
||||
/* call once */
|
||||
updateMessages();
|
||||
updateForums();
|
||||
privateChatChanged(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD);
|
||||
|
||||
idle = new Idle();
|
||||
idle->start();
|
||||
@ -511,18 +512,20 @@ void MainWindow::updateStatus()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::privateChatChanged(int type)
|
||||
void MainWindow::privateChatChanged(int list, int type)
|
||||
{
|
||||
/* first process the chat messages */
|
||||
PopupChatDialog::privateChatChanged();
|
||||
PopupChatDialog::privateChatChanged(list, type);
|
||||
|
||||
/* than count the chat messages */
|
||||
int chatCount = rsMsgs->getChatQueueCount(true);
|
||||
if (list == NOTIFY_LIST_PRIVATE_INCOMING_CHAT) {
|
||||
/* than count the chat messages */
|
||||
int chatCount = rsMsgs->getPrivateChatQueueCount(true);
|
||||
|
||||
if (chatCount) {
|
||||
trayIconChat->show();
|
||||
} else {
|
||||
trayIconChat->hide();
|
||||
if (chatCount) {
|
||||
trayIconChat->show();
|
||||
} else {
|
||||
trayIconChat->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -833,7 +836,7 @@ 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()) {
|
||||
if (rsMsgs->getPrivateChatQueueIds(true, ids) && ids.size()) {
|
||||
pcd = PopupChatDialog::getPrivateChat(ids.front(), RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS);
|
||||
}
|
||||
|
||||
|
@ -141,7 +141,7 @@ public slots:
|
||||
void checkAndSetIdle(int idleTime);
|
||||
void updateMessages();
|
||||
void updateForums();
|
||||
void privateChatChanged(int type);
|
||||
void privateChatChanged(int list, int type);
|
||||
|
||||
protected:
|
||||
/** Default Constructor */
|
||||
|
@ -439,7 +439,7 @@ void MessengerWindow::insertPeers()
|
||||
|
||||
std::list<std::string> privateChatIds;
|
||||
#ifndef MINIMAL_RSGUI
|
||||
rsMsgs->getPrivateChatQueueIds(privateChatIds);
|
||||
rsMsgs->getPrivateChatQueueIds(true, privateChatIds);
|
||||
#endif // MINIMAL_RSGUI
|
||||
|
||||
rsPeers->getGPGAcceptedList(gpgFriends);
|
||||
|
@ -474,7 +474,7 @@ void PeersDialog::insertPeers()
|
||||
bool bHideUnconnected = ui.action_Hide_Offline_Friends->isChecked();
|
||||
|
||||
std::list<std::string> privateChatIds;
|
||||
rsMsgs->getPrivateChatQueueIds(privateChatIds);
|
||||
rsMsgs->getPrivateChatQueueIds(true, privateChatIds);
|
||||
|
||||
rsPeers->getGPGAcceptedList(gpgFriends);
|
||||
|
||||
|
@ -127,8 +127,10 @@ PopupChatDialog::PopupChatDialog(std::string id, std::string name,
|
||||
connect(ui.colorButton, SIGNAL(clicked()), this, SLOT(setColor()));
|
||||
connect(ui.emoteiconButton, SIGNAL(clicked()), this, SLOT(smileyWidget()));
|
||||
connect(ui.actionSave_Chat_History, SIGNAL(triggered()), this, SLOT(fileSaveAs()));
|
||||
connect(ui.actionClearOfflineMessages, SIGNAL(triggered()), this, SLOT(clearOfflineMessages()));
|
||||
|
||||
connect(ui.textBrowser, SIGNAL(anchorClicked(const QUrl &)), SLOT(anchorClicked(const QUrl &)));
|
||||
connect(ui.offlineTextBrowser, SIGNAL(anchorClicked(const QUrl &)), SLOT(anchorClicked(const QUrl &)));
|
||||
|
||||
connect(NotifyQt::getInstance(), SIGNAL(peerStatusChanged(const QString&, int)), this, SLOT(updateStatus(const QString&, int)));
|
||||
connect(NotifyQt::getInstance(), SIGNAL(peerHasNewCustomStateString(const QString&, const QString&)), this, SLOT(updatePeersCustomStateString(const QString&, const QString&)));
|
||||
@ -164,6 +166,7 @@ PopupChatDialog::PopupChatDialog(std::string id, std::string name,
|
||||
QMenu * toolmenu = new QMenu();
|
||||
toolmenu->addAction(ui.actionClear_Chat);
|
||||
toolmenu->addAction(ui.actionSave_Chat_History);
|
||||
toolmenu->addAction(ui.actionClearOfflineMessages);
|
||||
//toolmenu->addAction(ui.action_Disable_Emoticons);
|
||||
ui.pushtoolsButton->setMenu(toolmenu);
|
||||
|
||||
@ -198,6 +201,9 @@ PopupChatDialog::PopupChatDialog(std::string id, std::string name,
|
||||
updatePeersCustomStateString(QString::fromStdString(dialogId), customStateString);
|
||||
|
||||
ui.chattextEdit->installEventFilter(this);
|
||||
|
||||
// call once
|
||||
onPrivateChatChanged(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_ADD);
|
||||
}
|
||||
|
||||
/** Destructor. */
|
||||
@ -321,24 +327,29 @@ void PopupChatDialog::processSettings(bool bLoad)
|
||||
chatDialogs.clear();
|
||||
}
|
||||
|
||||
/*static*/ void PopupChatDialog::privateChatChanged()
|
||||
/*static*/ void PopupChatDialog::privateChatChanged(int list, int type)
|
||||
{
|
||||
std::list<std::string> ids;
|
||||
if (!rsMsgs->getPrivateChatQueueIds(ids)) {
|
||||
#ifdef PEERS_DEBUG
|
||||
std::cerr << "no chat available." << std::endl ;
|
||||
#endif
|
||||
return;
|
||||
if (list == NOTIFY_LIST_PRIVATE_INCOMING_CHAT && type == NOTIFY_TYPE_ADD) {
|
||||
std::list<std::string> ids;
|
||||
if (rsMsgs->getPrivateChatQueueIds(true, ids)) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
/* now notify all open priavate chat windows */
|
||||
std::map<std::string, PopupChatDialog *>::iterator it;
|
||||
for (it = chatDialogs.begin (); it != chatDialogs.end(); it++) {
|
||||
if (it->second) {
|
||||
it->second->onPrivateChatChanged(list, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -349,37 +360,45 @@ void PopupChatDialog::chatFriend(std::string id)
|
||||
return;
|
||||
}
|
||||
std::cerr<<" popup dialog chat friend 1"<<std::endl;
|
||||
bool oneLocationConnected = false;
|
||||
|
||||
RsPeerDetails detail;
|
||||
if (!rsPeers->getPeerDetails(id, detail)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::string firstId;
|
||||
|
||||
if (detail.isOnlyGPGdetail) {
|
||||
//let's get the ssl child details, and open all the chat boxes
|
||||
std::list<std::string> sslIds;
|
||||
rsPeers->getSSLChildListOfGPGId(detail.gpg_id, sslIds);
|
||||
for (std::list<std::string>::iterator it = sslIds.begin(); it != sslIds.end(); it++) {
|
||||
if (firstId.empty()) {
|
||||
firstId = *it;
|
||||
}
|
||||
|
||||
RsPeerDetails sslDetails;
|
||||
if (rsPeers->getPeerDetails(*it, sslDetails)) {
|
||||
if (sslDetails.state & RS_PEER_STATE_CONNECTED) {
|
||||
oneLocationConnected = true;
|
||||
getPrivateChat(*it, RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (detail.state & RS_PEER_STATE_CONNECTED) {
|
||||
oneLocationConnected = true;
|
||||
getPrivateChat(id, RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS);
|
||||
return;
|
||||
}
|
||||
firstId = id;
|
||||
}
|
||||
|
||||
if (!oneLocationConnected) {
|
||||
/* info dialog */
|
||||
if ((QMessageBox::question(NULL, tr("Friend not Online"),tr("Your Friend is offline \nDo you want to send them a Message instead"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes) {
|
||||
MessageComposer::msgFriend(id);
|
||||
/* info dialog */
|
||||
if ((QMessageBox::question(NULL, tr("Friend not Online"),tr("Your Friend is offline \nDo you want to send them a Message instead"),QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes))== QMessageBox::Yes) {
|
||||
MessageComposer::msgFriend(id);
|
||||
} else {
|
||||
if (firstId.empty() == false) {
|
||||
getPrivateChat(firstId, RS_CHAT_OPEN_NEW | RS_CHAT_REOPEN | RS_CHAT_FOCUS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -505,6 +524,32 @@ void PopupChatDialog::updateChat()
|
||||
|
||||
}
|
||||
|
||||
void PopupChatDialog::onPrivateChatChanged(int list, int type)
|
||||
{
|
||||
if (list == NOTIFY_LIST_PRIVATE_OUTGOING_CHAT && type) {
|
||||
std::list<ChatInfo> offlineChat;
|
||||
if (rsMsgs->getPrivateChatQueueCount(false) && rsMsgs->getPrivateChatQueue(false, dialogId, offlineChat)) {
|
||||
ui.actionClearOfflineMessages->setEnabled(true);
|
||||
ui.offlineTextBrowser->setVisible(true);
|
||||
|
||||
std::list<ChatInfo>::iterator it;
|
||||
for(it = offlineChat.begin(); it != offlineChat.end(); it++) {
|
||||
/* are they public? */
|
||||
if ((it->chatflags & RS_CHAT_PRIVATE) == 0) {
|
||||
/* this should not happen */
|
||||
continue;
|
||||
}
|
||||
|
||||
addChatMsg(it->rsid, it->sendTime, it->msg, true);
|
||||
}
|
||||
} else {
|
||||
ui.actionClearOfflineMessages->setEnabled(false);
|
||||
ui.offlineTextBrowser->setVisible(false);
|
||||
ui.offlineTextBrowser->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PopupChatDialog::insertChatMsgs()
|
||||
{
|
||||
if (isVisible() == false) {
|
||||
@ -515,7 +560,7 @@ void PopupChatDialog::insertChatMsgs()
|
||||
m_bInsertOnVisible = false;
|
||||
|
||||
std::list<ChatInfo> newchat;
|
||||
if (!rsMsgs->getPrivateChatQueue(dialogId, newchat))
|
||||
if (!rsMsgs->getPrivateChatQueue(true, dialogId, newchat))
|
||||
{
|
||||
#ifdef PEERS_DEBUG
|
||||
std::cerr << "no chat for " << dialogId << " available." << std::endl ;
|
||||
@ -531,17 +576,21 @@ void PopupChatDialog::insertChatMsgs()
|
||||
continue;
|
||||
}
|
||||
|
||||
addChatMsg(it->rsid, it->sendTime, it->msg);
|
||||
addChatMsg(it->rsid, it->sendTime, it->msg, false);
|
||||
}
|
||||
|
||||
rsMsgs->clearPrivateChatQueue(true, dialogId);
|
||||
|
||||
playsound();
|
||||
QApplication::alert(this);
|
||||
}
|
||||
|
||||
void PopupChatDialog::addChatMsg(std::string &id, uint sendTime, std::wstring &msg)
|
||||
void PopupChatDialog::addChatMsg(std::string &id, uint sendTime, std::wstring &msg, bool offline)
|
||||
{
|
||||
std::string ownId = rsPeers->getOwnId();
|
||||
|
||||
QDateTime timestamp = QDateTime::fromTime_t(sendTime);
|
||||
QString name = QString::fromStdString(rsPeers->getPeerName(id));
|
||||
QString name = QString::fromStdString(rsPeers->getPeerName(offline ? ownId : id));
|
||||
QString message = QString::fromStdWString(msg);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
@ -555,10 +604,14 @@ void PopupChatDialog::addChatMsg(std::string &id, uint sendTime, std::wstring &m
|
||||
formatFlag |= CHAT_FORMATMSG_EMBED_SMILEYS;
|
||||
}
|
||||
|
||||
ChatStyle::enumFormatMessage type = (id == rsPeers->getOwnId()) ? ChatStyle::FORMATMSG_INCOMING : ChatStyle::FORMATMSG_OUTGOING;
|
||||
ChatStyle::enumFormatMessage type = (offline == false && id == ownId) ? ChatStyle::FORMATMSG_INCOMING : ChatStyle::FORMATMSG_OUTGOING;
|
||||
|
||||
QString formatMsg = style.formatMessage(type, name, timestamp, message, formatFlag);
|
||||
|
||||
if (offline) {
|
||||
ui.offlineTextBrowser->append(formatMsg);
|
||||
}
|
||||
|
||||
ui.textBrowser->append(formatMsg);
|
||||
|
||||
resetStatusBar() ;
|
||||
@ -627,9 +680,10 @@ void PopupChatDialog::sendChat()
|
||||
std::cout << "PopupChatDialog:sendChat " << std::endl;
|
||||
#endif
|
||||
|
||||
addChatMsg(ownId, time(NULL), msg);
|
||||
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
|
||||
addChatMsg(ownId, time(NULL), msg, false);
|
||||
}
|
||||
|
||||
rsMsgs->sendPrivateChat(dialogId, msg);
|
||||
chatWidget->clear();
|
||||
setFont();
|
||||
|
||||
@ -928,9 +982,9 @@ void PopupChatDialog::fileHashingFinished(AttachFileItem* file)
|
||||
|
||||
std::wstring msg = message.toStdWString();
|
||||
|
||||
addChatMsg(ownId, time(NULL), msg);
|
||||
|
||||
rsMsgs->sendPrivateChat(dialogId, msg);
|
||||
if (rsMsgs->sendPrivateChat(dialogId, msg)) {
|
||||
addChatMsg(ownId, time(NULL), msg, false);
|
||||
}
|
||||
}
|
||||
|
||||
void PopupChatDialog::anchorClicked (const QUrl& link )
|
||||
@ -1062,6 +1116,11 @@ void PopupChatDialog::setCurrentFileName(const QString &fileName)
|
||||
setWindowModified(false);
|
||||
}
|
||||
|
||||
void PopupChatDialog::clearOfflineMessages()
|
||||
{
|
||||
rsMsgs->clearPrivateChatQueue(false, dialogId);
|
||||
}
|
||||
|
||||
void PopupChatDialog::updateStatus(const QString &peer_id, int status)
|
||||
{
|
||||
std::string stdPeerId = peer_id.toStdString();
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
static void cleanupChat();
|
||||
static void chatFriend(std::string id);
|
||||
static void updateAllAvatars();
|
||||
static void privateChatChanged();
|
||||
static void privateChatChanged(int list, int type);
|
||||
|
||||
void updateChat();
|
||||
void updatePeerAvatar(const std::string&);
|
||||
@ -83,7 +83,7 @@ protected:
|
||||
bool eventFilter(QObject *obj, QEvent *ev);
|
||||
|
||||
void insertChatMsgs();
|
||||
void addChatMsg(std::string &id, uint sendTime, std::wstring &msg);
|
||||
void addChatMsg(std::string &id, uint sendTime, std::wstring &msg, bool offline);
|
||||
|
||||
void updateAvatar();
|
||||
|
||||
@ -108,16 +108,20 @@ private slots:
|
||||
|
||||
bool fileSave();
|
||||
bool fileSaveAs();
|
||||
void setCurrentFileName(const QString &fileName);
|
||||
void clearOfflineMessages();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void setCurrentFileName(const QString &fileName);
|
||||
|
||||
void colorChanged(const QColor &c);
|
||||
void fontChanged(const QFont &font);
|
||||
void addAttachment(std::string,int flag);
|
||||
void processSettings(bool bLoad);
|
||||
|
||||
void onPrivateChatChanged(int list, int type);
|
||||
|
||||
QAction *actionTextBold;
|
||||
QAction *actionTextUnderline;
|
||||
QAction *actionTextItalic;
|
||||
|
@ -38,7 +38,7 @@ stop:0 #F6FCFF, stop:1 #F6FCFF);}</string>
|
||||
<property name="verticalSpacing">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item row="0" column="0" rowspan="4">
|
||||
<item row="0" column="0" rowspan="6">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
@ -109,7 +109,7 @@ stop:0 #F6FCFF, stop:1 #F6FCFF);}</string>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="4">
|
||||
<item row="0" column="1" rowspan="6">
|
||||
<widget class="QFrame" name="avatarframe">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
@ -355,121 +355,7 @@ border-image: url(:/images/closepressed.png)
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QSplitter" name="chatsplitter">
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="handleWidth">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QTextBrowser" name="textBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="sizeIncrement">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QTextBrowser{border: 1px solid #B8B6B1;
|
||||
border-radius: 6px;
|
||||
background: white;}</string>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="chattextEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QTextEdit{border: 1px solid #B8B6B1;
|
||||
border-radius: 6px;
|
||||
background: white;}</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="typingpixmapLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>18</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>18</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">T</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<item row="5" column="2">
|
||||
<widget class="QFrame" name="Chatbuttonframe">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
@ -823,9 +709,150 @@ border: 1px solid #CCCCCC;
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="3">
|
||||
<item row="6" column="0" colspan="3">
|
||||
<layout class="QVBoxLayout" name="vboxLayout"/>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QSplitter" name="chatsplitter">
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="handleWidth">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="verticalLayoutWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="textBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QTextBrowser{border: 1px solid #B8B6B1;
|
||||
border-radius: 6px;
|
||||
background: white;}</string>
|
||||
</property>
|
||||
<property name="html">
|
||||
<string notr="true"><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;"></p></body></html></string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="offlineTextBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QTextBrowser{border: 1px solid #B8B6B1;
|
||||
border-radius: 6px;
|
||||
background: white;}</string>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openLinks">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="layoutWidget">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="statusLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="indent">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QTextEdit" name="chattextEdit">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>30</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QTextEdit{border: 1px solid #B8B6B1;
|
||||
border-radius: 6px;
|
||||
background: white;}</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="typingpixmapLabel">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>18</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>18</width>
|
||||
<height>18</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">T</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
@ -916,6 +943,11 @@ border: 1px solid #CCCCCC;
|
||||
<string>Save Chat History</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionClearOfflineMessages">
|
||||
<property name="text">
|
||||
<string>Clear offline messages</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../images.qrc"/>
|
||||
|
@ -232,11 +232,12 @@ void NotifyQt::notifyListChange(int list, int type)
|
||||
#endif
|
||||
emit publicChatChanged(type);
|
||||
break;
|
||||
case NOTIFY_LIST_PRIVATE_CHAT:
|
||||
case NOTIFY_LIST_PRIVATE_INCOMING_CHAT:
|
||||
case NOTIFY_LIST_PRIVATE_OUTGOING_CHAT:
|
||||
#ifdef NOTIFY_DEBUG
|
||||
std::cerr << "received private chat changed" << std::endl ;
|
||||
#endif
|
||||
emit privateChatChanged(type);
|
||||
emit privateChatChanged(list, type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -76,7 +76,7 @@ class NotifyQt: public QObject, public NotifyBase
|
||||
void peerStatusChanged(const QString& /* peer_id */, int /* status */);
|
||||
void peerStatusChangedSummary() const;
|
||||
void publicChatChanged(int type) const ;
|
||||
void privateChatChanged(int type) const ;
|
||||
void privateChatChanged(int list, int type) const ;
|
||||
|
||||
/* Notify from GUI */
|
||||
void chatStyleChanged(int /*ChatStyle::enumStyleType*/ styleType);
|
||||
|
@ -189,7 +189,7 @@ int main(int argc, char *argv[])
|
||||
QObject::connect(notify,SIGNAL(transfersChanged()) ,w->transfersDialog ,SLOT(insertTransfers() )) ;
|
||||
QObject::connect(notify,SIGNAL(friendsChanged()) ,w->peersDialog ,SLOT(insertPeers() )) ;
|
||||
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(privateChatChanged(int, int)) ,w ,SLOT(privateChatChanged(int, int) ));
|
||||
QObject::connect(notify,SIGNAL(neighborsChanged()) ,w->networkDialog ,SLOT(insertConnect() )) ;
|
||||
QObject::connect(notify,SIGNAL(messagesChanged()) ,w->messagesDialog ,SLOT(insertMessages() )) ;
|
||||
QObject::connect(notify,SIGNAL(messagesTagsChanged()) ,w->messagesDialog ,SLOT(messagesTagsChanged() )) ;
|
||||
|
Loading…
Reference in New Issue
Block a user