new notify capability of chat lobbies: message counting, nickname occurrence counting and specific text counting. Also sorts out notify tab in Settings (Patch from Phenom, slightly modified: gui layout/text + added a flag to enable/disable user defined text grep)

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8082 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2015-03-26 22:17:48 +00:00
parent 9d2b6faf9c
commit e40460bdcc
18 changed files with 1045 additions and 392 deletions

View file

@ -19,23 +19,77 @@
* Boston, MA 02110-1301, USA.
****************************************************************/
#include <QTime>
#include <QMenu>
#include "ChatLobbyUserNotify.h"
#include "gui/notifyqt.h"
#include "gui/MainWindow.h"
#include "gui/ChatLobbyWidget.h"
#include "gui/settings/rsharesettings.h"
#include "util/DateTime.h"
#include <retroshare/rsidentity.h>
ChatLobbyUserNotify::ChatLobbyUserNotify(QObject *parent) :
UserNotify(parent)
{
_name = tr("Chat Lobbies");
_group = "ChatLobby";
_bCheckForNickName = Settings->valueFromGroup(_group, "CheckForNickName", true).toBool();
_bCountUnRead = Settings->valueFromGroup(_group, "CountUnRead", true).toBool();
_bCountSpecificText = Settings->valueFromGroup(_group, "CountSpecificText").toBool();
_textToNotify = Settings->valueFromGroup(_group, "TextToNotify").toStringList();
}
bool ChatLobbyUserNotify::hasSetting(QString *name, QString *group)
{
if (name) *name = tr("Chat Lobbies");
if (group) *group = "ChatLobby";
if (name) *name = _name;
if (group) *group = _group;
return true;
}
void ChatLobbyUserNotify::setCheckForNickName(bool value)
{
if (_bCheckForNickName != value) {
_bCheckForNickName = value;
Settings->setValueToGroup(_group, "CheckForNickName", value);
}
}
void ChatLobbyUserNotify::setCountUnRead(bool value)
{
if (_bCountUnRead != value) {
_bCountUnRead = value;
Settings->setValueToGroup(_group, "CountUnRead", value);
}
}
void ChatLobbyUserNotify::setCountSpecificText(bool value)
{
if (_bCountSpecificText != value) {
_bCountSpecificText = value;
Settings->setValueToGroup(_group, "CountSpecificText", value);
}
}
void ChatLobbyUserNotify::setTextToNotify(QStringList value)
{
if (_textToNotify != value) {
_textToNotify = value;
Settings->setValueToGroup(_group, "TextToNotify", value);
}
}
void ChatLobbyUserNotify::setTextToNotify(QString value)
{
QRegExp regExp("([ ~!@#$%^&*()_+{}|:\"<>?,./;'[\\]\\\\\\-=\\t\\n\\r])"); //RegExp for End of Word
QStringList list = value.split(regExp);
QString newValue = list.join("\n");
while(newValue.contains("\n\n")) newValue.replace("\n\n","\n");
list = newValue.split("\n");
setTextToNotify(list);
}
QIcon ChatLobbyUserNotify::getIcon()
{
return QIcon(":/images/chat_32.png");
@ -48,17 +102,229 @@ QIcon ChatLobbyUserNotify::getMainIcon(bool hasNew)
unsigned int ChatLobbyUserNotify::getNewCount()
{
return mUnreadCount;
int iNum=0;
for (lobby_map::iterator itCL=_listMsg.begin(); itCL!=_listMsg.end(); ++itCL) {
iNum+=itCL->second.size();
if (itCL->second.size()==0) _listMsg.erase(itCL);
}
return iNum;
}
QString ChatLobbyUserNotify::getTrayMessage(bool plural)
{
return plural ? tr("You have %1 new messages") : tr("You have %1 new message");
}
QString ChatLobbyUserNotify::getNotifyMessage(bool plural)
{
return plural ? tr("%1 new messages") : tr("%1 new message");
}
void ChatLobbyUserNotify::iconClicked()
{
MainWindow::showWindow(MainWindow::ChatLobby);
/// Tray icon Menu ///
QMenu* trayMenu = new QMenu(MainWindow::getInstance());
std::list<ChatLobbyId> lobbies;
rsMsgs->getChatLobbyList(lobbies);
bool doUpdate=false;
for (lobby_map::iterator itCL=_listMsg.begin(); itCL!=_listMsg.end();++itCL) {
/// Create a menu per lobby ///
bool bFound=false;
QString strLobbyName=tr("Unknown Lobby");
QIcon icoLobby=QIcon();
std::list<ChatLobbyId>::const_iterator lobbyIt;
for (lobbyIt = lobbies.begin(); lobbyIt != lobbies.end(); ++lobbyIt) {
ChatLobbyId clId = *lobbyIt;
if (clId==itCL->first) {
ChatLobbyInfo clInfo;
if (rsMsgs->getChatLobbyInfo(clId,clInfo))
strLobbyName=QString::fromUtf8(clInfo.lobby_name.c_str()) ;
icoLobby=(clInfo.lobby_flags & RS_CHAT_LOBBY_FLAGS_PUBLIC) ? QIcon(":/images/chat_red24.png") : QIcon(":/images/chat_x24.png");
bFound=true;
break;
}
}
if (bFound){
makeSubMenu(trayMenu, icoLobby, strLobbyName, itCL->first);
} else {
_listMsg.erase(itCL);
doUpdate=true;
}
}
if (notifyCombined()) {
QSystemTrayIcon* trayIcon=getTrayIcon();
if (trayIcon!=NULL) trayIcon->setContextMenu(trayMenu);
} else {
QAction* action=getNotifyIcon();
if (action!=NULL) {
action->setMenu(trayMenu);
}
}
QString strName=tr("Remove All");
QAction *pAction = new QAction( QIcon(), strName, trayMenu);
ActionTag actionTag={0x0, "", true};
pAction->setData(qVariantFromValue(actionTag));
connect(trayMenu, SIGNAL(triggered(QAction*)), this, SLOT(subMenuClicked(QAction*)));
connect(trayMenu, SIGNAL(hovered(QAction*)), this, SLOT(subMenuHovered(QAction*)));
trayMenu->addAction(pAction);
trayMenu->exec(QCursor::pos());
if (doUpdate) updateIcon();
}
void ChatLobbyUserNotify::unreadCountChanged(unsigned int unreadCount)
void ChatLobbyUserNotify::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString strLobbyName, ChatLobbyId id)
{
mUnreadCount = unreadCount;
lobby_map::iterator itCL=_listMsg.find(id);
if (itCL==_listMsg.end()) return;
msg_map msgMap = itCL->second;
unsigned int msgCount=msgMap.size();
if(!parentMenu) parentMenu = new QMenu(MainWindow::getInstance());
QMenu *lobbyMenu = parentMenu->addMenu(icoLobby, strLobbyName);
connect(lobbyMenu, SIGNAL(triggered(QAction*)), this, SLOT(subMenuClicked(QAction*)));
connect(lobbyMenu, SIGNAL(hovered(QAction*)), this, SLOT(subMenuHovered(QAction*)));
lobbyMenu->setToolTip(getNotifyMessage(msgCount>1).arg(msgCount));
for (msg_map::iterator itMsg=msgMap.begin(); itMsg!=msgMap.end(); ++itMsg) {
/// initialize menu ///
QString strName=itMsg->first;
MsgData msgData=itMsg->second;
QTextDocument doc;
doc.setHtml(msgData.text);
strName.append(":").append(doc.toPlainText().left(30).replace(QString("\n"),QString(" ")));
QAction *pAction = new QAction( icoLobby, strName, lobbyMenu);
pAction->setToolTip(doc.toPlainText());
ActionTag actionTag={itCL->first, itMsg->first, false};
pAction->setData(qVariantFromValue(actionTag));
lobbyMenu->addAction(pAction);
}
QString strName=tr("Remove All");
QAction *pAction = new QAction( icoLobby, strName, lobbyMenu);
ActionTag actionTag={itCL->first, "", true};
pAction->setData(qVariantFromValue(actionTag));
lobbyMenu->addAction(pAction);
}
void ChatLobbyUserNotify::iconHovered()
{
iconClicked();
}
void ChatLobbyUserNotify::chatLobbyNewMessage(ChatLobbyId lobby_id, QDateTime time, QString senderName, QString msg)
{
bool bGetNickName = false;
if (_bCheckForNickName) {
RsGxsId gxs_id;
rsMsgs->getIdentityForChatLobby(lobby_id,gxs_id);
RsIdentityDetails details ;
rsIdentity->getIdDetails(gxs_id,details) ;
bGetNickName = checkWord(msg, QString::fromUtf8(details.mNickname.c_str()));
}
bool bFoundTextToNotify = false;
if(_bCountSpecificText)
for (QStringList::Iterator it = _textToNotify.begin(); it != _textToNotify.end(); ++it) {
bFoundTextToNotify |= checkWord(msg, (*it));
}
if ((bGetNickName || bFoundTextToNotify || _bCountUnRead)){
QString strAnchor = time.toString(Qt::ISODate);
strAnchor.append("_").append(senderName);
MsgData msgData;
msgData.text=msg;
msgData.unread=!(bGetNickName || bFoundTextToNotify);
_listMsg[lobby_id][strAnchor]=msgData;
emit countChanged(lobby_id, _listMsg[lobby_id].size());
updateIcon();
}
}
bool ChatLobbyUserNotify::checkWord(QString message, QString word)
{
bool bFound = false;
int nFound = -1;
if (((nFound=message.indexOf(word)) != -1)
&& (!word.isEmpty())) {
QString eow=" ~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="; // end of word
bool bFirstCharEOW = (nFound==0)?true:(eow.indexOf(message.at(nFound-1)) != -1);
bool bLastCharEOW = ((nFound+word.length()-1) < message.length())
?(eow.indexOf(message.at(nFound+word.length())) != -1)
:true;
bFound = (bFirstCharEOW && bLastCharEOW);
}
return bFound;
}
void ChatLobbyUserNotify::chatLobbyCleared(ChatLobbyId lobby_id, QString anchor, bool onlyUnread /*=false*/)
{
bool changed = anchor.isEmpty();
unsigned int count=0;
if (lobby_id==0) return;
lobby_map::iterator itCL=_listMsg.find(lobby_id);
if (itCL!=_listMsg.end()) {
if (!anchor.isEmpty()) {
msg_map::iterator itMsg=itCL->second.find(anchor);
if (itMsg!=itCL->second.end()) {
MsgData msgData = itMsg->second;
if(!onlyUnread || msgData.unread) {
itCL->second.erase(itMsg);
changed=true;
}
}
count = itCL->second.size();
}
if (count==0) _listMsg.erase(itCL);
}
if (changed) emit countChanged(lobby_id, count);
updateIcon();
}
void ChatLobbyUserNotify::subMenuClicked(QAction* action)
{
ActionTag actionTag=action->data().value<ActionTag>();
if(!actionTag.removeALL){
MainWindow::showWindow(MainWindow::ChatLobby);
ChatLobbyWidget *chatLobbyWidget = dynamic_cast<ChatLobbyWidget*>(MainWindow::getPage(MainWindow::ChatLobby));
if (chatLobbyWidget) chatLobbyWidget->showLobbyAnchor(actionTag.cli ,actionTag.timeStamp);
}
lobby_map::iterator itCL=_listMsg.find(actionTag.cli);
if (itCL!=_listMsg.end()) {
unsigned int count=0;
if(!actionTag.removeALL){
msg_map::iterator itMsg=itCL->second.find(actionTag.timeStamp);
if (itMsg!=itCL->second.end()) itCL->second.erase(itMsg);
count = itCL->second.size();
}
if (count==0) _listMsg.erase(itCL);
emit countChanged(actionTag.cli, count);
} else if(actionTag.cli==0x0){
for(itCL=_listMsg.begin();itCL!=_listMsg.end();++itCL){
emit countChanged(itCL->first, 0);
_listMsg.erase(itCL);
}
}
QMenu *lobbyMenu=dynamic_cast<QMenu*>(action->parent());
if (lobbyMenu) lobbyMenu->removeAction(action);
updateIcon();
}
void ChatLobbyUserNotify::subMenuHovered(QAction* action)
{
QMenu *lobbyMenu=dynamic_cast<QMenu*>(action->parent());
if (lobbyMenu) lobbyMenu->setToolTip(action->toolTip());
}