mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-10 06:59:42 -05:00
364 lines
12 KiB
C++
364 lines
12 KiB
C++
/*******************************************************************************
|
|
* gui/chat/ChatLobbyUserNotify.cpp *
|
|
* *
|
|
* LibResAPI: API for local socket server *
|
|
* *
|
|
* Copyright (C) 2014 Retroshare Team <retroshare.project@gmail.com> *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Affero General Public License as *
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Affero General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Affero General Public License *
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
* *
|
|
*******************************************************************************/
|
|
|
|
#include <QTime>
|
|
#include <QMenu>
|
|
|
|
#include "gui/common/FilesDefs.h"
|
|
#include "ChatLobbyUserNotify.h"
|
|
|
|
#include "gui/ChatLobbyWidget.h"
|
|
#include "gui/MainWindow.h"
|
|
#include "gui/notifyqt.h"
|
|
#include "gui/SoundManager.h"
|
|
#include "gui/settings/rsharesettings.h"
|
|
#include "util/DateTime.h"
|
|
#include <util/HandleRichText.h>
|
|
|
|
#include <retroshare/rsidentity.h>
|
|
|
|
ChatLobbyUserNotify::ChatLobbyUserNotify(QObject *parent) :
|
|
UserNotify(parent)
|
|
{
|
|
_name = tr("Chats");
|
|
_group = "ChatLobby";
|
|
|
|
_bCheckForNickName = Settings->valueFromGroup(_group, "CheckForNickName", true).toBool();
|
|
_bCountUnRead = Settings->valueFromGroup(_group, "CountUnRead", true).toBool();
|
|
_bCountSpecificText = Settings->valueFromGroup(_group, "CountSpecificText", false).toBool();
|
|
_textToNotify = Settings->valueFromGroup(_group, "TextToNotify").toStringList();
|
|
_bTextCaseSensitive = Settings->valueFromGroup(_group, "TextCaseSensitive", false).toBool();
|
|
}
|
|
|
|
bool ChatLobbyUserNotify::hasSetting(QString *name, QString *group)
|
|
{
|
|
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)
|
|
{
|
|
while(value.contains("\n\n")) value.replace("\n\n","\n");
|
|
QStringList list = value.split("\n");
|
|
setTextToNotify(list);
|
|
}
|
|
|
|
void ChatLobbyUserNotify::setTextCaseSensitive(bool value)
|
|
{
|
|
if (_bTextCaseSensitive != value) {
|
|
_bTextCaseSensitive = value;
|
|
Settings->setValueToGroup(_group, "TextCaseSensitive", value);
|
|
}
|
|
}
|
|
|
|
QIcon ChatLobbyUserNotify::getIcon()
|
|
{
|
|
return FilesDefs::getIconFromQtResourcePath(":/icons/png/chat-lobbies.png");
|
|
}
|
|
|
|
QIcon ChatLobbyUserNotify::getMainIcon(bool hasNew)
|
|
{
|
|
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/chat-lobbies-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/chat-lobbies.png");
|
|
}
|
|
|
|
unsigned int ChatLobbyUserNotify::getNewCount()
|
|
{
|
|
int iNum=0;
|
|
for (lobby_map::iterator itCL=_listMsg.begin(); itCL!=_listMsg.end();)
|
|
{
|
|
iNum+=itCL->second.size();
|
|
|
|
if (itCL->second.size()==0)
|
|
{
|
|
lobby_map::iterator ittmp = itCL ;
|
|
++ittmp ;
|
|
|
|
_listMsg.erase(itCL);
|
|
itCL = ittmp ;
|
|
}
|
|
else
|
|
++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()
|
|
{
|
|
/// 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();)
|
|
{
|
|
/// 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) ? FilesDefs::getIconFromQtResourcePath(":/images/chat_red24.png") : FilesDefs::getIconFromQtResourcePath(":/images/chat_x24.png");
|
|
bFound=true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bFound)
|
|
{
|
|
makeSubMenu(trayMenu, icoLobby, strLobbyName, itCL->first);
|
|
++itCL ;
|
|
}
|
|
else
|
|
{
|
|
lobby_map::iterator ittmp(itCL);
|
|
++ittmp ;
|
|
_listMsg.erase(itCL);
|
|
itCL=ittmp ;
|
|
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::makeSubMenu(QMenu* parentMenu, QIcon icoLobby, QString strLobbyName, ChatLobbyId id)
|
|
{
|
|
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);
|
|
MsgData msgData;
|
|
msgData.text=RsHtml::plainText(senderName) + ": " + msg;
|
|
msgData.unread=!(bGetNickName || bFoundTextToNotify);
|
|
|
|
_listMsg[lobby_id][strAnchor]=msgData;
|
|
emit countChanged(lobby_id, _listMsg[lobby_id].size());
|
|
updateIcon();
|
|
SoundManager::play(SOUND_NEW_LOBBY_MESSAGE);
|
|
}
|
|
}
|
|
|
|
bool ChatLobbyUserNotify::checkWord(QString message, QString word)
|
|
{
|
|
bool bFound = false;
|
|
int nFound = -1;
|
|
if (((nFound=message.indexOf(word,0,_bTextCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)) != -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() < 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){
|
|
while (!_listMsg.empty()) {
|
|
itCL = _listMsg.begin();
|
|
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());
|
|
}
|