1 #include "tab_message.h"
2 
3 #include "abstractclient.h"
4 #include "chatview/chatview.h"
5 #include "customlineedit.h"
6 #include "main.h"
7 #include "pb/event_user_message.pb.h"
8 #include "pb/serverinfo_user.pb.h"
9 #include "pb/session_commands.pb.h"
10 #include "pending_command.h"
11 #include "settingscache.h"
12 #include "soundengine.h"
13 
14 #include <QApplication>
15 #include <QDebug>
16 #include <QMenu>
17 #include <QSystemTrayIcon>
18 #include <QVBoxLayout>
19 
TabMessage(TabSupervisor * _tabSupervisor,AbstractClient * _client,const ServerInfo_User & _ownUserInfo,const ServerInfo_User & _otherUserInfo)20 TabMessage::TabMessage(TabSupervisor *_tabSupervisor,
21                        AbstractClient *_client,
22                        const ServerInfo_User &_ownUserInfo,
23                        const ServerInfo_User &_otherUserInfo)
24     : Tab(_tabSupervisor), client(_client), ownUserInfo(new ServerInfo_User(_ownUserInfo)),
25       otherUserInfo(new ServerInfo_User(_otherUserInfo)), userOnline(true)
26 {
27     chatView = new ChatView(tabSupervisor, tabSupervisor, 0, true);
28     connect(chatView, SIGNAL(showCardInfoPopup(QPoint, QString)), this, SLOT(showCardInfoPopup(QPoint, QString)));
29     connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
30     connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
31     sayEdit = new LineEditUnfocusable;
32     connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
33 
34     QVBoxLayout *vbox = new QVBoxLayout;
35     vbox->addWidget(chatView);
36     vbox->addWidget(sayEdit);
37 
38     aLeave = new QAction(this);
39     connect(aLeave, SIGNAL(triggered()), this, SLOT(actLeave()));
40 
41     messageMenu = new QMenu(this);
42     messageMenu->addAction(aLeave);
43     addTabMenu(messageMenu);
44 
45     retranslateUi();
46 
47     QWidget *mainWidget = new QWidget(this);
48     mainWidget->setLayout(vbox);
49     setCentralWidget(mainWidget);
50 }
51 
~TabMessage()52 TabMessage::~TabMessage()
53 {
54     emit talkClosing(this);
55     delete ownUserInfo;
56     delete otherUserInfo;
57 }
58 
addMentionTag(QString mentionTag)59 void TabMessage::addMentionTag(QString mentionTag)
60 {
61     sayEdit->insert(mentionTag + " ");
62     sayEdit->setFocus();
63 }
64 
retranslateUi()65 void TabMessage::retranslateUi()
66 {
67     messageMenu->setTitle(tr("Private &chat"));
68     aLeave->setText(tr("&Leave"));
69 }
70 
tabActivated()71 void TabMessage::tabActivated()
72 {
73     if (!sayEdit->hasFocus())
74         sayEdit->setFocus();
75 }
76 
getUserName() const77 QString TabMessage::getUserName() const
78 {
79     return QString::fromStdString(otherUserInfo->name());
80 }
81 
getTabText() const82 QString TabMessage::getTabText() const
83 {
84     return tr("%1 - Private chat").arg(QString::fromStdString(otherUserInfo->name()));
85 }
86 
closeRequest()87 void TabMessage::closeRequest()
88 {
89     actLeave();
90 }
91 
sendMessage()92 void TabMessage::sendMessage()
93 {
94     if (sayEdit->text().isEmpty() || !userOnline)
95         return;
96 
97     Command_Message cmd;
98     cmd.set_user_name(otherUserInfo->name());
99     cmd.set_message(sayEdit->text().toStdString());
100 
101     PendingCommand *pend = client->prepareSessionCommand(cmd);
102     connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(messageSent(const Response &)));
103     client->sendCommand(pend);
104 
105     sayEdit->clear();
106 }
107 
messageSent(const Response & response)108 void TabMessage::messageSent(const Response &response)
109 {
110     if (response.response_code() == Response::RespInIgnoreList)
111         chatView->appendMessage(tr(
112             "This user is ignoring you, they cannot see your messages in main chat and you cannot join their games."));
113 }
114 
actLeave()115 void TabMessage::actLeave()
116 {
117     deleteLater();
118 }
119 
processUserMessageEvent(const Event_UserMessage & event)120 void TabMessage::processUserMessageEvent(const Event_UserMessage &event)
121 {
122     auto userInfo = event.sender_name() == otherUserInfo->name() ? otherUserInfo : ownUserInfo;
123     const UserLevelFlags userLevel(userInfo->user_level());
124     const QString userPriv = QString::fromStdString(userInfo->privlevel());
125 
126     chatView->appendMessage(QString::fromStdString(event.message()), {}, QString::fromStdString(event.sender_name()),
127                             userLevel, userPriv, true);
128     if (tabSupervisor->currentIndex() != tabSupervisor->indexOf(this))
129         soundEngine->playSound("private_message");
130     if (SettingsCache::instance().getShowMessagePopup() && shouldShowSystemPopup(event))
131         showSystemPopup(event);
132     if (QString::fromStdString(event.sender_name()).toLower().simplified() == "servatrice")
133         sayEdit->setDisabled(true);
134 
135     emit userEvent();
136 }
137 
shouldShowSystemPopup(const Event_UserMessage & event)138 bool TabMessage::shouldShowSystemPopup(const Event_UserMessage &event)
139 {
140     return (QApplication::activeWindow() == 0 || QApplication::focusWidget() == 0 ||
141             (event.sender_name() == otherUserInfo->name() &&
142              tabSupervisor->currentIndex() != tabSupervisor->indexOf(this)));
143 }
144 
showSystemPopup(const Event_UserMessage & event)145 void TabMessage::showSystemPopup(const Event_UserMessage &event)
146 {
147     if (trayIcon) {
148         disconnect(trayIcon, SIGNAL(messageClicked()), 0, 0);
149         trayIcon->showMessage(tr("Private message from") + " " + otherUserInfo->name().c_str(),
150                               event.message().c_str());
151         connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
152     } else {
153         qDebug() << "Error: trayIcon is NULL. TabMessage::showSystemPopup failed";
154     }
155 }
156 
messageClicked()157 void TabMessage::messageClicked()
158 {
159     tabSupervisor->setCurrentIndex(tabSupervisor->indexOf(this));
160     QApplication::setActiveWindow(this);
161     emit maximizeClient();
162 }
163 
processUserLeft()164 void TabMessage::processUserLeft()
165 {
166     chatView->appendMessage(tr("%1 has left the server.").arg(QString::fromStdString(otherUserInfo->name())));
167     userOnline = false;
168 }
169 
processUserJoined(const ServerInfo_User & _userInfo)170 void TabMessage::processUserJoined(const ServerInfo_User &_userInfo)
171 {
172     chatView->appendMessage(tr("%1 has joined the server.").arg(QString::fromStdString(otherUserInfo->name())));
173     userOnline = true;
174     *otherUserInfo = _userInfo;
175 }
176