mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-15 11:38:49 -07:00
implemented direct chat
This commit is contained in:
parent
a8e166b609
commit
e597325ec3
24 changed files with 821 additions and 335 deletions
|
|
@ -33,9 +33,12 @@ void AbstractClient::processProtocolItem(ProtocolItem *item)
|
|||
if (genericEvent) {
|
||||
switch (genericEvent->getItemId()) {
|
||||
case ItemId_Event_ListGames: emit listGamesEventReceived(qobject_cast<Event_ListGames *>(item)); break;
|
||||
case ItemId_Event_UserJoined: emit userJoinedEventReceived(qobject_cast<Event_UserJoined *>(item)); break;
|
||||
case ItemId_Event_UserLeft: emit userLeftEventReceived(qobject_cast<Event_UserLeft *>(item)); break;
|
||||
case ItemId_Event_ServerMessage: emit serverMessageEventReceived(qobject_cast<Event_ServerMessage *>(item)); break;
|
||||
case ItemId_Event_ListChatChannels: emit listChatChannelsEventReceived(qobject_cast<Event_ListChatChannels *>(item)); break;
|
||||
case ItemId_Event_GameJoined: emit gameJoinedEventReceived(qobject_cast<Event_GameJoined *>(item)); break;
|
||||
case ItemId_Event_Message: emit messageEventReceived(qobject_cast<Event_Message *>(item)); break;
|
||||
}
|
||||
if (genericEvent->getReceiverMayDelete())
|
||||
delete genericEvent;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,12 @@ class CommandContainer;
|
|||
class ChatEvent;
|
||||
class GameEventContainer;
|
||||
class Event_ListGames;
|
||||
class Event_UserJoined;
|
||||
class Event_UserLeft;
|
||||
class Event_ServerMessage;
|
||||
class Event_ListChatChannels;
|
||||
class Event_GameJoined;
|
||||
class Event_Message;
|
||||
|
||||
enum ClientStatus {
|
||||
StatusDisconnected,
|
||||
|
|
@ -38,9 +41,12 @@ signals:
|
|||
void gameEventContainerReceived(GameEventContainer *event);
|
||||
// Generic events
|
||||
void listGamesEventReceived(Event_ListGames *event);
|
||||
void userJoinedEventReceived(Event_UserJoined *event);
|
||||
void userLeftEventReceived(Event_UserLeft *event);
|
||||
void serverMessageEventReceived(Event_ServerMessage *event);
|
||||
void listChatChannelsEventReceived(Event_ListChatChannels *event);
|
||||
void gameJoinedEventReceived(Event_GameJoined *event);
|
||||
void messageEventReceived(Event_Message *event);
|
||||
protected slots:
|
||||
void processProtocolItem(ProtocolItem *item);
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include <QPainter>
|
||||
#include <QSvgRenderer>
|
||||
#include <math.h>
|
||||
#include <QDebug>
|
||||
|
||||
QPixmap PingPixmapGenerator::generatePixmap(int size, int value, int max)
|
||||
{
|
||||
|
|
@ -39,11 +40,13 @@ QPixmap CountryPixmapGenerator::generatePixmap(int height, const QString &countr
|
|||
return pmCache.value(key);
|
||||
|
||||
QSvgRenderer svg(QString(":/resources/countries/" + countryCode + ".svg"));
|
||||
double aspect = (double) svg.defaultSize().width() / (double) svg.defaultSize().height();
|
||||
QPixmap pixmap((int) round(aspect * height), height);
|
||||
int width = (int) round(height * (double) svg.defaultSize().width() / (double) svg.defaultSize().height());
|
||||
QPixmap pixmap(width, height);
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
svg.render(&painter, QRectF(0, 0, aspect * height, height));
|
||||
svg.render(&painter, QRectF(0, 0, width, height));
|
||||
painter.setPen(Qt::black);
|
||||
painter.drawRect(0.5, 0.5, width - 1, height - 1);
|
||||
|
||||
pmCache.insert(key, pixmap);
|
||||
return pixmap;
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ void Player::actMoveTopCardsToGrave()
|
|||
|
||||
void Player::actMoveTopCardsToExile()
|
||||
{
|
||||
int number = QInputDialog::getInteger(0, tr("Move top cards to grave"), tr("Number:"));
|
||||
int number = QInputDialog::getInteger(0, tr("Move top cards to exile"), tr("Number:"));
|
||||
if (!number)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ PlayerListWidget::PlayerListWidget(QWidget *parent)
|
|||
playerIcon = QIcon(":/resources/icon_player.svg");
|
||||
spectatorIcon = QIcon(":/resources/icon_spectator.svg");
|
||||
|
||||
setIconSize(QSize(20, 15));
|
||||
setColumnCount(5);
|
||||
setRootIsDecorated(false);
|
||||
setSelectionMode(NoSelection);
|
||||
|
|
@ -47,7 +48,7 @@ void PlayerListWidget::updatePlayerProperties(ServerInfo_PlayerProperties *prop)
|
|||
player->setIcon(2, gameStarted ? (prop->getConceded() ? concededIcon : QIcon()) : (prop->getReadyStart() ? readyIcon : notReadyIcon));
|
||||
player->setText(3, prop->getUserInfo()->getName());
|
||||
if (!prop->getUserInfo()->getCountry().isEmpty())
|
||||
player->setIcon(3, QIcon(CountryPixmapGenerator::generatePixmap(10, prop->getUserInfo()->getCountry())));
|
||||
player->setIcon(3, QIcon(CountryPixmapGenerator::generatePixmap(12, prop->getUserInfo()->getCountry())));
|
||||
|
||||
QString deckText;
|
||||
if (!prop->getSpectator())
|
||||
|
|
|
|||
|
|
@ -49,6 +49,14 @@ void TabChatChannel::retranslateUi()
|
|||
aLeaveChannel->setText(tr("&Leave channel"));
|
||||
}
|
||||
|
||||
QString TabChatChannel::sanitizeHtml(QString dirty) const
|
||||
{
|
||||
return dirty
|
||||
.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">");
|
||||
}
|
||||
|
||||
void TabChatChannel::sendMessage()
|
||||
{
|
||||
if (sayEdit->text().isEmpty())
|
||||
|
|
@ -84,14 +92,14 @@ void TabChatChannel::processListPlayersEvent(Event_ChatListPlayers *event)
|
|||
|
||||
void TabChatChannel::processJoinChannelEvent(Event_ChatJoinChannel *event)
|
||||
{
|
||||
textEdit->append(tr("%1 has joined the channel.").arg(event->getUserInfo()->getName()));
|
||||
textEdit->append(tr("%1 has joined the channel.").arg(sanitizeHtml(event->getUserInfo()->getName())));
|
||||
playerList->addItem(event->getUserInfo()->getName());
|
||||
emit userEvent();
|
||||
}
|
||||
|
||||
void TabChatChannel::processLeaveChannelEvent(Event_ChatLeaveChannel *event)
|
||||
{
|
||||
textEdit->append(tr("%1 has left the channel.").arg(event->getPlayerName()));
|
||||
textEdit->append(tr("%1 has left the channel.").arg(sanitizeHtml(event->getPlayerName())));
|
||||
for (int i = 0; i < playerList->count(); ++i)
|
||||
if (playerList->item(i)->text() == event->getPlayerName()) {
|
||||
delete playerList->takeItem(i);
|
||||
|
|
@ -103,8 +111,8 @@ void TabChatChannel::processLeaveChannelEvent(Event_ChatLeaveChannel *event)
|
|||
void TabChatChannel::processSayEvent(Event_ChatSay *event)
|
||||
{
|
||||
if (event->getPlayerName().isEmpty())
|
||||
textEdit->append(QString("<font color=\"blue\">%1</font").arg(event->getMessage()));
|
||||
textEdit->append(QString("<font color=\"blue\">%1</font").arg(sanitizeHtml(event->getMessage())));
|
||||
else
|
||||
textEdit->append(QString("<font color=\"red\">%1:</font> %2").arg(event->getPlayerName()).arg(event->getMessage()));
|
||||
textEdit->append(QString("<font color=\"red\">%1:</font> %2").arg(sanitizeHtml(event->getPlayerName())).arg(sanitizeHtml(event->getMessage())));
|
||||
emit userEvent();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ private:
|
|||
QLineEdit *sayEdit;
|
||||
|
||||
QAction *aLeaveChannel;
|
||||
QString sanitizeHtml(QString dirty) const;
|
||||
signals:
|
||||
void channelClosing(TabChatChannel *tab);
|
||||
private slots:
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include "abstractclient.h"
|
||||
#include "protocol.h"
|
||||
#include "protocol_items.h"
|
||||
#include "pixmapgenerator.h"
|
||||
#include <QDebug>
|
||||
|
||||
GameSelector::GameSelector(AbstractClient *_client, QWidget *parent)
|
||||
: QGroupBox(parent), client(_client)
|
||||
|
|
@ -235,23 +237,116 @@ void ServerMessageLog::processServerMessageEvent(Event_ServerMessage *event)
|
|||
textEdit->append(event->getMessage());
|
||||
}
|
||||
|
||||
UserList::UserList(AbstractClient *_client, QWidget *parent)
|
||||
: QGroupBox(parent)
|
||||
{
|
||||
userTree = new QTreeWidget;
|
||||
userTree->setColumnCount(2);
|
||||
userTree->header()->setResizeMode(QHeaderView::ResizeToContents);
|
||||
userTree->setHeaderHidden(true);
|
||||
userTree->setRootIsDecorated(false);
|
||||
userTree->setIconSize(QSize(20, 12));
|
||||
connect(userTree, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(userClicked(QTreeWidgetItem *, int)));
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(userTree);
|
||||
|
||||
setLayout(vbox);
|
||||
|
||||
retranslateUi();
|
||||
|
||||
connect(_client, SIGNAL(userJoinedEventReceived(Event_UserJoined *)), this, SLOT(processUserJoinedEvent(Event_UserJoined *)));
|
||||
connect(_client, SIGNAL(userLeftEventReceived(Event_UserLeft *)), this, SLOT(processUserLeftEvent(Event_UserLeft *)));
|
||||
|
||||
Command_ListUsers *cmd = new Command_ListUsers;
|
||||
connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processResponse(ProtocolResponse *)));
|
||||
_client->sendCommand(cmd);
|
||||
}
|
||||
|
||||
void UserList::retranslateUi()
|
||||
{
|
||||
setTitle(tr("Users online: %1").arg(userTree->topLevelItemCount()));
|
||||
}
|
||||
|
||||
void UserList::processUserInfo(ServerInfo_User *user)
|
||||
{
|
||||
QTreeWidgetItem *item = 0;
|
||||
for (int i = 0; i < userTree->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *temp = userTree->topLevelItem(i);
|
||||
if (temp->data(1, Qt::UserRole) == user->getName()) {
|
||||
item = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!item) {
|
||||
item = new QTreeWidgetItem;
|
||||
userTree->addTopLevelItem(item);
|
||||
retranslateUi();
|
||||
}
|
||||
item->setIcon(0, QIcon(CountryPixmapGenerator::generatePixmap(12, user->getCountry())));
|
||||
item->setData(1, Qt::UserRole, user->getName());
|
||||
item->setData(1, Qt::DisplayRole, user->getName());
|
||||
}
|
||||
|
||||
void UserList::processResponse(ProtocolResponse *response)
|
||||
{
|
||||
Response_ListUsers *resp = qobject_cast<Response_ListUsers *>(response);
|
||||
if (!resp)
|
||||
return;
|
||||
|
||||
const QList<ServerInfo_User *> &respList = resp->getUserList();
|
||||
for (int i = 0; i < respList.size(); ++i)
|
||||
processUserInfo(respList[i]);
|
||||
|
||||
userTree->sortItems(1, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
void UserList::processUserJoinedEvent(Event_UserJoined *event)
|
||||
{
|
||||
processUserInfo(event->getUserInfo());
|
||||
userTree->sortItems(1, Qt::AscendingOrder);
|
||||
}
|
||||
|
||||
void UserList::processUserLeftEvent(Event_UserLeft *event)
|
||||
{
|
||||
for (int i = 0; i < userTree->topLevelItemCount(); ++i)
|
||||
if (userTree->topLevelItem(i)->data(1, Qt::UserRole) == event->getUserName()) {
|
||||
emit userLeft(event->getUserName());
|
||||
delete userTree->takeTopLevelItem(i);
|
||||
retranslateUi();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UserList::userClicked(QTreeWidgetItem *item, int /*column*/)
|
||||
{
|
||||
emit openMessageDialog(item->data(1, Qt::UserRole).toString(), true);
|
||||
}
|
||||
|
||||
TabServer::TabServer(AbstractClient *_client, QWidget *parent)
|
||||
: Tab(parent), client(_client)
|
||||
{
|
||||
gameSelector = new GameSelector(client);
|
||||
chatChannelSelector = new ChatChannelSelector(client);
|
||||
serverMessageLog = new ServerMessageLog(client);
|
||||
userList = new UserList(client);
|
||||
|
||||
connect(gameSelector, SIGNAL(gameJoined(int)), this, SIGNAL(gameJoined(int)));
|
||||
connect(chatChannelSelector, SIGNAL(channelJoined(const QString &)), this, SIGNAL(chatChannelJoined(const QString &)));
|
||||
connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool)));
|
||||
connect(userList, SIGNAL(userLeft(const QString &)), this, SIGNAL(userLeft(const QString &)));
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout;
|
||||
hbox->addWidget(chatChannelSelector);
|
||||
hbox->addWidget(serverMessageLog);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(gameSelector);
|
||||
mainLayout->addLayout(hbox);
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(gameSelector);
|
||||
vbox->addLayout(hbox);
|
||||
|
||||
QHBoxLayout *mainLayout = new QHBoxLayout;
|
||||
mainLayout->addLayout(vbox, 3);
|
||||
mainLayout->addWidget(userList, 1);
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
|
|
@ -261,4 +356,5 @@ void TabServer::retranslateUi()
|
|||
gameSelector->retranslateUi();
|
||||
chatChannelSelector->retranslateUi();
|
||||
serverMessageLog->retranslateUi();
|
||||
userList->retranslateUi();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
class AbstractClient;
|
||||
class QTreeView;
|
||||
class QTreeWidget;
|
||||
class QTreeWidgetItem;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
class QTextEdit;
|
||||
|
|
@ -18,6 +19,9 @@ class GamesProxyModel;
|
|||
class Event_ListGames;
|
||||
class Event_ListChatChannels;
|
||||
class Event_ServerMessage;
|
||||
class Event_UserJoined;
|
||||
class Event_UserLeft;
|
||||
class ProtocolResponse;
|
||||
|
||||
class GameSelector : public QGroupBox {
|
||||
Q_OBJECT
|
||||
|
|
@ -72,16 +76,37 @@ public:
|
|||
void retranslateUi();
|
||||
};
|
||||
|
||||
class UserList : public QGroupBox {
|
||||
Q_OBJECT
|
||||
private:
|
||||
QTreeWidget *userTree;
|
||||
void processUserInfo(ServerInfo_User *user);
|
||||
private slots:
|
||||
void processResponse(ProtocolResponse *response);
|
||||
void processUserJoinedEvent(Event_UserJoined *event);
|
||||
void processUserLeftEvent(Event_UserLeft *event);
|
||||
void userClicked(QTreeWidgetItem *item, int column);
|
||||
signals:
|
||||
void openMessageDialog(const QString &userName, bool focus);
|
||||
void userLeft(const QString &userName);
|
||||
public:
|
||||
UserList(AbstractClient *_client, QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
};
|
||||
|
||||
class TabServer : public Tab {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void chatChannelJoined(const QString &channelName);
|
||||
void gameJoined(int gameId);
|
||||
void openMessageDialog(const QString &userName, bool focus);
|
||||
void userLeft(const QString &userName);
|
||||
private:
|
||||
AbstractClient *client;
|
||||
GameSelector *gameSelector;
|
||||
ChatChannelSelector *chatChannelSelector;
|
||||
ServerMessageLog *serverMessageLog;
|
||||
UserList *userList;
|
||||
public:
|
||||
TabServer(AbstractClient *_client, QWidget *parent = 0);
|
||||
void retranslateUi();
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "tab_chatchannel.h"
|
||||
#include "tab_game.h"
|
||||
#include "tab_deck_storage.h"
|
||||
#include "tab_message.h"
|
||||
#include "protocol_items.h"
|
||||
#include "pixmapgenerator.h"
|
||||
#include <QDebug>
|
||||
|
|
@ -56,10 +57,13 @@ void TabSupervisor::start(AbstractClient *_client)
|
|||
connect(client, SIGNAL(chatEventReceived(ChatEvent *)), this, SLOT(processChatEvent(ChatEvent *)));
|
||||
connect(client, SIGNAL(gameEventContainerReceived(GameEventContainer *)), this, SLOT(processGameEventContainer(GameEventContainer *)));
|
||||
connect(client, SIGNAL(gameJoinedEventReceived(Event_GameJoined *)), this, SLOT(gameJoined(Event_GameJoined *)));
|
||||
connect(client, SIGNAL(messageEventReceived(Event_Message *)), this, SLOT(processMessageEvent(Event_Message *)));
|
||||
connect(client, SIGNAL(maxPingTime(int, int)), this, SLOT(updatePingTime(int, int)));
|
||||
|
||||
tabServer = new TabServer(client);
|
||||
connect(tabServer, SIGNAL(chatChannelJoined(const QString &)), this, SLOT(addChatChannelTab(const QString &)));
|
||||
connect(tabServer, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool)));
|
||||
connect(tabServer, SIGNAL(userLeft(const QString &)), this, SLOT(processUserLeft(const QString &)));
|
||||
myAddTab(tabServer);
|
||||
updatePingTime(0, -1);
|
||||
|
||||
|
|
@ -173,6 +177,25 @@ void TabSupervisor::chatChannelLeft(TabChatChannel *tab)
|
|||
removeTab(indexOf(tab));
|
||||
}
|
||||
|
||||
TabMessage *TabSupervisor::addMessageTab(const QString &userName, bool focus)
|
||||
{
|
||||
TabMessage *tab = new TabMessage(client, userName);
|
||||
connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *)));
|
||||
myAddTab(tab);
|
||||
messageTabs.insert(userName, tab);
|
||||
if (focus)
|
||||
setCurrentWidget(tab);
|
||||
return tab;
|
||||
}
|
||||
|
||||
void TabSupervisor::talkLeft(TabMessage *tab)
|
||||
{
|
||||
emit setMenu(0);
|
||||
|
||||
messageTabs.remove(tab->getUserName());
|
||||
removeTab(indexOf(tab));
|
||||
}
|
||||
|
||||
void TabSupervisor::tabUserEvent()
|
||||
{
|
||||
Tab *tab = static_cast<Tab *>(sender());
|
||||
|
|
@ -200,6 +223,23 @@ void TabSupervisor::processGameEventContainer(GameEventContainer *cont)
|
|||
qDebug() << "gameEvent: invalid gameId";
|
||||
}
|
||||
|
||||
void TabSupervisor::processMessageEvent(Event_Message *event)
|
||||
{
|
||||
TabMessage *tab = messageTabs.value(event->getSenderName());
|
||||
if (!tab)
|
||||
tab = messageTabs.value(event->getReceiverName());
|
||||
if (!tab)
|
||||
tab = addMessageTab(event->getSenderName(), false);
|
||||
tab->processMessageEvent(event);
|
||||
}
|
||||
|
||||
void TabSupervisor::processUserLeft(const QString &userName)
|
||||
{
|
||||
TabMessage *tab = messageTabs.value(userName);
|
||||
if (tab)
|
||||
tab->processUserLeft(userName);
|
||||
}
|
||||
|
||||
void TabSupervisor::updateCurrent(int index)
|
||||
{
|
||||
if (index != -1) {
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@ class TabServer;
|
|||
class TabChatChannel;
|
||||
class TabGame;
|
||||
class TabDeckStorage;
|
||||
class TabMessage;
|
||||
class ChatEvent;
|
||||
class GameEventContainer;
|
||||
class Event_GameJoined;
|
||||
class Event_Message;
|
||||
|
||||
class TabSupervisor : public QTabWidget {
|
||||
Q_OBJECT
|
||||
|
|
@ -25,6 +27,7 @@ private:
|
|||
TabDeckStorage *tabDeckStorage;
|
||||
QMap<QString, TabChatChannel *> chatChannelTabs;
|
||||
QMap<int, TabGame *> gameTabs;
|
||||
QMap<QString, TabMessage *> messageTabs;
|
||||
void myAddTab(Tab *tab);
|
||||
public:
|
||||
TabSupervisor(QWidget *parent = 0);
|
||||
|
|
@ -45,9 +48,13 @@ private slots:
|
|||
void gameLeft(TabGame *tab);
|
||||
void addChatChannelTab(const QString &channelName);
|
||||
void chatChannelLeft(TabChatChannel *tab);
|
||||
TabMessage *addMessageTab(const QString &userName, bool focus);
|
||||
void processUserLeft(const QString &userName);
|
||||
void talkLeft(TabMessage *tab);
|
||||
void tabUserEvent();
|
||||
void processChatEvent(ChatEvent *event);
|
||||
void processGameEventContainer(GameEventContainer *cont);
|
||||
void processMessageEvent(Event_Message *event);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue