Moved the tag feature in messages from the gui to the libretroshare.

Changed rsmsg interface and item classes so need full recompile.
Created new notifier for tag changes - NOTIFY_LIST_MESSAGE_TAGS.
Changed serialiser tests for message items.

After that all tags are reset to standard and all assigned tags to messages are lost.
Please delete the file msg_locale.cfg in your profile directory.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3381 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2010-08-22 22:12:26 +00:00
parent 340982b996
commit 52183a0c75
18 changed files with 708 additions and 515 deletions

View File

@ -216,16 +216,17 @@ class NotifyBase
virtual std::string askForPassword(const std::string& /* key_details */ ,bool /* prev_is_bad */ ) { return "" ;} virtual std::string askForPassword(const std::string& /* key_details */ ,bool /* prev_is_bad */ ) { return "" ;}
}; };
const int NOTIFY_LIST_NEIGHBOURS = 1; const int NOTIFY_LIST_NEIGHBOURS = 1;
const int NOTIFY_LIST_FRIENDS = 2; const int NOTIFY_LIST_FRIENDS = 2;
const int NOTIFY_LIST_SEARCHLIST = 4; const int NOTIFY_LIST_SEARCHLIST = 4;
const int NOTIFY_LIST_MESSAGELIST = 5; const int NOTIFY_LIST_MESSAGELIST = 5;
const int NOTIFY_LIST_CHANNELLIST = 6; const int NOTIFY_LIST_CHANNELLIST = 6;
const int NOTIFY_LIST_TRANSFERLIST = 7; const int NOTIFY_LIST_TRANSFERLIST = 7;
const int NOTIFY_LIST_CONFIG = 8; const int NOTIFY_LIST_CONFIG = 8;
const int NOTIFY_LIST_DIRLIST_LOCAL = 9; 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_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

@ -37,18 +37,26 @@
#define RS_MSG_BOXMASK 0x000f /* Mask for determining Box */ #define RS_MSG_BOXMASK 0x000f /* Mask for determining Box */
#define RS_MSG_OUTGOING 0x0001 /* !Inbox */ #define RS_MSG_OUTGOING 0x0001 /* !Inbox */
#define RS_MSG_PENDING 0x0002 /* OutBox */ #define RS_MSG_PENDING 0x0002 /* OutBox */
#define RS_MSG_DRAFT 0x0004 /* Draft */ #define RS_MSG_DRAFT 0x0004 /* Draft */
/* ORs of above */ /* ORs of above */
#define RS_MSG_INBOX 0x00 /* Inbox */ #define RS_MSG_INBOX 0x00 /* Inbox */
#define RS_MSG_SENTBOX 0x01 /* Sentbox */ #define RS_MSG_SENTBOX 0x01 /* Sentbox */
#define RS_MSG_OUTBOX 0x03 /* Outbox */ #define RS_MSG_OUTBOX 0x03 /* Outbox */
#define RS_MSG_DRAFTBOX 0x05 /* Draftbox */ #define RS_MSG_DRAFTBOX 0x05 /* Draftbox */
#define RS_MSG_NEW 0x0010 /* New */ #define RS_MSG_NEW 0x0010 /* New */
#define RS_MSG_TRASH 0x0020 /* Trash */ #define RS_MSG_TRASH 0x0020 /* Trash */
#define RS_MSG_UNREAD_BY_USER 0x0040 /* Unread by user */
#define RS_MSGTAGTYPE_IMPORTANT 1
#define RS_MSGTAGTYPE_WORK 2
#define RS_MSGTAGTYPE_PERSONAL 3
#define RS_MSGTAGTYPE_TODO 4
#define RS_MSGTAGTYPE_LATER 5
#define RS_MSGTAGTYPE_USER 100
class MessageInfo class MessageInfo
{ {
@ -96,8 +104,8 @@ class MsgTagInfo
public: public:
MsgTagInfo() {} MsgTagInfo() {}
uint32_t tagId;
std::string msgId; std::string msgId;
std::list<uint32_t> tagIds;
}; };
class MsgTagType class MsgTagType
@ -105,7 +113,7 @@ class MsgTagType
public: public:
MsgTagType() {} MsgTagType() {}
/* map containing tagid-> pair (text, rgb color) */ /* map containing tagId -> pair (text, rgb color) */
std::map<uint32_t, std::pair<std::string, uint32_t> > types; std::map<uint32_t, std::pair<std::string, uint32_t> > types;
}; };
@ -151,15 +159,19 @@ virtual bool MessageToDraft(MessageInfo &info) = 0;
virtual bool MessageToTrash(std::string mid, bool bTrash) = 0; virtual bool MessageToTrash(std::string mid, bool bTrash) = 0;
virtual bool MessageDelete(std::string mid) = 0; virtual bool MessageDelete(std::string mid) = 0;
virtual bool MessageRead(std::string mid) = 0; virtual bool MessageRead(std::string mid, bool bUnreadByUser) = 0;
/* message tagging */ /* message tagging */
virtual bool MessageGetTagTypes(MsgTagType& tags) = 0; virtual bool getMessageTagTypes(MsgTagType& tags) = 0;
virtual bool MessageGetMsgTag(std::string msgId, MsgTagInfo& info) = 0; /* set == false && tagId == 0 --> remove all */
virtual bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color) = 0;
virtual bool removeMessageTagType(uint32_t tagId) = 0;
virtual bool MessageSetTagType(std::string& text, uint32_t tag_id, uint32_t rgb_color) = 0; virtual bool getMessageTag(std::string msgId, MsgTagInfo& info) = 0;
virtual bool MessageSetMsgTag(MsgTagInfo& ) = 0; virtual bool setMessageTag(std::string msgId, uint32_t tagId, bool set) = 0;
virtual bool resetMessageStandardTagTypes(MsgTagType& tags) = 0;
/****************************************/ /****************************************/
/* Chat */ /* Chat */

View File

@ -92,39 +92,45 @@ bool p3Msgs::MessageDelete(std::string mid)
//std::cerr << "p3Msgs::MessageDelete() "; //std::cerr << "p3Msgs::MessageDelete() ";
//std::cerr << "mid: " << mid << std::endl; //std::cerr << "mid: " << mid << std::endl;
mMsgSrv -> removeMsgId(mid); return mMsgSrv -> removeMsgId(mid);
return 1;
} }
bool p3Msgs::MessageRead(std::string mid) bool p3Msgs::MessageRead(std::string mid, bool bUnreadByUser)
{ {
//std::cerr << "p3Msgs::MessageRead() "; //std::cerr << "p3Msgs::MessageRead() ";
//std::cerr << "mid: " << mid << std::endl; //std::cerr << "mid: " << mid << std::endl;
mMsgSrv -> markMsgIdRead(mid); return mMsgSrv -> markMsgIdRead(mid, bUnreadByUser);
return 1;
} }
bool p3Msgs::MessageGetTagTypes(MsgTagType& tags) bool p3Msgs::getMessageTagTypes(MsgTagType& tags)
{ {
mMsgSrv->MessageGetTagTypes(tags); return mMsgSrv->getMessageTagTypes(tags);
} }
bool p3Msgs::MessageGetMsgTag(std::string msgId, MsgTagInfo& info) bool p3Msgs::setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color)
{ {
mMsgSrv->MessageGetMsgTag(msgId, info); return mMsgSrv->setMessageTagType(tagId, text, rgb_color);
} }
bool p3Msgs::MessageSetTagType(std::string& text, uint32_t tag_id, uint32_t rgb_color) bool p3Msgs::removeMessageTagType(uint32_t tagId)
{ {
mMsgSrv->MessageSetTagType(text, tag_id, rgb_color); return mMsgSrv->removeMessageTagType(tagId);
} }
bool p3Msgs::MessageSetMsgTag(MsgTagInfo& tagInfo) bool p3Msgs::getMessageTag(std::string msgId, MsgTagInfo& info)
{ {
mMsgSrv->MessageSetMsgTag(tagInfo); return mMsgSrv->getMessageTag(msgId, info);
}
bool p3Msgs::setMessageTag(std::string msgId, uint32_t tagId, bool set)
{
return mMsgSrv->setMessageTag(msgId, tagId, set);
}
bool p3Msgs::resetMessageStandardTagTypes(MsgTagType& tags)
{
return mMsgSrv->resetMessageStandardTagTypes(tags);
} }
/****************************************/ /****************************************/

View File

@ -61,13 +61,17 @@ class p3Msgs: public RsMsgs
virtual bool MessageToDraft(MessageInfo &info); virtual bool MessageToDraft(MessageInfo &info);
virtual bool MessageToTrash(std::string mid, bool bTrash); virtual bool MessageToTrash(std::string mid, bool bTrash);
virtual bool MessageDelete(std::string mid); virtual bool MessageDelete(std::string mid);
virtual bool MessageRead(std::string mid); virtual bool MessageRead(std::string mid, bool bUnreadByUser);
virtual bool MessageGetTagTypes(MsgTagType& tags); virtual bool getMessageTagTypes(MsgTagType& tags);
virtual bool MessageGetMsgTag(std::string msgId, MsgTagInfo& info); virtual bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color);
virtual bool removeMessageTagType(uint32_t tagId);
virtual bool MessageSetTagType(std::string& text, uint32_t tag_id, uint32_t rgb_color); virtual bool getMessageTag(std::string msgId, MsgTagInfo& info);
virtual bool MessageSetMsgTag(MsgTagInfo& ); /* set == false && tagId == 0 --> remove all */
virtual bool setMessageTag(std::string msgId, uint32_t tagId, bool set);
virtual bool resetMessageStandardTagTypes(MsgTagType& tags);
/*! /*!
* gets avatar from peer, image data in jpeg format * gets avatar from peer, image data in jpeg format

View File

@ -422,8 +422,8 @@ void RsMsgTagType::clear()
void RsMsgTags::clear() void RsMsgTags::clear()
{ {
msgId.clear(); msgId = 0;
tagId = 0; tagIds.clear();
} }
std::ostream& RsMsgTagType::print(std::ostream &out, uint16_t indent) std::ostream& RsMsgTagType::print(std::ostream &out, uint16_t indent)
@ -698,8 +698,8 @@ uint32_t RsMsgSerialiser::sizeMsgTagItem(RsMsgTags* item)
{ {
uint32_t s = 8; /* header */ uint32_t s = 8; /* header */
s += GetTlvStringSize(item->msgId); s += 4; /* msgId */
s += 4; /* tag id */ s += item->tagIds.size() * 4; /* tagIds */
return s; return s;
} }
@ -726,8 +726,13 @@ bool RsMsgSerialiser::serialiseMsgTagItem(RsMsgTags *item, void *data, uint32_t*
/* skip the header */ /* skip the header */
offset += 8; offset += 8;
ok &= SetTlvString(data,tlvsize,&offset, TLV_TYPE_STR_MSGID, item->msgId); ok &= setRawUInt32(data,tlvsize,&offset, item->msgId);
ok &= setRawUInt32(data, tlvsize, &offset, item->tagId);
std::list<uint32_t>::iterator mit = item->tagIds.begin();
for(;mit != item->tagIds.end(); mit++)
{
ok &= setRawUInt32(data, tlvsize, &offset, *mit);
}
if (offset != tlvsize) if (offset != tlvsize)
{ {
@ -773,8 +778,17 @@ RsMsgTags* RsMsgSerialiser::deserialiseMsgTagItem(void* data, uint32_t* pktsize)
/* get mandatory parts first */ /* get mandatory parts first */
ok &= GetTlvString(data,rssize,&offset,TLV_TYPE_STR_MSGID,item->msgId); ok &= getRawUInt32(data, rssize, &offset, &item->msgId);
ok &= getRawUInt32(data, rssize, &offset, &(item->tagId));
uint32_t tagId;
while (offset != rssize)
{
tagId = 0;
ok &= getRawUInt32(data, rssize, &offset, &tagId);
item->tagIds.push_back(tagId);
}
if (offset != rssize) if (offset != rssize)
{ {

View File

@ -144,11 +144,12 @@ class RsChatSerialiser: public RsSerialType
/**************************************************************************/ /**************************************************************************/
const uint32_t RS_MSG_FLAGS_OUTGOING = 0x0001; const uint32_t RS_MSG_FLAGS_OUTGOING = 0x0001;
const uint32_t RS_MSG_FLAGS_PENDING = 0x0002; const uint32_t RS_MSG_FLAGS_PENDING = 0x0002;
const uint32_t RS_MSG_FLAGS_DRAFT = 0x0004; const uint32_t RS_MSG_FLAGS_DRAFT = 0x0004;
const uint32_t RS_MSG_FLAGS_NEW = 0x0010; const uint32_t RS_MSG_FLAGS_NEW = 0x0010;
const uint32_t RS_MSG_FLAGS_TRASH = 0x0020; const uint32_t RS_MSG_FLAGS_TRASH = 0x0020;
const uint32_t RS_MSG_FLAGS_UNREAD_BY_USER = 0x0040;
class RsMsgItem: public RsItem class RsMsgItem: public RsItem
{ {
@ -216,8 +217,8 @@ public:
virtual ~RsMsgTags(); virtual ~RsMsgTags();
virtual void clear(); virtual void clear();
std::string msgId; uint32_t msgId;
uint32_t tagId; std::list<uint32_t> tagIds;
}; };
class RsMsgSerialiser: public RsSerialType class RsMsgSerialiser: public RsSerialType

View File

@ -300,7 +300,7 @@ bool p3MsgService::saveConfiguration()
written = written && pa_out -> SendItem(mit->second) ; written = written && pa_out -> SendItem(mit->second) ;
std::map<uint32_t, RsMsgTagType* >::iterator mit2; std::map<uint32_t, RsMsgTagType* >::iterator mit2;
std::map<std::string, RsMsgTags* >::iterator mit3; std::map<uint32_t, RsMsgTags* >::iterator mit3;
for(mit2 = mTags.begin(); mit2 != mTags.end(); mit2++) for(mit2 = mTags.begin(); mit2 != mTags.end(); mit2++)
@ -324,6 +324,47 @@ bool p3MsgService::saveConfiguration()
return true; return true;
} }
// build list of standard tag types
static void getStandardTagTypes(MsgTagType &tags)
{
/* create standard tag types, the text must be translated in the GUI */
tags.types [RS_MSGTAGTYPE_IMPORTANT] = std::pair<std::string, uint32_t> ("Important", 0xFF0000);
tags.types [RS_MSGTAGTYPE_WORK] = std::pair<std::string, uint32_t> ("Work", 0xFF9900);
tags.types [RS_MSGTAGTYPE_PERSONAL] = std::pair<std::string, uint32_t> ("Personal", 0x009900);
tags.types [RS_MSGTAGTYPE_TODO] = std::pair<std::string, uint32_t> ("Todo", 0x3333FF);
tags.types [RS_MSGTAGTYPE_LATER] = std::pair<std::string, uint32_t> ("Later", 0x993399);
}
// Initialize the standard tag types after load
void p3MsgService::initStandardTagTypes()
{
bool bChanged = false;
std::string ownId = mConnMgr->getOwnId();
MsgTagType tags;
getStandardTagTypes(tags);
std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator tit;
for (tit = tags.types.begin(); tit != tags.types.end(); tit++) {
std::map<uint32_t, RsMsgTagType*>::iterator mit = mTags.find(tit->first);
if (mit == mTags.end()) {
RsMsgTagType* tagType = new RsMsgTagType();
tagType->PeerId (ownId);
tagType->tagId = tit->first;
tagType->text = tit->second.first;
tagType->rgb_color = tit->second.second;
mTags.insert(std::pair<uint32_t, RsMsgTagType*>(tit->first, tagType));
bChanged = true;
}
}
if (bChanged) {
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
}
bool p3MsgService::loadConfiguration(std::string &loadHash) bool p3MsgService::loadConfiguration(std::string &loadHash)
{ {
std::string msgfile = Filename(); std::string msgfile = Filename();
@ -360,7 +401,7 @@ bool p3MsgService::loadConfiguration(std::string &loadHash)
} }
else if(NULL != (mti = dynamic_cast<RsMsgTags *>(item))) else if(NULL != (mti = dynamic_cast<RsMsgTags *>(item)))
{ {
mMsgTags.insert(std::pair<std::string, RsMsgTags* >(mti->msgId, mti)); mMsgTags.insert(std::pair<uint32_t, RsMsgTags* >(mti->msgId, mti));
} }
else else
{ {
@ -437,6 +478,9 @@ bool p3MsgService::loadConfiguration(std::string &loadHash)
setHash(hashin); setHash(hashin);
/* Initialize standard tag types */
initStandardTagTypes();
return true; return true;
} }
@ -507,7 +551,7 @@ bool p3MsgService::getMessageSummaries(std::list<MsgInfoSummary> &msgList)
} }
bool p3MsgService::getMessage(std::string mId, MessageInfo &msg) bool p3MsgService::getMessage(std::string &mId, MessageInfo &msg)
{ {
std::map<uint32_t, RsMsgItem *>::iterator mit; std::map<uint32_t, RsMsgItem *>::iterator mit;
uint32_t msgId = atoi(mId.c_str()); uint32_t msgId = atoi(mId.c_str());
@ -574,11 +618,16 @@ void p3MsgService::getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxN
} }
/* remove based on the unique mid (stored in sid) */ /* remove based on the unique mid (stored in sid) */
bool p3MsgService::removeMsgId(std::string mid) bool p3MsgService::removeMsgId(std::string &mid)
{ {
std::map<uint32_t, RsMsgItem *>::iterator mit; std::map<uint32_t, RsMsgItem *>::iterator mit;
uint32_t msgId = atoi(mid.c_str()); uint32_t msgId = atoi(mid.c_str());
bool changed = false ; if (msgId == 0) {
std::cerr << "p3MsgService::removeMsgId: Unknown msgId " << msgId << std::endl;
return false;
}
bool changed = false;
{ {
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
@ -586,15 +635,10 @@ bool p3MsgService::removeMsgId(std::string mid)
mit = imsg.find(msgId); mit = imsg.find(msgId);
if (mit != imsg.end()) if (mit != imsg.end())
{ {
changed = true ; changed = true;
RsMsgItem *mi = mit->second; RsMsgItem *mi = mit->second;
imsg.erase(mit); imsg.erase(mit);
delete mi; delete mi;
// msgChanged.IndicateChanged();
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
return true;
} }
mit = msgOutgoing.find(msgId); mit = msgOutgoing.find(msgId);
@ -604,25 +648,25 @@ bool p3MsgService::removeMsgId(std::string mid)
RsMsgItem *mi = mit->second; RsMsgItem *mi = mit->second;
msgOutgoing.erase(mit); msgOutgoing.erase(mit);
delete mi; delete mi;
// msgChanged.IndicateChanged();
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
return true;
} }
} }
if(changed) if(changed) {
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD); IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
return false; setMessageTag(mid, 0, false);
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD);
}
return changed;
} }
bool p3MsgService::markMsgIdRead(std::string mid) bool p3MsgService::markMsgIdRead(std::string &mid, bool bUnreadByUser)
{ {
std::map<uint32_t, RsMsgItem *>::iterator mit; std::map<uint32_t, RsMsgItem *>::iterator mit;
uint32_t msgId = atoi(mid.c_str()); uint32_t msgId = atoi(mid.c_str());
bool changed = false ; bool changed = false;
{ {
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
@ -630,20 +674,35 @@ bool p3MsgService::markMsgIdRead(std::string mid)
mit = imsg.find(msgId); mit = imsg.find(msgId);
if (mit != imsg.end()) if (mit != imsg.end())
{ {
changed = true ;
RsMsgItem *mi = mit->second; RsMsgItem *mi = mit->second;
mi -> msgFlags &= ~(RS_MSG_FLAGS_NEW);
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/ uint32_t msgFlags = mi->msgFlags;
/* remove new state */
mi->msgFlags &= ~(RS_MSG_FLAGS_NEW);
/* set state from user */
if (bUnreadByUser) {
mi->msgFlags |= RS_MSG_FLAGS_UNREAD_BY_USER;
} else {
mi->msgFlags &= ~RS_MSG_FLAGS_UNREAD_BY_USER;
}
if (mi->msgFlags != msgFlags)
{
changed = true;
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
}
} else {
return false;
} }
} /* UNLOCKED */
if (changed) {
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD);
} }
if(changed) { return true;
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD);
return true;
} else {
return false;
}
} }
/****************************************/ /****************************************/
@ -760,12 +819,13 @@ bool p3MsgService::MessageToDraft(MessageInfo &info)
return false; return false;
} }
bool p3MsgService::MessageGetTagTypes(MsgTagType& tags) bool p3MsgService::getMessageTagTypes(MsgTagType& tags)
{ {
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
std::map<uint32_t, RsMsgTagType*>::iterator mit; std::map<uint32_t, RsMsgTagType*>::iterator mit;
for(mit = mTags.begin(); mit != mTags.end(); mit++) for(mit = mTags.begin(); mit != mTags.end(); mit++) {
{
std::pair<std::string, uint32_t> p(mit->second->text, mit->second->rgb_color); std::pair<std::string, uint32_t> p(mit->second->text, mit->second->rgb_color);
tags.types.insert(std::pair<uint32_t, std::pair<std::string, uint32_t> >(mit->first, p)); tags.types.insert(std::pair<uint32_t, std::pair<std::string, uint32_t> >(mit->first, p));
} }
@ -773,47 +833,243 @@ bool p3MsgService::MessageGetTagTypes(MsgTagType& tags)
return true; return true;
} }
bool p3MsgService::MessageGetMsgTag(std::string msgId, MsgTagInfo& info) bool p3MsgService::setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color)
{ {
int nNotifyType = 0;
std::map<std::string, RsMsgTags*>::iterator mit;
if(mMsgTags.end() != (mit = mMsgTags.find(msgId)))
{ {
info.msgId = mit->second->msgId; RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
info.tagId = mit->second->tagId;
std::map<uint32_t, RsMsgTagType*>::iterator mit;
mit = mTags.find(tagId);
if (mit == mTags.end()) {
if (tagId < RS_MSGTAGTYPE_USER) {
std::cerr << "p3MsgService::MessageSetTagType: Standard tag type " << tagId << " cannot be inserted" << std::endl;
return false;
}
/* new tag */
RsMsgTagType* tagType = new RsMsgTagType();
tagType->PeerId (mConnMgr->getOwnId());
tagType->rgb_color = rgb_color;
tagType->tagId = tagId;
tagType->text = text;
mTags.insert(std::pair<uint32_t, RsMsgTagType*>(tagId, tagType));
nNotifyType = NOTIFY_TYPE_ADD;
} else {
if (mit->second->text != text || mit->second->rgb_color != rgb_color) {
/* modify existing tag */
if (tagId >= RS_MSGTAGTYPE_USER) {
mit->second->text = text;
} else {
/* don't change text for standard tag types */
if (mit->second->text != text) {
std::cerr << "p3MsgService::MessageSetTagType: Text " << text << " for standard tag type " << tagId << " cannot be changed" << std::endl;
}
}
mit->second->rgb_color = rgb_color;
nNotifyType = NOTIFY_TYPE_MOD;
}
}
} /* UNLOCKED */
if (nNotifyType) {
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType);
return true; return true;
} }
std::cerr << "p3MsgService::MessageGetMsgTag: no tag found for msgId " << msgId << std::endl;
return false; return false;
} }
bool p3MsgService::MessageSetTagType(std::string& text, uint32_t tagId, uint32_t rgb_color) bool p3MsgService::removeMessageTagType(uint32_t tagId)
{ {
if (tagId < RS_MSGTAGTYPE_USER) {
std::cerr << "p3MsgService::MessageRemoveTagType: Can't delete standard tag type " << tagId << std::endl;
return false;
}
RsMsgTagType* tagType = new RsMsgTagType(); {
tagType->rgb_color = rgb_color; RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
tagType->tagId = tagId;
tagType->text = text;
mTags.insert(std::pair<uint32_t, RsMsgTagType*>(tagId, tagType)); std::map<uint32_t, RsMsgTagType*>::iterator mit;
mit = mTags.find(tagId);
if (mit == mTags.end()) {
/* tag id not found */
std::cerr << "p3MsgService::MessageRemoveTagType: Tag Id not found " << tagId << std::endl;
return false;
}
/* search for messages with this tag type */
std::map<uint32_t, RsMsgTags*>::iterator mit1;
for (mit1 = mMsgTags.begin(); mit1 != mMsgTags.end(); ) {
RsMsgTags* tag = mit1->second;
std::list<uint32_t>::iterator lit;
lit = std::find(tag->tagIds.begin(), tag->tagIds.end(), tagId);
if (lit != tag->tagIds.end()) {
tag->tagIds.erase(lit);
if (tag->tagIds.size() == 0) {
/* remove empty tag */
delete(tag);
std::map<uint32_t, RsMsgTags*>::iterator mit2 = mit1;
mit1++;
mMsgTags.erase(mit2);
continue;
}
}
mit1++;
}
/* remove tag type */
delete(mit->second);
mTags.erase(mit);
} /* UNLOCKED */
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, NOTIFY_TYPE_DEL);
return true;
} }
bool p3MsgService::MessageSetMsgTag(MsgTagInfo& tagInfo) bool p3MsgService::getMessageTag(std::string &msgId, MsgTagInfo& info)
{ {
RsMsgTags* tag = new RsMsgTags(); RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
tag->msgId = tagInfo.msgId; uint32_t mid = atoi(msgId.c_str());
tag->tagId = tagInfo.tagId; if (mid == 0) {
std::cerr << "p3MsgService::MessageGetMsgTag: Unknown msgId " << msgId << std::endl;
return false;
}
mMsgTags.insert(std::pair<std::string, RsMsgTags*>(tag->msgId, tag)); std::map<uint32_t, RsMsgTags*>::iterator mit;
if(mMsgTags.end() != (mit = mMsgTags.find(mid))) {
std::ostringstream out;
out << mit->second->msgId;
info.msgId = out.str();
info.tagIds = mit->second->tagIds;
return true;
}
return false;
} }
/* set == false && tagId == 0 --> remove all */
bool p3MsgService::setMessageTag(std::string &msgId, uint32_t tagId, bool set)
{
uint32_t mid = atoi(msgId.c_str());
if (mid == 0) {
std::cerr << "p3MsgService::MessageSetMsgTag: Unknown msgId " << msgId << std::endl;
return false;
}
if (tagId == 0) {
if (set == true) {
std::cerr << "p3MsgService::MessageSetMsgTag: No valid tagId given " << tagId << std::endl;
return false;
}
}
int nNotifyType = 0;
{
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
std::map<uint32_t, RsMsgTags*>::iterator mit;
mit = mMsgTags.find(mid);
if (mit == mMsgTags.end()) {
if (set) {
/* new msg */
RsMsgTags* tag = new RsMsgTags();
tag->PeerId (mConnMgr->getOwnId());
tag->msgId = mid;
tag->tagIds.push_back(tagId);
mMsgTags.insert(std::pair<uint32_t, RsMsgTags*>(tag->msgId, tag));
nNotifyType = NOTIFY_TYPE_ADD;
}
} else {
RsMsgTags* tag = mit->second;
/* search existing tagId */
std::list<uint32_t>::iterator lit;
if (tagId) {
lit = std::find(tag->tagIds.begin(), tag->tagIds.end(), tagId);
} else {
lit = tag->tagIds.end();
}
if (set) {
if (lit == tag->tagIds.end()) {
tag->tagIds.push_back(tagId);
/* keep the list sorted */
tag->tagIds.sort();
nNotifyType = NOTIFY_TYPE_ADD;
}
} else {
if (tagId == 0) {
/* remove all */
delete(tag);
mMsgTags.erase(mit);
nNotifyType = NOTIFY_TYPE_DEL;
} else {
if (lit != tag->tagIds.end()) {
tag->tagIds.erase(lit);
nNotifyType = NOTIFY_TYPE_DEL;
if (tag->tagIds.size() == 0) {
/* remove empty tag */
delete(tag);
mMsgTags.erase(mit);
}
}
}
}
}
} /* UNLOCKED */
if (nNotifyType) {
IndicateConfigChanged(); /**** INDICATE MSG CONFIG CHANGED! *****/
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGE_TAGS, nNotifyType);
return true;
}
return false;
}
bool p3MsgService::resetMessageStandardTagTypes(MsgTagType& tags)
{
MsgTagType standardTags;
getStandardTagTypes(standardTags);
std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator mit;
for (mit = standardTags.types.begin(); mit != standardTags.types.end(); mit++) {
tags.types[mit->first] = mit->second;
}
return true;
}
/* move message to trash based on the unique mid */ /* move message to trash based on the unique mid */
bool p3MsgService::MessageToTrash(std::string mid, bool bTrash) bool p3MsgService::MessageToTrash(std::string mid, bool bTrash)
@ -902,6 +1158,14 @@ void p3MsgService::initRsMI(RsMsgItem *msg, MessageInfo &mi)
{ {
mi.msgflags |= RS_MSG_NEW; mi.msgflags |= RS_MSG_NEW;
} }
if (msg->msgFlags & RS_MSG_FLAGS_TRASH)
{
mi.msgflags |= RS_MSG_TRASH;
}
if (msg->msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER)
{
mi.msgflags |= RS_MSG_UNREAD_BY_USER;
}
mi.ts = msg->sendTime; mi.ts = msg->sendTime;
mi.srcId = msg->PeerId(); mi.srcId = msg->PeerId();
@ -985,6 +1249,10 @@ void p3MsgService::initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis)
{ {
mis.msgflags |= RS_MSG_TRASH; mis.msgflags |= RS_MSG_TRASH;
} }
if (msg->msgFlags & RS_MSG_FLAGS_UNREAD_BY_USER)
{
mis.msgflags |= RS_MSG_UNREAD_BY_USER;
}
mis.srcId = msg->PeerId(); mis.srcId = msg->PeerId();
{ {

View File

@ -56,21 +56,25 @@ bool MsgNotifications(); /* popup - messages */
bool getMessageNotifications(std::list<MsgInfoSummary> &noteList); bool getMessageNotifications(std::list<MsgInfoSummary> &noteList);
bool getMessageSummaries(std::list<MsgInfoSummary> &msgList); bool getMessageSummaries(std::list<MsgInfoSummary> &msgList);
bool getMessage(std::string mid, MessageInfo &msg); bool getMessage(std::string &mid, MessageInfo &msg);
void getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxNew, unsigned int *pnOutbox, unsigned int *pnDraftbox, unsigned int *pnSentbox, unsigned int *pnTrashbox); void getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxNew, unsigned int *pnOutbox, unsigned int *pnDraftbox, unsigned int *pnSentbox, unsigned int *pnTrashbox);
bool removeMsgId(std::string mid); bool removeMsgId(std::string &mid);
bool markMsgIdRead(std::string mid); bool markMsgIdRead(std::string &mid, bool bUnreadByUser);
bool MessageSend(MessageInfo &info); bool MessageSend(MessageInfo &info);
bool MessageToDraft(MessageInfo &info); bool MessageToDraft(MessageInfo &info);
bool MessageToTrash(std::string mid, bool bTrash); bool MessageToTrash(std::string mid, bool bTrash);
bool MessageGetTagTypes(MsgTagType& tags); bool getMessageTagTypes(MsgTagType& tags);
bool MessageGetMsgTag(std::string msgId, MsgTagInfo& info); bool setMessageTagType(uint32_t tagId, std::string& text, uint32_t rgb_color);
bool removeMessageTagType(uint32_t tagId);
bool MessageSetTagType(std::string& text, uint32_t tag_id, uint32_t rgb_color); bool getMessageTag(std::string &msgId, MsgTagInfo& info);
bool MessageSetMsgTag(MsgTagInfo& ); /* set == false && tagId == 0 --> remove all */
bool setMessageTag(std::string &msgId, uint32_t tagId, bool set);
bool resetMessageStandardTagTypes(MsgTagType& tags);
void loadWelcomeMsg(); /* startup message */ void loadWelcomeMsg(); /* startup message */
@ -100,6 +104,8 @@ void initRsMI(RsMsgItem *msg, MessageInfo &mi);
void initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis); void initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis);
RsMsgItem *initMIRsMsg(MessageInfo &info, std::string to); RsMsgItem *initMIRsMsg(MessageInfo &info, std::string to);
void initStandardTagTypes();
p3ConnectMgr *mConnMgr; p3ConnectMgr *mConnMgr;
/* Mutex Required for stuff below */ /* Mutex Required for stuff below */
@ -117,7 +123,7 @@ RsMsgItem *initMIRsMsg(MessageInfo &info, std::string to);
/* maps for tags types and msg tags */ /* maps for tags types and msg tags */
std::map<uint32_t, RsMsgTagType*> mTags; std::map<uint32_t, RsMsgTagType*> mTags;
std::map<std::string, RsMsgTags*> mMsgTags; std::map<uint32_t, RsMsgTags*> mMsgTags;
Indicator msgChanged; Indicator msgChanged;

View File

@ -94,8 +94,12 @@ RsSerialType* init_item(RsMsgTagType& mtt)
RsSerialType* init_item(RsMsgTags& mt) RsSerialType* init_item(RsMsgTags& mt)
{ {
randString(SHORT_STR, mt.msgId); mt.msgId = rand()%3334;
mt.tagId = rand()%3334;
int i;
for (i = 0; i < 10; i++) {
mt.tagIds.push_back(rand()%21341);
}
return new RsMsgSerialiser(); return new RsMsgSerialiser();
} }
@ -173,7 +177,7 @@ bool operator ==(const RsMsgTagType& mttLeft, const RsMsgTagType& mttRight)
bool operator ==(const RsMsgTags& mtLeft, const RsMsgTags& mtRight) bool operator ==(const RsMsgTags& mtLeft, const RsMsgTags& mtRight)
{ {
if(mtLeft.msgId != mtRight.msgId) return false; if(mtLeft.msgId != mtRight.msgId) return false;
if(mtLeft.tagId != mtRight.tagId) return false; if(mtLeft.tagIds != mtRight.tagIds) return false;
return true; return true;
} }

View File

@ -42,6 +42,7 @@
#include <retroshare/rspeers.h> #include <retroshare/rspeers.h>
#include <retroshare/rsfiles.h> #include <retroshare/rsfiles.h>
#include <algorithm>
/* Images for context menu icons */ /* Images for context menu icons */
#define IMAGE_MESSAGE ":/images/folder-draft.png" #define IMAGE_MESSAGE ":/images/folder-draft.png"
@ -83,17 +84,6 @@
#define ACTION_TAGS_TAG 1 #define ACTION_TAGS_TAG 1
#define ACTION_TAGS_NEWTAG 2 #define ACTION_TAGS_NEWTAG 2
#define CONFIG_FILE (RsInit::RsProfileConfigDirectory() + "/msg_locale.cfg")
#define CONFIG_SECTION_UNREAD "Unread"
#define CONFIG_SECTION_TAGS "Tags"
#define CONFIG_KEY_TEXT "Text"
#define CONFIG_KEY_COLOR "Color"
#define CONFIG_SECTION_TAG "Tag"
#define CONFIG_KEY_TAG "Tag"
class MessagesItemDelegate : public QItemDelegate class MessagesItemDelegate : public QItemDelegate
{ {
public: public:
@ -189,6 +179,11 @@ MessagesDialog::LockUpdate::~LockUpdate ()
} }
} }
void MessagesDialog::LockUpdate::setUpdate(bool bUpdate)
{
m_bUpdate = bUpdate;
}
static int FilterColumnFromComboBox(int nIndex) static int FilterColumnFromComboBox(int nIndex)
{ {
switch (nIndex) { switch (nIndex) {
@ -239,7 +234,6 @@ MessagesDialog::MessagesDialog(QWidget *parent)
m_bProcessSettings = false; m_bProcessSettings = false;
m_bInChange = false; m_bInChange = false;
m_nLockUpdate = 0; m_nLockUpdate = 0;
m_pConfig = new RSettings (CONFIG_FILE);
connect( ui.messagestreeView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( messageslistWidgetCostumPopupMenu( QPoint ) ) ); connect( ui.messagestreeView, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( messageslistWidgetCostumPopupMenu( QPoint ) ) );
connect( ui.msgList, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( msgfilelistWidgetCostumPopupMenu( QPoint ) ) ); connect( ui.msgList, SIGNAL( customContextMenuRequested( QPoint ) ), this, SLOT( msgfilelistWidgetCostumPopupMenu( QPoint ) ) );
@ -403,8 +397,6 @@ MessagesDialog::~MessagesDialog()
// save settings // save settings
processSettings(false); processSettings(false);
delete (m_pConfig);
} }
void MessagesDialog::processSettings(bool bLoad) void MessagesDialog::processSettings(bool bLoad)
@ -459,168 +451,11 @@ void MessagesDialog::processSettings(bool bLoad)
m_bProcessSettings = false; m_bProcessSettings = false;
} }
static void getMessageTags (RSettings *pConfig, QString msgId, QList<int> &tagIds)
{
pConfig->beginGroup(CONFIG_SECTION_TAG);
int nSize = pConfig->beginReadArray(msgId);
for (int i = 0; i < nSize; i++) {
pConfig->setArrayIndex(i);
int nTagId = pConfig->value(CONFIG_KEY_TAG).toInt();
tagIds.push_back(nTagId);
}
pConfig->endArray();
pConfig->endGroup();
}
static void setMessageTags (RSettings *pConfig, QString &msgId, QList<int> &tagIds)
{
pConfig->beginGroup(CONFIG_SECTION_TAG);
pConfig->remove(msgId);
if (tagIds.size()) {
pConfig->beginWriteArray(msgId, tagIds.size());
int i = 0;
for (QList<int>::iterator tagId = tagIds.begin(); tagId != tagIds.end(); tagId++) {
pConfig->setArrayIndex(i++);
pConfig->setValue(CONFIG_KEY_TAG, *tagId);
}
pConfig->endArray();
}
pConfig->endGroup();
}
/*static*/ void MessagesDialog::initStandardTagItems(std::map<int, TagItem> &Items)
{
// create standard enties ... id = sort, maybe later own member
Items [-5].text = tr("Important");
Items [-5].color = QColor(255, 0, 0).rgb();
Items [-4].text = tr("Work");
Items [-4].color = QColor(255, 153, 0).rgb();
Items [-3].text = tr("Personal");
Items [-3].color = QColor(0, 153, 0).rgb();
Items [-2].text = tr("Todo");
Items [-2].color = QColor(51, 51, 255).rgb();
Items [-1].text = tr("Later");
Items [-1].color = QColor(153, 51, 153).rgb();
}
void MessagesDialog::getTagItems(std::map<int, TagItem> &Items)
{
initStandardTagItems (Items);
// create standard enties
initStandardTagItems(Items);
// load user tags and colors
m_pConfig->beginGroup(CONFIG_SECTION_TAGS);
QStringList ids = m_pConfig->childGroups();
for (QStringList::iterator id = ids.begin(); id != ids.end(); id++) {
int nId = 0;
std::istringstream instream((*id).toStdString());
instream >> nId;
m_pConfig->beginGroup(*id);
TagItem Item;
if (nId < 0) {
// standard tag
Item = Items[nId];
} else {
Item.text = m_pConfig->value(CONFIG_KEY_TEXT).toString();
}
Item.color = m_pConfig->value(CONFIG_KEY_COLOR, Item.color).toUInt();
m_pConfig->endGroup();
Items [nId] = Item;
}
m_pConfig->endGroup();
}
void MessagesDialog::setTagItems(std::map<int, TagItem> &Items)
{
// process deleted tags
QList<int> tagIdsToDelete;
std::map<int, TagItem>::iterator Item;
for (Item = Items.begin(); Item != Items.end(); Item++) {
if (Item->second._delete) {
tagIdsToDelete.push_back(Item->first);
}
}
if (tagIdsToDelete.size()) {
// iterate all saved tags on messages and remove the id's
// get all msgIds with tags
m_pConfig->beginGroup(CONFIG_SECTION_TAG);
QStringList msgIds = m_pConfig->childGroups();
m_pConfig->endGroup();
for (QStringList::iterator msgId = msgIds.begin(); msgId != msgIds.end(); msgId++) {
QList<int> tagIds;
getMessageTags (m_pConfig, *msgId, tagIds);
bool bSave = false;
for (QList<int>::iterator tagIdToDelete = tagIdsToDelete.begin(); tagIdToDelete != tagIdsToDelete.end(); tagIdToDelete++) {
QList<int>::iterator tagId = qFind(tagIds.begin(), tagIds.end(), *tagIdToDelete);
if (tagId != tagIds.end()) {
tagIds.erase(tagId);
bSave = true;
}
}
if (bSave) {
setMessageTags (m_pConfig, *msgId, tagIds);
}
}
}
// save tags
m_pConfig->remove(CONFIG_SECTION_TAGS);
m_pConfig->beginGroup(CONFIG_SECTION_TAGS);
for (Item = Items.begin(); Item != Items.end(); Item++) {
if (Item->second._delete) {
continue;
}
QString sId;
sId.sprintf("%d", Item->first);
m_pConfig->beginGroup(sId);
if (Item->first > 0) {
m_pConfig->setValue(CONFIG_KEY_TEXT, Item->second.text);
}
m_pConfig->setValue(CONFIG_KEY_COLOR, Item->second.color);
m_pConfig->endGroup();
}
m_pConfig->endGroup();
fillTags();
insertMessages();
}
void MessagesDialog::fillTags() void MessagesDialog::fillTags()
{ {
std::map<int, TagItem> TagItems; MsgTagType Tags;
std::map<int, TagItem>::iterator Item; rsMsgs->getMessageTagTypes(Tags);
getTagItems(TagItems); std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
// create tag menu // create tag menu
QMenu *pMenu = new MessagesMenu (tr("Tag"), this); QMenu *pMenu = new MessagesMenu (tr("Tag"), this);
@ -629,10 +464,11 @@ void MessagesDialog::fillTags()
bool bUser = false; bool bUser = false;
QString text;
QAction *pAction; QAction *pAction;
QMap<QString, QVariant> Values; QMap<QString, QVariant> Values;
if (TagItems.size()) { if (Tags.types.size()) {
pAction = new QAction(tr("Remove All Tags"), pMenu); pAction = new QAction(tr("Remove All Tags"), pMenu);
Values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_REMOVEALL; Values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_REMOVEALL;
Values [ACTION_TAGSINDEX_ID] = 0; Values [ACTION_TAGSINDEX_ID] = 0;
@ -642,15 +478,20 @@ void MessagesDialog::fillTags()
pMenu->addSeparator(); pMenu->addSeparator();
for (Item = TagItems.begin(); Item != TagItems.end(); Item++) { for (Tag = Tags.types.begin(); Tag != Tags.types.end(); Tag++) {
pAction = new QAction(Item->second.text, pMenu); if (Tag->first < RS_MSGTAGTYPE_USER) {
text = tr(Tag->second.first.c_str());
} else {
text = QString::fromStdString(Tag->second.first);
}
pAction = new QAction(text, pMenu);
Values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_TAG; Values [ACTION_TAGSINDEX_TYPE] = ACTION_TAGS_TAG;
Values [ACTION_TAGSINDEX_ID] = Item->first; Values [ACTION_TAGSINDEX_ID] = Tag->first;
Values [ACTION_TAGSINDEX_COLOR] = Item->second.color; Values [ACTION_TAGSINDEX_COLOR] = QRgb(Tag->second.second);
pAction->setData (Values); pAction->setData (Values);
pAction->setCheckable(true); pAction->setCheckable(true);
if (Item->first > 0 && bUser == false) { if (Tag->first >= RS_MSGTAGTYPE_USER && bUser == false) {
bUser = true; bUser = true;
pMenu->addSeparator(); pMenu->addSeparator();
} }
@ -675,7 +516,7 @@ void MessagesDialog::fillTags()
// save current selection // save current selection
QListWidgetItem *pItem = ui.tagWidget->currentItem(); QListWidgetItem *pItem = ui.tagWidget->currentItem();
int nSelectecTagId = 0; uint32_t nSelectecTagId = 0;
if (pItem) { if (pItem) {
nSelectecTagId = pItem->data(Qt::UserRole).toInt(); nSelectecTagId = pItem->data(Qt::UserRole).toInt();
} }
@ -683,14 +524,19 @@ void MessagesDialog::fillTags()
QListWidgetItem *pItemToSelect = NULL; QListWidgetItem *pItemToSelect = NULL;
ui.tagWidget->clear(); ui.tagWidget->clear();
for (Item = TagItems.begin(); Item != TagItems.end(); Item++) { for (Tag = Tags.types.begin(); Tag != Tags.types.end(); Tag++) {
pItem = new QListWidgetItem (Item->second.text, ui.tagWidget); if (Tag->first < RS_MSGTAGTYPE_USER) {
pItem->setForeground(QBrush(QColor(Item->second.color))); text = tr(Tag->second.first.c_str());
} else {
text = QString::fromStdString(Tag->second.first);
}
pItem = new QListWidgetItem (text, ui.tagWidget);
pItem->setForeground(QBrush(QColor(Tag->second.second)));
pItem->setIcon(QIcon(":/images/foldermail.png")); pItem->setIcon(QIcon(":/images/foldermail.png"));
pItem->setData(Qt::UserRole, Item->first); pItem->setData(Qt::UserRole, Tag->first);
pItem->setData(Qt::UserRole + 1, Item->second.text); // for updateMessageSummaryList pItem->setData(Qt::UserRole + 1, text); // for updateMessageSummaryList
if (Item->first == nSelectecTagId) { if (Tag->first == nSelectecTagId) {
pItemToSelect = pItem; pItemToSelect = pItem;
} }
} }
@ -1211,15 +1057,23 @@ void MessagesDialog::changeTag(int)
m_bInChange = false; m_bInChange = false;
} }
static void InitIconAndFont(RSettings *pConfig, QStandardItem *pItem [COLUMN_COUNT], int nFlag) void MessagesDialog::messagesTagsChanged()
{
if (m_nLockUpdate) {
return;
}
fillTags();
insertMessages();
}
static void InitIconAndFont(QStandardItem *pItem [COLUMN_COUNT], int nFlag)
{ {
QString sText = pItem [COLUMN_SUBJECT]->text(); QString sText = pItem [COLUMN_SUBJECT]->text();
QString mid = pItem [COLUMN_DATA]->data(ROLE_MSGID).toString(); QString mid = pItem [COLUMN_DATA]->data(ROLE_MSGID).toString();
bool bNew = (nFlag & RS_MSG_NEW);
// show the real "New" state // show the real "New" state
if (bNew) { if (nFlag & RS_MSG_NEW) {
if (sText.startsWith("Re:", Qt::CaseInsensitive)) { if (sText.startsWith("Re:", Qt::CaseInsensitive)) {
pItem[COLUMN_SUBJECT]->setIcon(QIcon(":/images/message-mail-replied.png")); pItem[COLUMN_SUBJECT]->setIcon(QIcon(":/images/message-mail-replied.png"));
} else if (sText.startsWith("Fwd:", Qt::CaseInsensitive)) { } else if (sText.startsWith("Fwd:", Qt::CaseInsensitive)) {
@ -1240,13 +1094,7 @@ static void InitIconAndFont(RSettings *pConfig, QStandardItem *pItem [COLUMN_COU
pItem[COLUMN_SUBJECT]->setIcon(QIcon()); pItem[COLUMN_SUBJECT]->setIcon(QIcon());
} }
// show the locale "New" state bool bNew = nFlag & (RS_MSG_NEW | RS_MSG_UNREAD_BY_USER);
if (bNew == false) {
// check locale config
pConfig->beginGroup(CONFIG_SECTION_UNREAD);
bNew = pConfig->value(mid, false).toBool();
pConfig->endGroup();
}
// set icon // set icon
if (bNew) { if (bNew) {
@ -1291,7 +1139,7 @@ void MessagesDialog::insertMessages()
unsigned int msgbox = 0; unsigned int msgbox = 0;
bool bTrash = false; bool bTrash = false;
bool bFill = true; bool bFill = true;
int nTagId = 0; uint32_t nTagId = 0;
switch (m_eListMode) { switch (m_eListMode) {
case LIST_NOTHING: case LIST_NOTHING:
@ -1356,8 +1204,8 @@ void MessagesDialog::insertMessages()
} }
if (bFill) { if (bFill) {
std::map<int, TagItem> TagItems; MsgTagType Tags;
getTagItems(TagItems); rsMsgs->getMessageTagTypes(Tags);
/* search messages */ /* search messages */
std::list<MsgInfoSummary> msgToShow; std::list<MsgInfoSummary> msgToShow;
@ -1376,9 +1224,9 @@ void MessagesDialog::insertMessages()
} }
} }
} else if (m_eListMode == LIST_TAG) { } else if (m_eListMode == LIST_TAG) {
QList<int> tagIds; MsgTagInfo tagInfo;
getMessageTags (m_pConfig, QString::fromStdString(it->msgId), tagIds); rsMsgs->getMessageTag(it->msgId, tagInfo);
if (qFind(tagIds.begin(), tagIds.end(), nTagId) == tagIds.end()) { if (std::find(tagInfo.tagIds.begin(), tagInfo.tagIds.end(), nTagId) == tagInfo.tagIds.end()) {
continue; continue;
} }
} else { } else {
@ -1539,27 +1387,44 @@ void MessagesDialog::insertMessages()
item[COLUMN_DATA]->setData(msgId, ROLE_MSGID); item[COLUMN_DATA]->setData(msgId, ROLE_MSGID);
// Init icon and font // Init icon and font
InitIconAndFont(m_pConfig, item, it->msgflags); InitIconAndFont(item, it->msgflags);
// Tags // Tags
QList<int> tagIds; MsgTagInfo tagInfo;
getMessageTags (m_pConfig, msgId, tagIds); rsMsgs->getMessageTag(it->msgId, tagInfo);
qSort(tagIds.begin(), tagIds.end());
text.clear(); text.clear();
for (QList<int>::iterator tagId = tagIds.begin(); tagId != tagIds.end(); tagId++) { // build tag names
std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
for (std::list<uint32_t>::iterator tagId = tagInfo.tagIds.begin(); tagId != tagInfo.tagIds.end(); tagId++) {
if (text.isEmpty() == false) { if (text.isEmpty() == false) {
text += ","; text += ",";
} }
text += TagItems[*tagId].text; Tag = Tags.types.find(*tagId);
if (Tag != Tags.types.end()) {
if (Tag->first < RS_MSGTAGTYPE_USER) {
text += tr(Tag->second.first.c_str());
} else {
text += QString::fromStdString(Tag->second.first);
}
} else {
// clean tagId
rsMsgs->setMessageTag(it->msgId, *tagId, false);
}
} }
item[COLUMN_TAGS]->setText(text); item[COLUMN_TAGS]->setText(text);
// set color // set color
QBrush Brush; // standard QBrush Brush; // standard
if (tagIds.size()) { if (tagInfo.tagIds.size()) {
Brush = QBrush(TagItems [tagIds [0]].color); Tag = Tags.types.find(tagInfo.tagIds.front());
if (Tag != Tags.types.end()) {
Brush = QBrush(Tag->second.second);
} else {
// clean tagId
rsMsgs->setMessageTag(it->msgId, tagInfo.tagIds.front(), false);
}
} }
for (int i = 0; i < COLUMN_COUNT; i++) { for (int i = 0; i < COLUMN_COUNT; i++) {
item[i]->setForeground(Brush); item[i]->setForeground(Brush);
@ -1671,26 +1536,13 @@ void MessagesDialog::setMsgAsReadUnread(const QList<int> &Rows, bool bRead)
item[nCol] = MessagesModel->item(Rows [nRow], nCol); item[nCol] = MessagesModel->item(Rows [nRow], nCol);
} }
QString mid = item[COLUMN_DATA]->data(ROLE_MSGID).toString(); std::string mid = item[COLUMN_DATA]->data(ROLE_MSGID).toString().toStdString();
if (bRead) { if (rsMsgs->MessageRead(mid, !bRead)) {
// set as read in config InitIconAndFont(item, bRead ? 0 : RS_MSG_UNREAD_BY_USER);
m_pConfig->beginGroup(CONFIG_SECTION_UNREAD);
m_pConfig->setValue(mid, false);
m_pConfig->endGroup();
// set message to read
rsMsgs->MessageRead(mid.toStdString());
} else {
// set as unread in config
m_pConfig->beginGroup(CONFIG_SECTION_UNREAD);
m_pConfig->setValue(mid, true);
m_pConfig->endGroup();
} }
InitIconAndFont(m_pConfig, item, 0);
} }
// LockUpdate // LockUpdate
} }
@ -1784,15 +1636,16 @@ void MessagesDialog::insertMsgTxtAndFiles(QModelIndex Index, bool bSetToRead)
bool bSetToReadOnActive = Settings->getMsgSetToReadOnActivate(); bool bSetToReadOnActive = Settings->getMsgSetToReadOnActivate();
if (msgInfo.msgflags & RS_MSG_NEW) { if (msgInfo.msgflags & RS_MSG_NEW) {
// set to read // set always to read or unread
setMsgAsReadUnread(Rows, true);
if (bSetToReadOnActive == false || bSetToRead == false) { if (bSetToReadOnActive == false || bSetToRead == false) {
// set locally to unread // set locally to unread
setMsgAsReadUnread(Rows, false); setMsgAsReadUnread(Rows, false);
} else {
setMsgAsReadUnread(Rows, true);
} }
updateMessageSummaryList(); updateMessageSummaryList();
} else { } else {
if (bSetToRead && bSetToReadOnActive) { if ((msgInfo.msgflags & RS_MSG_UNREAD_BY_USER) && bSetToRead && bSetToReadOnActive) {
// set to read // set to read
setMsgAsReadUnread(Rows, true); setMsgAsReadUnread(Rows, true);
updateMessageSummaryList(); updateMessageSummaryList();
@ -1968,15 +1821,6 @@ void MessagesDialog::removemessage()
if (bDelete) { if (bDelete) {
rsMsgs->MessageDelete(mid.toStdString()); rsMsgs->MessageDelete(mid.toStdString());
// clean locale config
m_pConfig->beginGroup(CONFIG_SECTION_UNREAD);
m_pConfig->remove (mid);
m_pConfig->endGroup();
// remove tag
m_pConfig->beginGroup(CONFIG_SECTION_TAG);
m_pConfig->remove (mid);
m_pConfig->endGroup();
} else { } else {
rsMsgs->MessageToTrash(mid.toStdString(), true); rsMsgs->MessageToTrash(mid.toStdString(), true);
} }
@ -1988,7 +1832,7 @@ void MessagesDialog::removemessage()
void MessagesDialog::undeletemessage() void MessagesDialog::undeletemessage()
{ {
LockUpdate (this, true); LockUpdate Lock (this, true);
QList<int> Rows; QList<int> Rows;
getSelectedMsgCount (&Rows, NULL, NULL); getSelectedMsgCount (&Rows, NULL, NULL);
@ -2156,12 +2000,12 @@ void MessagesDialog::updateMessageSummaryList()
QMap<int, int> tagCount; QMap<int, int> tagCount;
/*calculating the new messages*/ /* calculating the new messages */
for (it = msgList.begin(); it != msgList.end(); it++) { for (it = msgList.begin(); it != msgList.end(); it++) {
/* calcluate tag count */ /* calcluate tag count */
QList<int> tagIds; MsgTagInfo tagInfo;
getMessageTags (m_pConfig, QString::fromStdString(it->msgId), tagIds); rsMsgs->getMessageTag(it->msgId, tagInfo);
for (QList<int>::iterator tagId = tagIds.begin(); tagId != tagIds.end(); tagId++) { for (std::list<uint32_t>::iterator tagId = tagInfo.tagIds.begin(); tagId != tagInfo.tagIds.end(); tagId++) {
int nCount = tagCount [*tagId]; int nCount = tagCount [*tagId];
nCount++; nCount++;
tagCount [*tagId] = nCount; tagCount [*tagId] = nCount;
@ -2176,15 +2020,8 @@ void MessagesDialog::updateMessageSummaryList()
switch (it->msgflags & RS_MSG_BOXMASK) { switch (it->msgflags & RS_MSG_BOXMASK) {
case RS_MSG_INBOX: case RS_MSG_INBOX:
inboxCount++; inboxCount++;
if ((it->msgflags & RS_MSG_NEW) == RS_MSG_NEW) { if (it->msgflags & (RS_MSG_NEW | RS_MSG_UNREAD_BY_USER)) {
newInboxCount++; newInboxCount++;
} else {
// check locale config
m_pConfig->beginGroup(CONFIG_SECTION_UNREAD);
if (m_pConfig->value(QString::fromStdString(it->msgId), false).toBool()) {
newInboxCount++;
}
m_pConfig->endGroup();
} }
break; break;
case RS_MSG_OUTBOX: case RS_MSG_OUTBOX:
@ -2332,16 +2169,16 @@ void MessagesDialog::clearFilter()
void MessagesDialog::tagAboutToShow() void MessagesDialog::tagAboutToShow()
{ {
// activate actions from the first selected row // activate actions from the first selected row
QList<int> tagIds; MsgTagInfo tagInfo;
QList<int> Rows; QList<int> Rows;
getSelectedMsgCount (&Rows, NULL, NULL); getSelectedMsgCount (&Rows, NULL, NULL);
if (Rows.size()) { if (Rows.size()) {
QStandardItem* pItem = MessagesModel->item(Rows [0], COLUMN_DATA); QStandardItem* pItem = MessagesModel->item(Rows [0], COLUMN_DATA);
QString msgId = pItem->data(ROLE_MSGID).toString(); std::string msgId = pItem->data(ROLE_MSGID).toString().toStdString();
getMessageTags(m_pConfig, msgId, tagIds); rsMsgs->getMessageTag(msgId, tagInfo);
} }
QMenu *pMenu = ui.tagButton->menu(); QMenu *pMenu = ui.tagButton->menu();
@ -2360,8 +2197,8 @@ void MessagesDialog::tagAboutToShow()
continue; continue;
} }
QList<int>::iterator tagId = qFind(tagIds.begin(), tagIds.end(), Values [ACTION_TAGSINDEX_ID]); std::list<uint32_t>::iterator tagId = std::find(tagInfo.tagIds.begin(), tagInfo.tagIds.end(), Values [ACTION_TAGSINDEX_ID]);
pAction->setChecked(tagId != tagIds.end()); pAction->setChecked(tagId != tagInfo.tagIds.end());
} }
} }
@ -2376,6 +2213,8 @@ void MessagesDialog::tagTriggered(QAction *pAction)
return; return;
} }
LockUpdate Lock (this, false);
bool bRemoveAll = false; bool bRemoveAll = false;
int nId = 0; int nId = 0;
bool bSet = false; bool bSet = false;
@ -2385,14 +2224,20 @@ void MessagesDialog::tagTriggered(QAction *pAction)
bRemoveAll = true; bRemoveAll = true;
} else if (Values [ACTION_TAGSINDEX_TYPE] == ACTION_TAGS_NEWTAG) { } else if (Values [ACTION_TAGSINDEX_TYPE] == ACTION_TAGS_NEWTAG) {
// new tag // new tag
std::map<int, TagItem> TagItems; MsgTagType Tags;
getTagItems(TagItems); rsMsgs->getMessageTagTypes(Tags);
NewTag Tag(TagItems); NewTag TagDlg(Tags);
if (Tag.exec() == QDialog::Accepted && Tag.m_nId) { if (TagDlg.exec() == QDialog::Accepted && TagDlg.m_nId) {
// Tag.m_nId std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag = Tags.types.find(TagDlg.m_nId);
setTagItems (TagItems); if (Tag == Tags.types.end()) {
nId = Tag.m_nId; return;
}
if (rsMsgs->setMessageTagType(Tag->first, Tag->second.first, Tag->second.second) == false) {
return;
}
fillTags();
nId = TagDlg.m_nId;
bSet = true; bSet = true;
} else { } else {
return; return;
@ -2411,41 +2256,21 @@ void MessagesDialog::tagTriggered(QAction *pAction)
getSelectedMsgCount (&Rows, NULL, NULL); getSelectedMsgCount (&Rows, NULL, NULL);
for (int nRow = 0; nRow < Rows.size(); nRow++) { for (int nRow = 0; nRow < Rows.size(); nRow++) {
QStandardItem* pItem = MessagesModel->item(Rows [nRow], COLUMN_DATA); QStandardItem* pItem = MessagesModel->item(Rows [nRow], COLUMN_DATA);
QString msgId = pItem->data(ROLE_MSGID).toString(); std::string msgId = pItem->data(ROLE_MSGID).toString().toStdString();
if (bRemoveAll) { if (bRemoveAll) {
// remove all // remove all
m_pConfig->beginGroup(CONFIG_SECTION_TAG); rsMsgs->setMessageTag(msgId, 0, false);
m_pConfig->remove (msgId); Lock.setUpdate(true);
m_pConfig->endGroup();
insertMessages();
} else { } else {
// set or unset tag // set or unset tag
QList<int> tagIds; MsgTagInfo tagInfo;
getMessageTags(m_pConfig, msgId, tagIds); if (rsMsgs->setMessageTag(msgId, nId, bSet)) {
Lock.setUpdate(true);
QList<int>::iterator tagId = qFind(tagIds.begin(), tagIds.end(), nId);
bool bSaveAndRefresh = false;
if (bSet) {
if (tagId == tagIds.end()) {
// not found
tagIds.push_back(nId);
bSaveAndRefresh = true;
}
} else {
if (tagId != tagIds.end()) {
// found
tagIds.erase(tagId);
bSaveAndRefresh = true;
}
}
if (bSaveAndRefresh) {
setMessageTags(m_pConfig, msgId, tagIds);
insertMessages();
} }
} }
} }
// LockUpdate -> insertMessages();
} }

View File

@ -35,8 +35,6 @@
#include "settings/NewTag.h" #include "settings/NewTag.h"
class RSettings;
class MessagesDialog : public MainPage class MessagesDialog : public MainPage
{ {
Q_OBJECT Q_OBJECT
@ -47,16 +45,12 @@ public:
/** Default Destructor */ /** Default Destructor */
~MessagesDialog(); ~MessagesDialog();
static void initStandardTagItems(std::map<int, TagItem> &Items);
void getTagItems(std::map<int, TagItem> &Items);
void setTagItems(std::map<int, TagItem> &Items);
// replaced by shortcut // replaced by shortcut
// virtual void keyPressEvent(QKeyEvent *) ; // virtual void keyPressEvent(QKeyEvent *) ;
public slots: public slots:
void insertMessages(); void insertMessages();
void messagesTagsChanged();
private slots: private slots:
@ -118,6 +112,8 @@ private:
LockUpdate (MessagesDialog *pDialog, bool bUpdate); LockUpdate (MessagesDialog *pDialog, bool bUpdate);
~LockUpdate (); ~LockUpdate ();
void setUpdate(bool bUpdate);
private: private:
MessagesDialog *m_pDialog; MessagesDialog *m_pDialog;
bool m_bUpdate; bool m_bUpdate;
@ -155,7 +151,6 @@ private:
QString fileName; QString fileName;
QFont mFont; QFont mFont;
RSettings *m_pConfig;
// timer and index for showing message // timer and index for showing message
QTimer *timer; QTimer *timer;

View File

@ -198,6 +198,12 @@ void NotifyQt::notifyListChange(int list, int type)
#endif #endif
emit messagesChanged() ; emit messagesChanged() ;
break; break;
case NOTIFY_LIST_MESSAGE_TAGS:
#ifdef NOTIFY_DEBUG
std::cerr << "received msg tags changed" << std::endl ;
#endif
emit messagesTagsChanged();
break;
case NOTIFY_LIST_CHANNELLIST: case NOTIFY_LIST_CHANNELLIST:
break; break;
case NOTIFY_LIST_TRANSFERLIST: case NOTIFY_LIST_TRANSFERLIST:

View File

@ -58,6 +58,7 @@ class NotifyQt: public QObject, public NotifyBase
void friendsChanged() const ; void friendsChanged() const ;
void neighborsChanged() const ; void neighborsChanged() const ;
void messagesChanged() const ; void messagesChanged() const ;
void messagesTagsChanged() const;
void forumsChanged() const ; // use connect with Qt::QueuedConnection void forumsChanged() const ; // use connect with Qt::QueuedConnection
void configChanged() const ; void configChanged() const ;
void logInfoChanged(const QString&) const ; void logInfoChanged(const QString&) const ;

View File

@ -22,9 +22,12 @@
#include "MessagePage.h" #include "MessagePage.h"
#include "rshare.h" #include "rshare.h"
#include "rsharesettings.h" #include "rsharesettings.h"
#include "retroshare/rsmsgs.h"
#include <algorithm>
#include "../MainWindow.h" #include "../MainWindow.h"
#include "../MessagesDialog.h" #include "NewTag.h"
MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags) MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags)
: ConfigPage(parent, flags) : ConfigPage(parent, flags)
@ -32,6 +35,8 @@ MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags)
ui.setupUi(this); ui.setupUi(this);
setAttribute(Qt::WA_QuitOnClose, false); setAttribute(Qt::WA_QuitOnClose, false);
m_pTags = new MsgTagType;
connect (ui.addpushButton, SIGNAL(clicked(bool)), this, SLOT (addTag())); connect (ui.addpushButton, SIGNAL(clicked(bool)), this, SLOT (addTag()));
connect (ui.editpushButton, SIGNAL(clicked(bool)), this, SLOT (editTag())); connect (ui.editpushButton, SIGNAL(clicked(bool)), this, SLOT (editTag()));
connect (ui.deletepushButton, SIGNAL(clicked(bool)), this, SLOT (deleteTag())); connect (ui.deletepushButton, SIGNAL(clicked(bool)), this, SLOT (deleteTag()));
@ -45,6 +50,7 @@ MessagePage::MessagePage(QWidget * parent, Qt::WFlags flags)
MessagePage::~MessagePage() MessagePage::~MessagePage()
{ {
delete(m_pTags);
} }
void void
@ -59,9 +65,22 @@ MessagePage::save(QString &errmsg)
{ {
Settings->setMsgSetToReadOnActivate(ui.setMsgToReadOnActivate->isChecked()); Settings->setMsgSetToReadOnActivate(ui.setMsgToReadOnActivate->isChecked());
MessagesDialog *pPage = (MessagesDialog*) MainWindow::getPage (MainWindow::Messages); std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
if (pPage) { for (Tag = m_pTags->types.begin(); Tag != m_pTags->types.end(); Tag++) {
pPage->setTagItems (m_TagItems); // check for changed tags
std::list<uint32_t>::iterator changedTagId;
for (changedTagId = m_changedTagIds.begin(); changedTagId != m_changedTagIds.end(); changedTagId++) {
if (*changedTagId == Tag->first) {
if (Tag->second.first.empty()) {
// delete tag
rsMsgs->removeMessageTagType(Tag->first);
continue;
}
rsMsgs->setMessageTagType(Tag->first, Tag->second.first, Tag->second.second);
break;
}
}
} }
return true; return true;
@ -73,47 +92,49 @@ MessagePage::load()
{ {
ui.setMsgToReadOnActivate->setChecked(Settings->getMsgSetToReadOnActivate()); ui.setMsgToReadOnActivate->setChecked(Settings->getMsgSetToReadOnActivate());
MessagesDialog *pPage = (MessagesDialog*) MainWindow::getPage (MainWindow::Messages); // fill items
if (pPage) { rsMsgs->getMessageTagTypes(*m_pTags);
pPage->getTagItems (m_TagItems); fillTags();
// fill items
fillTagItems();
} else {
// MessagesDialog not available
ui.tags_listWidget->setEnabled(false);
ui.addpushButton->setEnabled(false);
ui.editpushButton->setEnabled(false);
ui.deletepushButton->setEnabled(false);
ui.defaultTagButton->setEnabled(false);
}
} }
// fill items // fill tags
void MessagePage::fillTagItems() void MessagePage::fillTags()
{ {
ui.tags_listWidget->clear(); ui.tags_listWidget->clear();
std::map<int, TagItem>::iterator Item; std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
for (Item = m_TagItems.begin(); Item != m_TagItems.end(); Item++) { for (Tag = m_pTags->types.begin(); Tag != m_pTags->types.end(); Tag++) {
if (Item->second._delete) { QString text;
continue; if (Tag->first < RS_MSGTAGTYPE_USER) {
text = tr(Tag->second.first.c_str());
} else {
text = QString::fromStdString(Tag->second.first);
} }
QListWidgetItem *pItemWidget = new QListWidgetItem(text, ui.tags_listWidget);
QListWidgetItem *pItemWidget = new QListWidgetItem(Item->second.text, ui.tags_listWidget); pItemWidget->setTextColor(QColor(Tag->second.second));
pItemWidget->setTextColor(QColor(Item->second.color)); pItemWidget->setData(Qt::UserRole, Tag->first);
pItemWidget->setData(Qt::UserRole, Item->first);
} }
} }
void MessagePage::addTag() void MessagePage::addTag()
{ {
NewTag Tag(m_TagItems); NewTag TagDlg(*m_pTags);
if (Tag.exec() == QDialog::Accepted && Tag.m_nId) { if (TagDlg.exec() == QDialog::Accepted && TagDlg.m_nId) {
TagItem &Item = m_TagItems [Tag.m_nId]; std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
QListWidgetItem *pItemWidget = new QListWidgetItem(Item.text, ui.tags_listWidget); Tag = m_pTags->types.find(TagDlg.m_nId);
pItemWidget->setTextColor(QColor(Item.color)); if (Tag != m_pTags->types.end()) {
pItemWidget->setData(Qt::UserRole, Tag.m_nId); QString text;
if (Tag->first < RS_MSGTAGTYPE_USER) {
text = tr(Tag->second.first.c_str());
} else {
text = QString::fromStdString(Tag->second.first);
}
QListWidgetItem *pItemWidget = new QListWidgetItem(text, ui.tags_listWidget);
pItemWidget->setTextColor(QColor(Tag->second.second));
pItemWidget->setData(Qt::UserRole, TagDlg.m_nId);
m_changedTagIds.push_back(TagDlg.m_nId);
}
} }
} }
@ -124,17 +145,26 @@ void MessagePage::editTag()
return; return;
} }
int nId = pItemWidget->data(Qt::UserRole).toInt(); uint32_t nId = pItemWidget->data(Qt::UserRole).toInt();
if (nId == 0) { if (nId == 0) {
return; return;
} }
NewTag Tag(m_TagItems, nId); NewTag TagDlg(*m_pTags, nId);
Tag.setWindowTitle(tr("Edit Tag")); TagDlg.setWindowTitle(tr("Edit Tag"));
if (Tag.exec() == QDialog::Accepted && Tag.m_nId) { if (TagDlg.exec() == QDialog::Accepted && TagDlg.m_nId) {
TagItem &Item = m_TagItems [Tag.m_nId]; std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
pItemWidget->setText(Item.text); Tag = m_pTags->types.find(TagDlg.m_nId);
pItemWidget->setTextColor(QColor(Item.color)); if (Tag != m_pTags->types.end()) {
if (Tag->first >= RS_MSGTAGTYPE_USER) {
pItemWidget->setText(QString::fromStdString(Tag->second.first));
}
pItemWidget->setTextColor(QColor(Tag->second.second));
if (std::find(m_changedTagIds.begin(), m_changedTagIds.end(), TagDlg.m_nId) == m_changedTagIds.end()) {
m_changedTagIds.push_back(TagDlg.m_nId);
}
}
} }
} }
@ -145,26 +175,46 @@ void MessagePage::deleteTag()
return; return;
} }
int nId = pItemWidget->data(Qt::UserRole).toInt(); uint32_t nId = pItemWidget->data(Qt::UserRole).toInt();
if (nId == 0) { if (nId == 0) {
return; return;
} }
if (nId < 0) { if (nId < RS_MSGTAGTYPE_USER) {
// can't delete standard tag item
return; return;
} }
TagItem &Item = m_TagItems [nId]; std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
Item._delete = true; Tag = m_pTags->types.find(nId);
if (Tag != m_pTags->types.end()) {
// erase the text for later delete
Tag->second.first.erase();
}
ui.tags_listWidget->removeItemWidget(pItemWidget); ui.tags_listWidget->removeItemWidget(pItemWidget);
delete (pItemWidget); delete (pItemWidget);
if (std::find(m_changedTagIds.begin(), m_changedTagIds.end(), nId) == m_changedTagIds.end()) {
m_changedTagIds.push_back(nId);
}
} }
void MessagePage::defaultTag() void MessagePage::defaultTag()
{ {
MessagesDialog::initStandardTagItems(m_TagItems); rsMsgs->resetMessageStandardTagTypes(*m_pTags);
fillTagItems();
// add all standard items to changed list
std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
for (Tag = m_pTags->types.begin(); Tag != m_pTags->types.end(); Tag++) {
if (Tag->first < RS_MSGTAGTYPE_USER) {
if (std::find(m_changedTagIds.begin(), m_changedTagIds.end(), Tag->first) == m_changedTagIds.end()) {
m_changedTagIds.push_back(Tag->first);
}
}
}
fillTags();
} }
void MessagePage::currentRowChangedTag(int row) void MessagePage::currentRowChangedTag(int row)
@ -177,9 +227,9 @@ void MessagePage::currentRowChangedTag(int row)
if (pItemWidget) { if (pItemWidget) {
bEditEnable = true; bEditEnable = true;
int nId = pItemWidget->data(Qt::UserRole).toInt(); uint32_t nId = pItemWidget->data(Qt::UserRole).toInt();
if (nId > 0) { if (nId >= RS_MSGTAGTYPE_USER) {
bDeleteEnable = true; bDeleteEnable = true;
} }
} }

View File

@ -27,7 +27,7 @@
#include "configpage.h" #include "configpage.h"
#include "ui_MessagePage.h" #include "ui_MessagePage.h"
#include "NewTag.h" class MsgTagType;
class MessagePage : public ConfigPage class MessagePage : public ConfigPage
{ {
@ -52,9 +52,11 @@ private slots:
private: private:
void closeEvent (QCloseEvent * event); void closeEvent (QCloseEvent * event);
void fillTagItems(); void fillTags();
std::map<int, TagItem> m_TagItems; /* Pointer for not include of rsmsgs.h */
MsgTagType *m_pTags;
std::list<uint32_t> m_changedTagIds;
Ui::MessagePage ui; Ui::MessagePage ui;
}; };

View File

@ -20,11 +20,13 @@
****************************************************************/ ****************************************************************/
#include "NewTag.h" #include "NewTag.h"
#include "retroshare/rsmsgs.h"
#include <QColorDialog> #include <QColorDialog>
/** Default constructor */ /** Default constructor */
NewTag::NewTag(std::map<int, TagItem> &Items, int nId /*= 0*/, QWidget *parent, Qt::WFlags flags) NewTag::NewTag(MsgTagType &Tags, uint32_t nId /*= 0*/, QWidget *parent, Qt::WFlags flags)
: QDialog(parent, flags), m_Items(Items) : QDialog(parent, flags), m_Tags(Tags)
{ {
/* Invoke Qt Designer generated QObject setup routine */ /* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this); ui.setupUi(this);
@ -40,13 +42,20 @@ NewTag::NewTag(std::map<int, TagItem> &Items, int nId /*= 0*/, QWidget *parent,
ui.okButton->setEnabled(false); ui.okButton->setEnabled(false);
if (m_nId) { if (m_nId) {
TagItem &Item = m_Items [m_nId]; std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
ui.lineEdit->setText(Item.text); Tag = m_Tags.types.find(m_nId);
m_Color = Item.color; if (Tag != m_Tags.types.end()) {
ui.lineEdit->setText(QString::fromStdString(Tag->second.first));
m_Color = QRgb(Tag->second.second);
if (m_nId < 0) { if (m_nId < RS_MSGTAGTYPE_USER) {
// standard tag // standard tag
ui.lineEdit->setEnabled(false); ui.lineEdit->setEnabled(false);
}
} else {
// tag id not found
m_Color = 0;
m_nId = 0;
} }
} else { } else {
m_Color = 0; m_Color = 0;
@ -62,22 +71,19 @@ void NewTag::closeEvent (QCloseEvent * event)
void NewTag::OnOK() void NewTag::OnOK()
{ {
TagItem Item;
Item.text = ui.lineEdit->text();
Item.color = m_Color;
if (m_nId == 0) { if (m_nId == 0) {
// calculate new id // calculate new id
m_nId = 1; m_nId = RS_MSGTAGTYPE_USER;
std::map<int, TagItem>::iterator Item; std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
for (Item = m_Items.begin(); Item != m_Items.end(); Item++) { for (Tag = m_Tags.types.begin(); Tag != m_Tags.types.end(); Tag++) {
if (Item->first + 1 > m_nId) { if (Tag->first + 1 > m_nId) {
m_nId = Item->first + 1; m_nId = Tag->first + 1;
} }
} }
} }
m_Items [m_nId] = Item; std::pair<std::string, uint32_t> newTag(ui.lineEdit->text().toStdString(), m_Color);
m_Tags.types [m_nId] = newTag;
setResult(QDialog::Accepted); setResult(QDialog::Accepted);
hide(); hide();
@ -92,22 +98,25 @@ void NewTag::OnCancel()
void NewTag::textChanged(const QString &text) void NewTag::textChanged(const QString &text)
{ {
bool bEnabled = true; bool bEnabled = true;
std::string stdText = text.toStdString();
if (text.isEmpty()) { if (text.isEmpty()) {
bEnabled = false; bEnabled = false;
} else { } else {
// check for existing text // check for existing text
std::map<int, TagItem>::iterator Item; std::map<uint32_t, std::pair<std::string, uint32_t> >::iterator Tag;
for (Item = m_Items.begin(); Item != m_Items.end(); Item++) { for (Tag = m_Tags.types.begin(); Tag != m_Tags.types.end(); Tag++) {
if (m_nId && Item->first == m_nId) { if (m_nId && Tag->first == m_nId) {
// its me
continue; continue;
} }
if (Item->second._delete) { if (Tag->second.first.empty()) {
// deleted
continue; continue;
} }
if (Item->second.text == text) { if (Tag->second.first == stdText) {
bEnabled = false; bEnabled = false;
break; break;
} }

View File

@ -26,19 +26,7 @@
#include "ui_NewTag.h" #include "ui_NewTag.h"
class TagItem class MsgTagType;
{
public:
TagItem()
{
_delete = false;
};
QString text;
QRgb color;
bool _delete; // for internal use
};
class NewTag : public QDialog class NewTag : public QDialog
{ {
@ -46,9 +34,9 @@ class NewTag : public QDialog
public: public:
/** Default constructor */ /** Default constructor */
NewTag(std::map<int, TagItem> &Items, int nId = 0, QWidget *parent = 0, Qt::WFlags flags = 0); NewTag(MsgTagType &Tags, uint32_t nId = 0, QWidget *parent = 0, Qt::WFlags flags = 0);
int m_nId; uint32_t m_nId;
protected: protected:
void closeEvent (QCloseEvent * event); void closeEvent (QCloseEvent * event);
@ -64,7 +52,7 @@ private slots:
private: private:
void showColor(QRgb color); void showColor(QRgb color);
std::map<int, TagItem> &m_Items; MsgTagType &m_Tags;
QRgb m_Color; QRgb m_Color;
/** Qt Designer generated object */ /** Qt Designer generated object */

View File

@ -177,6 +177,7 @@ int main(int argc, char *argv[])
QObject::connect(notify,SIGNAL(friendsChanged()) ,w->peersDialog ,SLOT(insertPeers() )) ; QObject::connect(notify,SIGNAL(friendsChanged()) ,w->peersDialog ,SLOT(insertPeers() )) ;
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(messagesChanged()) ,w ,SLOT(updateMessages() )) ; QObject::connect(notify,SIGNAL(messagesChanged()) ,w ,SLOT(updateMessages() )) ;
QObject::connect(notify,SIGNAL(forumsChanged()) ,w ,SLOT(updateForums() ), Qt::QueuedConnection); QObject::connect(notify,SIGNAL(forumsChanged()) ,w ,SLOT(updateForums() ), Qt::QueuedConnection);