From 9e34c9c985a0035f41e35d201e5fbd4bf667ebc9 Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Mon, 28 Feb 2011 20:44:03 +0100 Subject: [PATCH] more buddy list & ignore list code --- cockatrice/cockatrice.pro | 2 + cockatrice/src/tab.h | 6 +- cockatrice/src/tab_admin.cpp | 4 +- cockatrice/src/tab_admin.h | 2 +- cockatrice/src/tab_deck_storage.cpp | 4 +- cockatrice/src/tab_deck_storage.h | 2 +- cockatrice/src/tab_game.cpp | 4 +- cockatrice/src/tab_game.h | 2 +- cockatrice/src/tab_message.cpp | 4 +- cockatrice/src/tab_message.h | 2 +- cockatrice/src/tab_room.cpp | 11 ++- cockatrice/src/tab_room.h | 2 +- cockatrice/src/tab_server.cpp | 53 +---------- cockatrice/src/tab_server.h | 14 +-- cockatrice/src/tab_supervisor.cpp | 25 +++-- cockatrice/src/tab_supervisor.h | 3 + cockatrice/src/userlist.cpp | 94 +++++++++++++++++-- cockatrice/src/userlist.h | 18 +++- common/protocol_item_ids.h | 140 ++++++++++++++-------------- common/protocol_items.cpp | 24 +++++ common/protocol_items.dat | 4 + common/protocol_items.h | 32 +++++++ 22 files changed, 278 insertions(+), 174 deletions(-) diff --git a/cockatrice/cockatrice.pro b/cockatrice/cockatrice.pro index be01da98..4a0203f2 100644 --- a/cockatrice/cockatrice.pro +++ b/cockatrice/cockatrice.pro @@ -58,6 +58,7 @@ HEADERS += src/abstractcounter.h \ src/tab_deck_storage.h \ src/tab_supervisor.h \ src/tab_admin.h \ + src/tab_userlists.h \ src/chatview.h \ src/userlist.h \ src/userinfobox.h \ @@ -140,6 +141,7 @@ SOURCES += src/abstractcounter.cpp \ src/tab_deck_storage.cpp \ src/tab_supervisor.cpp \ src/tab_admin.cpp \ + src/tab_userlists.cpp \ src/chatview.cpp \ src/userlist.cpp \ src/userinfobox.cpp \ diff --git a/cockatrice/src/tab.h b/cockatrice/src/tab.h index 48e72744..ac83ec59 100644 --- a/cockatrice/src/tab.h +++ b/cockatrice/src/tab.h @@ -4,6 +4,7 @@ #include class QMenu; +class TabSupervisor; class Tab : public QWidget { Q_OBJECT @@ -11,11 +12,12 @@ signals: void userEvent(); protected: QMenu *tabMenu; + TabSupervisor *tabSupervisor; private: bool contentsChanged; public: - Tab(QWidget *parent = 0) - : QWidget(parent), tabMenu(0), contentsChanged(false) { } + Tab(TabSupervisor *_tabSupervisor, QWidget *parent = 0) + : QWidget(parent), tabMenu(0), tabSupervisor(_tabSupervisor), contentsChanged(false) { } QMenu *getTabMenu() const { return tabMenu; } bool getContentsChanged() const { return contentsChanged; } void setContentsChanged(bool _contentsChanged) { contentsChanged = _contentsChanged; } diff --git a/cockatrice/src/tab_admin.cpp b/cockatrice/src/tab_admin.cpp index 3c520077..3b949ec6 100644 --- a/cockatrice/src/tab_admin.cpp +++ b/cockatrice/src/tab_admin.cpp @@ -6,8 +6,8 @@ #include "abstractclient.h" #include "protocol_items.h" -TabAdmin::TabAdmin(AbstractClient *_client, QWidget *parent) - : Tab(parent), client(_client) +TabAdmin::TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent) + : Tab(_tabSupervisor, parent), client(_client) { updateServerMessageButton = new QPushButton; connect(updateServerMessageButton, SIGNAL(clicked()), this, SLOT(actUpdateServerMessage())); diff --git a/cockatrice/src/tab_admin.h b/cockatrice/src/tab_admin.h index f3d9b860..fc61eb95 100644 --- a/cockatrice/src/tab_admin.h +++ b/cockatrice/src/tab_admin.h @@ -21,7 +21,7 @@ private slots: void actUnlock(); void actLock(); public: - TabAdmin(AbstractClient *_client, QWidget *parent = 0); + TabAdmin(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent = 0); void retranslateUi(); QString getTabText() const { return tr("Administration"); } }; diff --git a/cockatrice/src/tab_deck_storage.cpp b/cockatrice/src/tab_deck_storage.cpp index 6792f152..c4940ed8 100644 --- a/cockatrice/src/tab_deck_storage.cpp +++ b/cockatrice/src/tab_deck_storage.cpp @@ -17,8 +17,8 @@ #include "window_deckeditor.h" #include "settingscache.h" -TabDeckStorage::TabDeckStorage(AbstractClient *_client) - : Tab(), client(_client) +TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client) + : Tab(_tabSupervisor), client(_client) { localDirModel = new QFileSystemModel(this); localDirModel->setRootPath(settingsCache->getDeckPath()); diff --git a/cockatrice/src/tab_deck_storage.h b/cockatrice/src/tab_deck_storage.h index 43893efb..758ed12b 100644 --- a/cockatrice/src/tab_deck_storage.h +++ b/cockatrice/src/tab_deck_storage.h @@ -45,7 +45,7 @@ private slots: void actDelete(); void deleteFinished(ResponseCode resp); public: - TabDeckStorage(AbstractClient *_client); + TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_client); void retranslateUi(); QString getTabText() const { return tr("Deck storage"); } }; diff --git a/cockatrice/src/tab_game.cpp b/cockatrice/src/tab_game.cpp index 31baaa78..41b7c5b2 100644 --- a/cockatrice/src/tab_game.cpp +++ b/cockatrice/src/tab_game.cpp @@ -159,8 +159,8 @@ void DeckViewContainer::setDeck(DeckList *deck) readyStartButton->setEnabled(true); } -TabGame::TabGame(QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) - : Tab(), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1), infoPopup(0) +TabGame::TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming) + : Tab(_tabSupervisor), clients(_clients), gameId(_gameId), gameDescription(_gameDescription), localPlayerId(_localPlayerId), spectator(_spectator), spectatorsCanTalk(_spectatorsCanTalk), spectatorsSeeEverything(_spectatorsSeeEverything), started(false), resuming(_resuming), currentPhase(-1), infoPopup(0) { phasesToolbar = new PhasesToolbar; phasesToolbar->hide(); diff --git a/cockatrice/src/tab_game.h b/cockatrice/src/tab_game.h index b2413437..f79088b9 100644 --- a/cockatrice/src/tab_game.h +++ b/cockatrice/src/tab_game.h @@ -153,7 +153,7 @@ private slots: void actNextPhase(); void actNextTurn(); public: - TabGame(QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming); + TabGame(TabSupervisor *_tabSupervisor, QList &_clients, int _gameId, const QString &_gameDescription, int _localPlayerId, bool _spectator, bool _spectatorsCanTalk, bool _spectatorsSeeEverything, bool _resuming); ~TabGame(); void retranslateUi(); const QMap &getPlayers() const { return players; } diff --git a/cockatrice/src/tab_message.cpp b/cockatrice/src/tab_message.cpp index 339a293f..ba627432 100644 --- a/cockatrice/src/tab_message.cpp +++ b/cockatrice/src/tab_message.cpp @@ -8,8 +8,8 @@ #include "protocol_items.h" #include "chatview.h" -TabMessage::TabMessage(AbstractClient *_client, const QString &_ownName, const QString &_userName) - : Tab(), client(_client), userName(_userName), userOnline(true) +TabMessage::TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName) + : Tab(_tabSupervisor), client(_client), userName(_userName), userOnline(true) { chatView = new ChatView(_ownName); sayEdit = new QLineEdit; diff --git a/cockatrice/src/tab_message.h b/cockatrice/src/tab_message.h index 868f6316..a2d35f84 100644 --- a/cockatrice/src/tab_message.h +++ b/cockatrice/src/tab_message.h @@ -25,7 +25,7 @@ private slots: void sendMessage(); void actLeave(); public: - TabMessage(AbstractClient *_client, const QString &_ownName, const QString &_userName); + TabMessage(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, const QString &_userName); ~TabMessage(); void retranslateUi(); QString getUserName() const { return userName; } diff --git a/cockatrice/src/tab_room.cpp b/cockatrice/src/tab_room.cpp index 8892479e..5b7ace63 100644 --- a/cockatrice/src/tab_room.cpp +++ b/cockatrice/src/tab_room.cpp @@ -10,6 +10,7 @@ #include #include #include "dlg_creategame.h" +#include "tab_supervisor.h" #include "tab_room.h" #include "userlist.h" #include "abstractclient.h" @@ -122,15 +123,15 @@ void GameSelector::processGameInfo(ServerInfo_Game *info) gameListModel->updateGameList(info); } -TabRoom::TabRoom(AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info) - : Tab(), client(_client), roomId(info->getRoomId()), roomName(info->getName()), ownName(_ownName) +TabRoom::TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info) + : Tab(_tabSupervisor), client(_client), roomId(info->getRoomId()), roomName(info->getName()), ownName(_ownName) { const QList gameTypeList = info->getGameTypeList(); for (int i = 0; i < gameTypeList.size(); ++i) gameTypes.insert(gameTypeList[i]->getGameTypeId(), gameTypeList[i]->getDescription()); gameSelector = new GameSelector(client, this); - userList = new UserList(client, false); + userList = new UserList(tabSupervisor->getUserListsTab(), client, UserList::RoomList); connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool))); chatView = new ChatView(ownName); @@ -169,7 +170,7 @@ TabRoom::TabRoom(AbstractClient *_client, const QString &_ownName, ServerInfo_Ro const QList users = info->getUserList(); for (int i = 0; i < users.size(); ++i) - userList->processUserInfo(users[i]); + userList->processUserInfo(users[i], true); userList->sortItems(); const QList games = info->getGameList(); @@ -233,7 +234,7 @@ void TabRoom::processListGamesEvent(Event_ListGames *event) void TabRoom::processJoinRoomEvent(Event_JoinRoom *event) { - userList->processUserInfo(event->getUserInfo()); + userList->processUserInfo(event->getUserInfo(), true); userList->sortItems(); } diff --git a/cockatrice/src/tab_room.h b/cockatrice/src/tab_room.h index 331097f2..cc2913a9 100644 --- a/cockatrice/src/tab_room.h +++ b/cockatrice/src/tab_room.h @@ -79,7 +79,7 @@ private slots: void processLeaveRoomEvent(Event_LeaveRoom *event); void processSayEvent(Event_RoomSay *event); public: - TabRoom(AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info); + TabRoom(TabSupervisor *_tabSupervisor, AbstractClient *_client, const QString &_ownName, ServerInfo_Room *info); ~TabRoom(); void retranslateUi(); void processRoomEvent(RoomEvent *event); diff --git a/cockatrice/src/tab_server.cpp b/cockatrice/src/tab_server.cpp index 47c49af8..6fd858ae 100644 --- a/cockatrice/src/tab_server.cpp +++ b/cockatrice/src/tab_server.cpp @@ -117,47 +117,27 @@ void RoomSelector::joinFinished(ProtocolResponse *r) emit roomJoined(resp->getRoomInfo(), static_cast(sender())->getExtraData().toBool()); } -TabServer::TabServer(AbstractClient *_client, ServerInfo_User *userInfo, QWidget *parent) - : Tab(parent), client(_client) +TabServer::TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent) + : Tab(_tabSupervisor, parent), client(_client) { roomSelector = new RoomSelector(client); serverInfoBox = new QTextBrowser; serverInfoBox->setOpenExternalLinks(true); - userInfoBox = new UserInfoBox(_client, false); - userInfoBox->updateInfo(userInfo); - userList = new UserList(client, true); connect(roomSelector, SIGNAL(roomJoined(ServerInfo_Room *, bool)), this, SIGNAL(roomJoined(ServerInfo_Room *, bool))); - connect(userList, SIGNAL(openMessageDialog(const QString &, bool)), this, SIGNAL(openMessageDialog(const QString &, bool))); - connect(client, SIGNAL(userJoinedEventReceived(Event_UserJoined *)), this, SLOT(processUserJoinedEvent(Event_UserJoined *))); - connect(client, SIGNAL(userLeftEventReceived(Event_UserLeft *)), this, SLOT(processUserLeftEvent(Event_UserLeft *))); connect(client, SIGNAL(serverMessageEventReceived(Event_ServerMessage *)), this, SLOT(processServerMessageEvent(Event_ServerMessage *))); - Command_ListUsers *cmd = new Command_ListUsers; - connect(cmd, SIGNAL(finished(ProtocolResponse *)), this, SLOT(processListUsersResponse(ProtocolResponse *))); - client->sendCommand(cmd); - QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(roomSelector); vbox->addWidget(serverInfoBox); - QVBoxLayout *vbox2 = new QVBoxLayout; - vbox2->addWidget(userInfoBox); - vbox2->addWidget(userList); - - QHBoxLayout *mainLayout = new QHBoxLayout; - mainLayout->addLayout(vbox, 3); - mainLayout->addLayout(vbox2, 1); - - setLayout(mainLayout); + setLayout(vbox); } void TabServer::retranslateUi() { roomSelector->retranslateUi(); - userInfoBox->retranslateUi(); - userList->retranslateUi(); } void TabServer::processServerMessageEvent(Event_ServerMessage *event) @@ -165,30 +145,3 @@ void TabServer::processServerMessageEvent(Event_ServerMessage *event) serverInfoBox->setHtml(event->getMessage()); emit userEvent(); } - -void TabServer::processListUsersResponse(ProtocolResponse *response) -{ - Response_ListUsers *resp = qobject_cast(response); - if (!resp) - return; - - const QList &respList = resp->getUserList(); - for (int i = 0; i < respList.size(); ++i) - userList->processUserInfo(respList[i]); - - userList->sortItems(); -} - -void TabServer::processUserJoinedEvent(Event_UserJoined *event) -{ - userList->processUserInfo(event->getUserInfo()); - userList->sortItems(); - - emit userJoined(event->getUserInfo()->getName()); -} - -void TabServer::processUserLeftEvent(Event_UserLeft *event) -{ - if (userList->deleteUser(event->getUserName())) - emit userLeft(event->getUserName()); -} \ No newline at end of file diff --git a/cockatrice/src/tab_server.h b/cockatrice/src/tab_server.h index 6093f860..556f0f97 100644 --- a/cockatrice/src/tab_server.h +++ b/cockatrice/src/tab_server.h @@ -11,14 +11,10 @@ class QTextEdit; class QLabel; class UserList; class QPushButton; -class UserInfoBox; class Event_ListRooms; class Event_ServerMessage; -class Event_UserJoined; -class Event_UserLeft; class ProtocolResponse; -class ServerInfo_User; class ServerInfo_Room; class RoomSelector : public QGroupBox { @@ -44,22 +40,14 @@ class TabServer : public Tab { Q_OBJECT signals: void roomJoined(ServerInfo_Room *info, bool setCurrent); - void openMessageDialog(const QString &userName, bool focus); - void userLeft(const QString &userName); - void userJoined(const QString &userName); private slots: - void processListUsersResponse(ProtocolResponse *response); - void processUserJoinedEvent(Event_UserJoined *event); - void processUserLeftEvent(Event_UserLeft *event); void processServerMessageEvent(Event_ServerMessage *event); private: AbstractClient *client; RoomSelector *roomSelector; QTextBrowser *serverInfoBox; - UserList *userList; - UserInfoBox *userInfoBox; public: - TabServer(AbstractClient *_client, ServerInfo_User *userInfo, QWidget *parent = 0); + TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client, QWidget *parent = 0); void retranslateUi(); QString getTabText() const { return tr("Server"); } }; diff --git a/cockatrice/src/tab_supervisor.cpp b/cockatrice/src/tab_supervisor.cpp index d5f37fdf..fbb108ff 100644 --- a/cockatrice/src/tab_supervisor.cpp +++ b/cockatrice/src/tab_supervisor.cpp @@ -7,6 +7,7 @@ #include "tab_deck_storage.h" #include "tab_admin.h" #include "tab_message.h" +#include "tab_userlists.h" #include "protocol_items.h" #include "pixmapgenerator.h" #include @@ -63,22 +64,26 @@ void TabSupervisor::start(AbstractClient *_client, ServerInfo_User *userInfo) 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, userInfo); + tabServer = new TabServer(this, client); connect(tabServer, SIGNAL(roomJoined(ServerInfo_Room *, bool)), this, SLOT(addRoomTab(ServerInfo_Room *, bool))); - connect(tabServer, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); - connect(tabServer, SIGNAL(userJoined(const QString &)), this, SLOT(processUserJoined(const QString &))); - connect(tabServer, SIGNAL(userLeft(const QString &)), this, SLOT(processUserLeft(const QString &))); myAddTab(tabServer); + + tabUserLists = new TabUserLists(this, client, userInfo); + connect(tabUserLists, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); + connect(tabUserLists, SIGNAL(userJoined(const QString &)), this, SLOT(processUserJoined(const QString &))); + connect(tabUserLists, SIGNAL(userLeft(const QString &)), this, SLOT(processUserLeft(const QString &))); + myAddTab(tabUserLists); + updatePingTime(0, -1); if (userInfo->getUserLevel() & ServerInfo_User::IsRegistered) { - tabDeckStorage = new TabDeckStorage(client); + tabDeckStorage = new TabDeckStorage(this, client); myAddTab(tabDeckStorage); } else tabDeckStorage = 0; if (userInfo->getUserLevel() & ServerInfo_User::IsAdmin) { - tabAdmin = new TabAdmin(client); + tabAdmin = new TabAdmin(this, client); myAddTab(tabAdmin); } else tabAdmin = 0; @@ -148,7 +153,7 @@ void TabSupervisor::updatePingTime(int value, int max) void TabSupervisor::gameJoined(Event_GameJoined *event) { - TabGame *tab = new TabGame(QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); + TabGame *tab = new TabGame(this, QList() << client, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); myAddTab(tab); gameTabs.insert(event->getGameId(), tab); @@ -157,7 +162,7 @@ void TabSupervisor::gameJoined(Event_GameJoined *event) void TabSupervisor::localGameJoined(Event_GameJoined *event) { - TabGame *tab = new TabGame(localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); + TabGame *tab = new TabGame(this, localClients, event->getGameId(), event->getGameDescription(), event->getPlayerId(), event->getSpectator(), event->getSpectatorsCanTalk(), event->getSpectatorsSeeEverything(), event->getResuming()); connect(tab, SIGNAL(gameClosing(TabGame *)), this, SLOT(gameLeft(TabGame *))); myAddTab(tab); gameTabs.insert(event->getGameId(), tab); @@ -182,7 +187,7 @@ void TabSupervisor::gameLeft(TabGame *tab) void TabSupervisor::addRoomTab(ServerInfo_Room *info, bool setCurrent) { - TabRoom *tab = new TabRoom(client, userName, info); + TabRoom *tab = new TabRoom(this, client, userName, info); connect(tab, SIGNAL(roomClosing(TabRoom *)), this, SLOT(roomLeft(TabRoom *))); connect(tab, SIGNAL(openMessageDialog(const QString &, bool)), this, SLOT(addMessageTab(const QString &, bool))); myAddTab(tab); @@ -204,7 +209,7 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus if (receiverName == userName) return 0; - TabMessage *tab = new TabMessage(client, userName, receiverName); + TabMessage *tab = new TabMessage(this, client, userName, receiverName); connect(tab, SIGNAL(talkClosing(TabMessage *)), this, SLOT(talkLeft(TabMessage *))); myAddTab(tab); messageTabs.insert(receiverName, tab); diff --git a/cockatrice/src/tab_supervisor.h b/cockatrice/src/tab_supervisor.h index 0dab9085..75402672 100644 --- a/cockatrice/src/tab_supervisor.h +++ b/cockatrice/src/tab_supervisor.h @@ -13,6 +13,7 @@ class TabGame; class TabDeckStorage; class TabAdmin; class TabMessage; +class TabUserLists; class RoomEvent; class GameEventContainer; class Event_GameJoined; @@ -28,6 +29,7 @@ private: AbstractClient *client; QList localClients; TabServer *tabServer; + TabUserLists *tabUserLists; TabDeckStorage *tabDeckStorage; TabAdmin *tabAdmin; QMap roomTabs; @@ -42,6 +44,7 @@ public: void startLocal(const QList &_clients); void stop(); int getGameCount() const { return gameTabs.size(); } + TabUserLists *getUserListsTab() const { return tabUserLists; } signals: void setMenu(QMenu *menu); void localGameEnded(); diff --git a/cockatrice/src/userlist.cpp b/cockatrice/src/userlist.cpp index 353554c6..39aaf4df 100644 --- a/cockatrice/src/userlist.cpp +++ b/cockatrice/src/userlist.cpp @@ -1,4 +1,5 @@ #include "userlist.h" +#include "tab_userlists.h" #include "abstractclient.h" #include "pixmapgenerator.h" #include "userinfobox.h" @@ -31,15 +32,20 @@ UserListTWI::UserListTWI() bool UserListTWI::operator<(const QTreeWidgetItem &other) const { - // Equal user level => sort by name - if (data(0, Qt::UserRole) == other.data(0, Qt::UserRole)) - return data(2, Qt::UserRole).toString().toLower() < other.data(2, Qt::UserRole).toString().toLower(); - // Else sort by user level - return data(0, Qt::UserRole).toInt() > other.data(0, Qt::UserRole).toInt(); + // Sort by online/offline + if (data(0, Qt::UserRole + 1) != other.data(0, Qt::UserRole + 1)) + return data(0, Qt::UserRole + 1).toBool(); + + // Sort by user level + if (data(0, Qt::UserRole) != other.data(0, Qt::UserRole)) + return data(0, Qt::UserRole).toInt() > other.data(0, Qt::UserRole).toInt(); + + // Sort by name + return data(2, Qt::UserRole).toString().toLower() < other.data(2, Qt::UserRole).toString().toLower(); } -UserList::UserList(AbstractClient *_client, bool _global, QWidget *parent) - : QGroupBox(parent), client(_client), global(_global) +UserList::UserList(TabUserLists *_tabUserLists, AbstractClient *_client, UserListType _type, QWidget *parent) + : QGroupBox(parent), tabUserLists(_tabUserLists), client(_client), type(_type), onlineCount(0) { itemDelegate = new UserListItemDelegate(this); @@ -62,11 +68,16 @@ UserList::UserList(AbstractClient *_client, bool _global, QWidget *parent) void UserList::retranslateUi() { - titleStr = global ? tr("Users online: %1") : tr("Users in this room: %1"); + switch (type) { + case AllUsersList: titleStr = tr("Users online: %1"); break; + case RoomList: titleStr = tr("Users in this room: %1"); break; + case BuddyList: titleStr = tr("Buddies online: %1 / %2"); break; + case IgnoreList: titleStr = tr("Ignored users online: %1 / %2"); break; + } updateCount(); } -void UserList::processUserInfo(ServerInfo_User *user) +void UserList::processUserInfo(ServerInfo_User *user, bool online) { QTreeWidgetItem *item = 0; for (int i = 0; i < userTree->topLevelItemCount(); ++i) { @@ -86,6 +97,12 @@ void UserList::processUserInfo(ServerInfo_User *user) item->setIcon(1, QIcon(CountryPixmapGenerator::generatePixmap(12, user->getCountry()))); item->setData(2, Qt::UserRole, user->getName()); item->setData(2, Qt::DisplayRole, user->getName()); + + item->setData(0, Qt::UserRole + 1, online); + if (online) + item->setData(2, Qt::ForegroundRole, QBrush()); + else + item->setData(2, Qt::ForegroundRole, QBrush(Qt::gray)); } bool UserList::deleteUser(const QString &userName) @@ -100,9 +117,37 @@ bool UserList::deleteUser(const QString &userName) return false; } +void UserList::setUserOnline(QTreeWidgetItem *item, bool online) +{ + item->setData(0, Qt::UserRole + 1, online); + + if (online) { + item->setData(2, Qt::ForegroundRole, QBrush()); + ++onlineCount; + } else { + item->setData(2, Qt::ForegroundRole, QBrush(Qt::gray)); + --onlineCount; + } + updateCount(); +} + +void UserList::setUserOnline(const QString &userName, bool online) +{ + for (int i = 0; i < userTree->topLevelItemCount(); ++i) { + QTreeWidgetItem *item = userTree->topLevelItem(i); + if (item->data(2, Qt::UserRole) == userName) { + setUserOnline(item, online); + break; + } + } +} + void UserList::updateCount() { - setTitle(titleStr.arg(userTree->topLevelItemCount())); + QString str = titleStr; + if ((type == BuddyList) || (type == IgnoreList)) + str = str.arg(onlineCount); + setTitle(str.arg(userTree->topLevelItemCount())); } void UserList::userClicked(QTreeWidgetItem *item, int /*column*/) @@ -118,12 +163,25 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) aUserName->setEnabled(false); QAction *aDetails = new QAction(tr("User &details"), this); QAction *aChat = new QAction(tr("Direct &chat"), this); + QAction *aAddToBuddyList = new QAction(tr("Add to &buddy list"), this); + QAction *aRemoveFromBuddyList = new QAction(tr("Remove from &buddy list"), this); + QAction *aAddToIgnoreList = new QAction(tr("Remove from &ignore list"), this); + QAction *aRemoveFromIgnoreList = new QAction(tr("Remove from &ignore list"), this); QMenu *menu = new QMenu(this); menu->addAction(aUserName); menu->addSeparator(); menu->addAction(aDetails); menu->addAction(aChat); + menu->addSeparator(); + if (tabUserLists->getBuddyList()->userInList(userName)) + menu->addAction(aRemoveFromBuddyList); + else + menu->addAction(aAddToBuddyList); + if (tabUserLists->getIgnoreList()->userInList(userName)) + menu->addAction(aRemoveFromIgnoreList); + else + menu->addAction(aAddToIgnoreList); QAction *actionClicked = menu->exec(pos); if (actionClicked == aDetails) { @@ -132,6 +190,14 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) infoWidget->updateInfo(userName); } else if (actionClicked == aChat) emit openMessageDialog(userName, true); + else if (actionClicked == aAddToBuddyList) + emit addBuddy(userName); + else if (actionClicked == aRemoveFromBuddyList) + emit removeBuddy(userName); + else if (actionClicked == aAddToIgnoreList) + emit addIgnore(userName); + else if (actionClicked == aRemoveFromIgnoreList) + emit removeIgnore(userName); delete menu; delete aUserName; @@ -139,6 +205,14 @@ void UserList::showContextMenu(const QPoint &pos, const QModelIndex &index) delete aChat; } +bool UserList::userInList(const QString &userName) const +{ + for (int i = 0; i < userTree->topLevelItemCount(); ++i) + if (userTree->topLevelItem(i)->data(2, Qt::UserRole) == userName) + return true; + return false; +} + void UserList::sortItems() { userTree->sortItems(1, Qt::AscendingOrder); diff --git a/cockatrice/src/userlist.h b/cockatrice/src/userlist.h index 09b5d888..cd883ff6 100644 --- a/cockatrice/src/userlist.h +++ b/cockatrice/src/userlist.h @@ -8,6 +8,7 @@ class QTreeWidget; class ServerInfo_User; class AbstractClient; +class TabUserLists; class UserListItemDelegate : public QStyledItemDelegate { public: @@ -23,22 +24,33 @@ public: class UserList : public QGroupBox { Q_OBJECT +public: + enum UserListType { AllUsersList, RoomList, BuddyList, IgnoreList }; private: + TabUserLists *tabUserLists; AbstractClient *client; + UserListType type; QTreeWidget *userTree; UserListItemDelegate *itemDelegate; - bool global; + int onlineCount; QString titleStr; void updateCount(); + void setUserOnline(QTreeWidgetItem *user, bool online); private slots: void userClicked(QTreeWidgetItem *item, int column); signals: void openMessageDialog(const QString &userName, bool focus); + void addBuddy(const QString &userName); + void removeBuddy(const QString &userName); + void addIgnore(const QString &userName); + void removeIgnore(const QString &userName); public: - UserList(AbstractClient *_client, bool _global, QWidget *parent = 0); + UserList(TabUserLists *_tabUserLists, AbstractClient *_client, UserListType _type, QWidget *parent = 0); void retranslateUi(); - void processUserInfo(ServerInfo_User *user); + void processUserInfo(ServerInfo_User *user, bool online); bool deleteUser(const QString &userName); + void setUserOnline(const QString &userName, bool online); + bool userInList(const QString &userName) const; void showContextMenu(const QPoint &pos, const QModelIndex &index); void sortItems(); }; diff --git a/common/protocol_item_ids.h b/common/protocol_item_ids.h index 8ac92abf..2f486df2 100644 --- a/common/protocol_item_ids.h +++ b/common/protocol_item_ids.h @@ -4,72 +4,76 @@ ItemId_Command_Login = 1002, ItemId_Command_Message = 1003, ItemId_Command_ListUsers = 1004, ItemId_Command_GetUserInfo = 1005, -ItemId_Command_DeckList = 1006, -ItemId_Command_DeckNewDir = 1007, -ItemId_Command_DeckDelDir = 1008, -ItemId_Command_DeckDel = 1009, -ItemId_Command_DeckDownload = 1010, -ItemId_Command_ListRooms = 1011, -ItemId_Command_JoinRoom = 1012, -ItemId_Command_LeaveRoom = 1013, -ItemId_Command_RoomSay = 1014, -ItemId_Command_JoinGame = 1015, -ItemId_Command_LeaveGame = 1016, -ItemId_Command_Say = 1017, -ItemId_Command_Shuffle = 1018, -ItemId_Command_Mulligan = 1019, -ItemId_Command_RollDie = 1020, -ItemId_Command_DrawCards = 1021, -ItemId_Command_UndoDraw = 1022, -ItemId_Command_FlipCard = 1023, -ItemId_Command_AttachCard = 1024, -ItemId_Command_CreateToken = 1025, -ItemId_Command_CreateArrow = 1026, -ItemId_Command_DeleteArrow = 1027, -ItemId_Command_SetCardAttr = 1028, -ItemId_Command_SetCardCounter = 1029, -ItemId_Command_IncCardCounter = 1030, -ItemId_Command_ReadyStart = 1031, -ItemId_Command_Concede = 1032, -ItemId_Command_IncCounter = 1033, -ItemId_Command_CreateCounter = 1034, -ItemId_Command_SetCounter = 1035, -ItemId_Command_DelCounter = 1036, -ItemId_Command_NextTurn = 1037, -ItemId_Command_SetActivePhase = 1038, -ItemId_Command_DumpZone = 1039, -ItemId_Command_StopDumpZone = 1040, -ItemId_Command_RevealCards = 1041, -ItemId_Event_Say = 1042, -ItemId_Event_Leave = 1043, -ItemId_Event_GameClosed = 1044, -ItemId_Event_Shuffle = 1045, -ItemId_Event_RollDie = 1046, -ItemId_Event_MoveCard = 1047, -ItemId_Event_FlipCard = 1048, -ItemId_Event_DestroyCard = 1049, -ItemId_Event_AttachCard = 1050, -ItemId_Event_CreateToken = 1051, -ItemId_Event_DeleteArrow = 1052, -ItemId_Event_SetCardAttr = 1053, -ItemId_Event_SetCardCounter = 1054, -ItemId_Event_SetCounter = 1055, -ItemId_Event_DelCounter = 1056, -ItemId_Event_SetActivePlayer = 1057, -ItemId_Event_SetActivePhase = 1058, -ItemId_Event_DumpZone = 1059, -ItemId_Event_StopDumpZone = 1060, -ItemId_Event_ServerMessage = 1061, -ItemId_Event_Message = 1062, -ItemId_Event_GameJoined = 1063, -ItemId_Event_UserLeft = 1064, -ItemId_Event_LeaveRoom = 1065, -ItemId_Event_RoomSay = 1066, -ItemId_Context_ReadyStart = 1067, -ItemId_Context_Concede = 1068, -ItemId_Context_DeckSelect = 1069, -ItemId_Context_UndoDraw = 1070, -ItemId_Context_MoveCard = 1071, -ItemId_Command_UpdateServerMessage = 1072, -ItemId_Other = 1073 +ItemId_Command_AddBuddy = 1006, +ItemId_Command_RemoveBuddy = 1007, +ItemId_Command_AddIgnore = 1008, +ItemId_Command_RemoveIgnore = 1009, +ItemId_Command_DeckList = 1010, +ItemId_Command_DeckNewDir = 1011, +ItemId_Command_DeckDelDir = 1012, +ItemId_Command_DeckDel = 1013, +ItemId_Command_DeckDownload = 1014, +ItemId_Command_ListRooms = 1015, +ItemId_Command_JoinRoom = 1016, +ItemId_Command_LeaveRoom = 1017, +ItemId_Command_RoomSay = 1018, +ItemId_Command_JoinGame = 1019, +ItemId_Command_LeaveGame = 1020, +ItemId_Command_Say = 1021, +ItemId_Command_Shuffle = 1022, +ItemId_Command_Mulligan = 1023, +ItemId_Command_RollDie = 1024, +ItemId_Command_DrawCards = 1025, +ItemId_Command_UndoDraw = 1026, +ItemId_Command_FlipCard = 1027, +ItemId_Command_AttachCard = 1028, +ItemId_Command_CreateToken = 1029, +ItemId_Command_CreateArrow = 1030, +ItemId_Command_DeleteArrow = 1031, +ItemId_Command_SetCardAttr = 1032, +ItemId_Command_SetCardCounter = 1033, +ItemId_Command_IncCardCounter = 1034, +ItemId_Command_ReadyStart = 1035, +ItemId_Command_Concede = 1036, +ItemId_Command_IncCounter = 1037, +ItemId_Command_CreateCounter = 1038, +ItemId_Command_SetCounter = 1039, +ItemId_Command_DelCounter = 1040, +ItemId_Command_NextTurn = 1041, +ItemId_Command_SetActivePhase = 1042, +ItemId_Command_DumpZone = 1043, +ItemId_Command_StopDumpZone = 1044, +ItemId_Command_RevealCards = 1045, +ItemId_Event_Say = 1046, +ItemId_Event_Leave = 1047, +ItemId_Event_GameClosed = 1048, +ItemId_Event_Shuffle = 1049, +ItemId_Event_RollDie = 1050, +ItemId_Event_MoveCard = 1051, +ItemId_Event_FlipCard = 1052, +ItemId_Event_DestroyCard = 1053, +ItemId_Event_AttachCard = 1054, +ItemId_Event_CreateToken = 1055, +ItemId_Event_DeleteArrow = 1056, +ItemId_Event_SetCardAttr = 1057, +ItemId_Event_SetCardCounter = 1058, +ItemId_Event_SetCounter = 1059, +ItemId_Event_DelCounter = 1060, +ItemId_Event_SetActivePlayer = 1061, +ItemId_Event_SetActivePhase = 1062, +ItemId_Event_DumpZone = 1063, +ItemId_Event_StopDumpZone = 1064, +ItemId_Event_ServerMessage = 1065, +ItemId_Event_Message = 1066, +ItemId_Event_GameJoined = 1067, +ItemId_Event_UserLeft = 1068, +ItemId_Event_LeaveRoom = 1069, +ItemId_Event_RoomSay = 1070, +ItemId_Context_ReadyStart = 1071, +ItemId_Context_Concede = 1072, +ItemId_Context_DeckSelect = 1073, +ItemId_Context_UndoDraw = 1074, +ItemId_Context_MoveCard = 1075, +ItemId_Command_UpdateServerMessage = 1076, +ItemId_Other = 1077 }; diff --git a/common/protocol_items.cpp b/common/protocol_items.cpp index 98177afa..630d5c63 100644 --- a/common/protocol_items.cpp +++ b/common/protocol_items.cpp @@ -26,6 +26,26 @@ Command_GetUserInfo::Command_GetUserInfo(const QString &_userName) { insertItem(new SerializableItem_String("user_name", _userName)); } +Command_AddBuddy::Command_AddBuddy(const QString &_userName) + : Command("add_buddy") +{ + insertItem(new SerializableItem_String("user_name", _userName)); +} +Command_RemoveBuddy::Command_RemoveBuddy(const QString &_userName) + : Command("remove_buddy") +{ + insertItem(new SerializableItem_String("user_name", _userName)); +} +Command_AddIgnore::Command_AddIgnore(const QString &_userName) + : Command("add_ignore") +{ + insertItem(new SerializableItem_String("user_name", _userName)); +} +Command_RemoveIgnore::Command_RemoveIgnore(const QString &_userName) + : Command("remove_ignore") +{ + insertItem(new SerializableItem_String("user_name", _userName)); +} Command_DeckList::Command_DeckList() : Command("deck_list") { @@ -437,6 +457,10 @@ void ProtocolItem::initializeHashAuto() itemNameHash.insert("cmdmessage", Command_Message::newItem); itemNameHash.insert("cmdlist_users", Command_ListUsers::newItem); itemNameHash.insert("cmdget_user_info", Command_GetUserInfo::newItem); + itemNameHash.insert("cmdadd_buddy", Command_AddBuddy::newItem); + itemNameHash.insert("cmdremove_buddy", Command_RemoveBuddy::newItem); + itemNameHash.insert("cmdadd_ignore", Command_AddIgnore::newItem); + itemNameHash.insert("cmdremove_ignore", Command_RemoveIgnore::newItem); itemNameHash.insert("cmddeck_list", Command_DeckList::newItem); itemNameHash.insert("cmddeck_new_dir", Command_DeckNewDir::newItem); itemNameHash.insert("cmddeck_del_dir", Command_DeckDelDir::newItem); diff --git a/common/protocol_items.dat b/common/protocol_items.dat index 2b9d7dac..941242ae 100644 --- a/common/protocol_items.dat +++ b/common/protocol_items.dat @@ -3,6 +3,10 @@ 0:message:s,user_name:s,text 0:list_users 0:get_user_info:s,user_name +0:add_buddy:s,user_name +0:remove_buddy:s,user_name +0:add_ignore:s,user_name +0:remove_ignore:s,user_name 0:deck_list 0:deck_new_dir:s,path:s,dir_name 0:deck_del_dir:s,path diff --git a/common/protocol_items.h b/common/protocol_items.h index 852723f4..d0783fe5 100644 --- a/common/protocol_items.h +++ b/common/protocol_items.h @@ -43,6 +43,38 @@ public: static SerializableItem *newItem() { return new Command_GetUserInfo; } int getItemId() const { return ItemId_Command_GetUserInfo; } }; +class Command_AddBuddy : public Command { + Q_OBJECT +public: + Command_AddBuddy(const QString &_userName = QString()); + QString getUserName() const { return static_cast(itemMap.value("user_name"))->getData(); }; + static SerializableItem *newItem() { return new Command_AddBuddy; } + int getItemId() const { return ItemId_Command_AddBuddy; } +}; +class Command_RemoveBuddy : public Command { + Q_OBJECT +public: + Command_RemoveBuddy(const QString &_userName = QString()); + QString getUserName() const { return static_cast(itemMap.value("user_name"))->getData(); }; + static SerializableItem *newItem() { return new Command_RemoveBuddy; } + int getItemId() const { return ItemId_Command_RemoveBuddy; } +}; +class Command_AddIgnore : public Command { + Q_OBJECT +public: + Command_AddIgnore(const QString &_userName = QString()); + QString getUserName() const { return static_cast(itemMap.value("user_name"))->getData(); }; + static SerializableItem *newItem() { return new Command_AddIgnore; } + int getItemId() const { return ItemId_Command_AddIgnore; } +}; +class Command_RemoveIgnore : public Command { + Q_OBJECT +public: + Command_RemoveIgnore(const QString &_userName = QString()); + QString getUserName() const { return static_cast(itemMap.value("user_name"))->getData(); }; + static SerializableItem *newItem() { return new Command_RemoveIgnore; } + int getItemId() const { return ItemId_Command_RemoveIgnore; } +}; class Command_DeckList : public Command { Q_OBJECT public: