mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-10 08:14:47 -07:00
[Move refactor] Reparent orphan classes (#6236)
* Move orphaned classes to their correct parent folders. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
1ef07309d6
commit
d9c65d4ae0
143 changed files with 171 additions and 169 deletions
|
|
@ -0,0 +1,536 @@
|
|||
#include "user_context_menu.h"
|
||||
|
||||
#include "../../tabs/tab_account.h"
|
||||
#include "../../tabs/tab_game.h"
|
||||
#include "../../tabs/tab_supervisor.h"
|
||||
#include "../chat_view/chat_view.h"
|
||||
#include "../game_selector.h"
|
||||
#include "user_info_box.h"
|
||||
#include "user_list_manager.h"
|
||||
#include "user_list_proxy.h"
|
||||
#include "user_list_widget.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QSignalMapper>
|
||||
#include <QtGui>
|
||||
#include <QtWidgets>
|
||||
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||
#include <libcockatrice/protocol/pb/command_kick_from_game.pb.h>
|
||||
#include <libcockatrice/protocol/pb/commands.pb.h>
|
||||
#include <libcockatrice/protocol/pb/moderator_commands.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_ban_history.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_admin_notes.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_games_of_user.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_user_info.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_warn_history.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_warn_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/session_commands.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
|
||||
UserContextMenu::UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *parent, AbstractGame *_game)
|
||||
: QObject(parent), client(_tabSupervisor->getClient()), tabSupervisor(_tabSupervisor),
|
||||
userListProxy(_tabSupervisor->getUserListManager()), game(_game)
|
||||
{
|
||||
aUserName = new QAction(QString(), this);
|
||||
aUserName->setEnabled(false);
|
||||
aDetails = new QAction(QString(), this);
|
||||
aChat = new QAction(QString(), this);
|
||||
aShowGames = new QAction(QString(), this);
|
||||
aAddToBuddyList = new QAction(QString(), this);
|
||||
aRemoveFromBuddyList = new QAction(QString(), this);
|
||||
aAddToIgnoreList = new QAction(QString(), this);
|
||||
aRemoveFromIgnoreList = new QAction(QString(), this);
|
||||
aKick = new QAction(QString(), this);
|
||||
aWarnUser = new QAction(QString(), this);
|
||||
aWarnHistory = new QAction(QString(), this);
|
||||
aBan = new QAction(QString(), this);
|
||||
aBanHistory = new QAction(QString(), this);
|
||||
aPromoteToMod = new QAction(QString(), this);
|
||||
aDemoteFromMod = new QAction(QString(), this);
|
||||
aPromoteToJudge = new QAction(QString(), this);
|
||||
aDemoteFromJudge = new QAction(QString(), this);
|
||||
aGetAdminNotes = new QAction(QString(), this);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void UserContextMenu::retranslateUi()
|
||||
{
|
||||
aDetails->setText(tr("User &details"));
|
||||
aChat->setText(tr("Private &chat"));
|
||||
aShowGames->setText(tr("Show this user's &games"));
|
||||
aAddToBuddyList->setText(tr("Add to &buddy list"));
|
||||
aRemoveFromBuddyList->setText(tr("Remove from &buddy list"));
|
||||
aAddToIgnoreList->setText(tr("Add to &ignore list"));
|
||||
aRemoveFromIgnoreList->setText(tr("Remove from &ignore list"));
|
||||
aKick->setText(tr("Kick from &game"));
|
||||
aWarnUser->setText(tr("Warn user"));
|
||||
aWarnHistory->setText(tr("View user's war&n history"));
|
||||
aBan->setText(tr("Ban from &server"));
|
||||
aBanHistory->setText(tr("View user's &ban history"));
|
||||
aPromoteToMod->setText(tr("&Promote user to moderator"));
|
||||
aDemoteFromMod->setText(tr("Dem&ote user from moderator"));
|
||||
aPromoteToJudge->setText(tr("Promote user to &judge"));
|
||||
aDemoteFromJudge->setText(tr("Demote user from judge"));
|
||||
aGetAdminNotes->setText(tr("View admin notes"));
|
||||
}
|
||||
|
||||
void UserContextMenu::gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer)
|
||||
{
|
||||
const Command_GetGamesOfUser &cmd = commandContainer.session_command(0).GetExtension(Command_GetGamesOfUser::ext);
|
||||
if (resp.response_code() == Response::RespNameNotFound) {
|
||||
QMessageBox::critical(static_cast<QWidget *>(parent()), tr("Error"), tr("This user does not exist."));
|
||||
return;
|
||||
} else if (resp.response_code() == Response::RespInIgnoreList) {
|
||||
QMessageBox::critical(
|
||||
static_cast<QWidget *>(parent()), tr("Error"),
|
||||
tr("You are being ignored by %1 and can't see their games.").arg(QString::fromStdString(cmd.user_name())));
|
||||
return;
|
||||
} else if (resp.response_code() != Response::RespOk) {
|
||||
QMessageBox::critical(static_cast<QWidget *>(parent()), tr("Error"),
|
||||
tr("Could not get %1's games.").arg(QString::fromStdString(cmd.user_name())));
|
||||
return;
|
||||
}
|
||||
const Response_GetGamesOfUser &response = resp.GetExtension(Response_GetGamesOfUser::ext);
|
||||
|
||||
QMap<int, GameTypeMap> gameTypeMap;
|
||||
QMap<int, QString> roomMap;
|
||||
const int roomListSize = response.room_list_size();
|
||||
for (int i = 0; i < roomListSize; ++i) {
|
||||
const ServerInfo_Room &roomInfo = response.room_list(i);
|
||||
roomMap.insert(roomInfo.room_id(), QString::fromStdString(roomInfo.name()));
|
||||
GameTypeMap tempMap;
|
||||
const int gameTypeListSize = roomInfo.gametype_list_size();
|
||||
for (int j = 0; j < gameTypeListSize; ++j) {
|
||||
const ServerInfo_GameType &gameTypeInfo = roomInfo.gametype_list(j);
|
||||
tempMap.insert(gameTypeInfo.game_type_id(), QString::fromStdString(gameTypeInfo.description()));
|
||||
}
|
||||
gameTypeMap.insert(roomInfo.room_id(), tempMap);
|
||||
}
|
||||
|
||||
GameSelector *selector = new GameSelector(client, tabSupervisor, nullptr, roomMap, gameTypeMap, false, false);
|
||||
selector->setParent(static_cast<QWidget *>(parent()), Qt::Window);
|
||||
const int gameListSize = response.game_list_size();
|
||||
for (int i = 0; i < gameListSize; ++i) {
|
||||
selector->processGameInfo(response.game_list(i));
|
||||
}
|
||||
|
||||
selector->setWindowTitle(tr("%1's games").arg(QString::fromStdString(cmd.user_name())));
|
||||
selector->setMinimumWidth(800);
|
||||
selector->setAttribute(Qt::WA_DeleteOnClose);
|
||||
selector->show();
|
||||
}
|
||||
|
||||
void UserContextMenu::banUser_processUserInfoResponse(const Response &r)
|
||||
{
|
||||
const Response_GetUserInfo &response = r.GetExtension(Response_GetUserInfo::ext);
|
||||
|
||||
// The dialog needs to be non-modal in order to not block the event queue of the client.
|
||||
BanDialog *dlg = new BanDialog(response.user_info(), static_cast<QWidget *>(parent()));
|
||||
connect(dlg, &QDialog::accepted, this, &UserContextMenu::banUser_dialogFinished);
|
||||
dlg->show();
|
||||
}
|
||||
|
||||
void UserContextMenu::warnUser_processGetWarningsListResponse(const Response &r)
|
||||
{
|
||||
const Response_WarnList &response = r.GetExtension(Response_WarnList::ext);
|
||||
|
||||
QString user = QString::fromStdString(response.user_name()).simplified();
|
||||
QString clientid = QString::fromStdString(response.user_clientid()).simplified();
|
||||
|
||||
// The dialog needs to be non-modal in order to not block the event queue of the client.
|
||||
WarningDialog *dlg = new WarningDialog(user, clientid, static_cast<QWidget *>(parent()));
|
||||
connect(dlg, &QDialog::accepted, this, &UserContextMenu::warnUser_dialogFinished);
|
||||
|
||||
if (response.warning_size() > 0) {
|
||||
for (int i = 0; i < response.warning_size(); ++i) {
|
||||
dlg->addWarningOption(QString::fromStdString(response.warning(i)).simplified());
|
||||
}
|
||||
}
|
||||
dlg->show();
|
||||
}
|
||||
|
||||
void UserContextMenu::warnUser_processUserInfoResponse(const Response &resp)
|
||||
{
|
||||
const Response_GetUserInfo &response = resp.GetExtension(Response_GetUserInfo::ext);
|
||||
ServerInfo_User userInfo = response.user_info();
|
||||
|
||||
Command_GetWarnList cmd;
|
||||
cmd.set_user_name(userInfo.name());
|
||||
cmd.set_user_clientid(userInfo.clientid());
|
||||
PendingCommand *pend = client->prepareModeratorCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::warnUser_processGetWarningsListResponse);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void UserContextMenu::banUserHistory_processResponse(const Response &resp)
|
||||
{
|
||||
const Response_BanHistory &response = resp.GetExtension(Response_BanHistory::ext);
|
||||
if (resp.response_code() == Response::RespOk) {
|
||||
|
||||
if (response.ban_list_size() > 0) {
|
||||
QTableWidget *table = new QTableWidget();
|
||||
table->setWindowTitle(tr("Ban History"));
|
||||
table->setRowCount(response.ban_list_size());
|
||||
table->setColumnCount(5);
|
||||
table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
table->setHorizontalHeaderLabels(
|
||||
QString(tr("Ban Time;Moderator;Ban Length;Ban Reason;Visible Reason")).split(";"));
|
||||
|
||||
ServerInfo_Ban ban;
|
||||
for (int i = 0; i < response.ban_list_size(); ++i) {
|
||||
ban = response.ban_list(i);
|
||||
table->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(ban.ban_time())));
|
||||
table->setItem(i, 1, new QTableWidgetItem(QString::fromStdString(ban.admin_name())));
|
||||
table->setItem(i, 2, new QTableWidgetItem(QString::fromStdString(ban.ban_length())));
|
||||
table->setItem(i, 3, new QTableWidgetItem(QString::fromStdString(ban.ban_reason())));
|
||||
table->setItem(i, 4, new QTableWidgetItem(QString::fromStdString(ban.visible_reason())));
|
||||
}
|
||||
|
||||
table->resizeColumnsToContents();
|
||||
table->setMinimumSize(table->horizontalHeader()->length() + (table->columnCount() * 5),
|
||||
table->verticalHeader()->length() + (table->rowCount() * 3));
|
||||
table->show();
|
||||
} else
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Ban History"),
|
||||
tr("User has never been banned."));
|
||||
|
||||
} else
|
||||
QMessageBox::critical(static_cast<QWidget *>(parent()), tr("Ban History"),
|
||||
tr("Failed to collect ban information."));
|
||||
}
|
||||
|
||||
void UserContextMenu::warnUserHistory_processResponse(const Response &resp)
|
||||
{
|
||||
const Response_WarnHistory &response = resp.GetExtension(Response_WarnHistory::ext);
|
||||
if (resp.response_code() == Response::RespOk) {
|
||||
|
||||
if (response.warn_list_size() > 0) {
|
||||
QTableWidget *table = new QTableWidget();
|
||||
table->setWindowTitle(tr("Warning History"));
|
||||
table->setRowCount(response.warn_list_size());
|
||||
table->setColumnCount(4);
|
||||
table->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
|
||||
table->setHorizontalHeaderLabels(QString(tr("Warning Time;Moderator;User Name;Reason")).split(";"));
|
||||
|
||||
ServerInfo_Warning warn;
|
||||
for (int i = 0; i < response.warn_list_size(); ++i) {
|
||||
warn = response.warn_list(i);
|
||||
table->setItem(i, 0, new QTableWidgetItem(QString::fromStdString(warn.time_of())));
|
||||
table->setItem(i, 1, new QTableWidgetItem(QString::fromStdString(warn.admin_name())));
|
||||
table->setItem(i, 2, new QTableWidgetItem(QString::fromStdString(warn.user_name())));
|
||||
table->setItem(i, 3, new QTableWidgetItem(QString::fromStdString(warn.reason())));
|
||||
}
|
||||
|
||||
table->resizeColumnsToContents();
|
||||
table->setMinimumSize(table->horizontalHeader()->length() + (table->columnCount() * 5),
|
||||
table->verticalHeader()->length() + (table->rowCount() * 3));
|
||||
table->show();
|
||||
} else
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Warning History"),
|
||||
tr("User has never been warned."));
|
||||
|
||||
} else
|
||||
QMessageBox::critical(static_cast<QWidget *>(parent()), tr("Warning History"),
|
||||
tr("Failed to collect warning information."));
|
||||
}
|
||||
|
||||
void UserContextMenu::getAdminNotes_processResponse(const Response &resp)
|
||||
{
|
||||
const Response_GetAdminNotes &response = resp.GetExtension(Response_GetAdminNotes::ext);
|
||||
|
||||
if (resp.response_code() != Response::RespOk) {
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Failed"), tr("Failed to get admin notes."));
|
||||
return;
|
||||
}
|
||||
|
||||
auto *dlg = new AdminNotesDialog(QString::fromStdString(response.user_name()),
|
||||
QString::fromStdString(response.notes()), static_cast<QWidget *>(parent()));
|
||||
connect(dlg, &AdminNotesDialog::accepted, this, &UserContextMenu::updateAdminNotes_dialogFinished);
|
||||
dlg->show();
|
||||
}
|
||||
|
||||
void UserContextMenu::adjustMod_processUserResponse(const Response &resp, const CommandContainer &commandContainer)
|
||||
{
|
||||
|
||||
const Command_AdjustMod &cmd = commandContainer.admin_command(0).GetExtension(Command_AdjustMod::ext);
|
||||
|
||||
if (resp.response_code() == Response::RespOk) {
|
||||
if (cmd.should_be_mod() || cmd.should_be_judge()) {
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Success"),
|
||||
tr("Successfully promoted user."));
|
||||
} else {
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Success"), tr("Successfully demoted user."));
|
||||
}
|
||||
|
||||
} else {
|
||||
if (cmd.should_be_mod() || cmd.should_be_judge()) {
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Failed"), tr("Failed to promote user."));
|
||||
} else {
|
||||
QMessageBox::information(static_cast<QWidget *>(parent()), tr("Failed"), tr("Failed to demote user."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UserContextMenu::banUser_dialogFinished()
|
||||
{
|
||||
BanDialog *dlg = static_cast<BanDialog *>(sender());
|
||||
|
||||
Command_BanFromServer cmd;
|
||||
cmd.set_user_name(dlg->getBanName().toStdString());
|
||||
cmd.set_address(dlg->getBanIP().toStdString());
|
||||
cmd.set_minutes(dlg->getMinutes());
|
||||
cmd.set_reason(dlg->getReason().toStdString());
|
||||
cmd.set_visible_reason(dlg->getVisibleReason().toStdString());
|
||||
cmd.set_clientid(dlg->getBanId().toStdString());
|
||||
int removeAmount = dlg->getDeleteMessages();
|
||||
if (removeAmount != 0) {
|
||||
cmd.set_remove_messages(removeAmount);
|
||||
}
|
||||
|
||||
client->sendCommand(client->prepareModeratorCommand(cmd));
|
||||
}
|
||||
|
||||
void UserContextMenu::warnUser_dialogFinished()
|
||||
{
|
||||
WarningDialog *dlg = static_cast<WarningDialog *>(sender());
|
||||
|
||||
if (dlg->getName().isEmpty() || userListProxy->getOwnUsername().simplified().isEmpty())
|
||||
return;
|
||||
|
||||
Command_WarnUser cmd;
|
||||
cmd.set_user_name(dlg->getName().toStdString());
|
||||
cmd.set_reason(dlg->getReason().toStdString());
|
||||
cmd.set_clientid(dlg->getWarnID().toStdString());
|
||||
int removeAmount = dlg->getDeleteMessages();
|
||||
if (removeAmount != 0) {
|
||||
cmd.set_remove_messages(removeAmount);
|
||||
}
|
||||
|
||||
client->sendCommand(client->prepareModeratorCommand(cmd));
|
||||
}
|
||||
|
||||
void UserContextMenu::updateAdminNotes_dialogFinished()
|
||||
{
|
||||
auto *dlg = static_cast<AdminNotesDialog *>(sender());
|
||||
|
||||
Command_UpdateAdminNotes cmd;
|
||||
cmd.set_user_name(dlg->getName().toStdString());
|
||||
cmd.set_notes(dlg->getNotes().toStdString());
|
||||
|
||||
client->sendCommand(client->prepareModeratorCommand(cmd));
|
||||
}
|
||||
|
||||
void UserContextMenu::showContextMenu(const QPoint &pos,
|
||||
const QString &userName,
|
||||
UserLevelFlags userLevel,
|
||||
bool online,
|
||||
int playerId)
|
||||
{
|
||||
showContextMenu(pos, userName, userLevel, online, playerId, QString(), nullptr);
|
||||
}
|
||||
|
||||
void UserContextMenu::showContextMenu(const QPoint &pos,
|
||||
const QString &userName,
|
||||
UserLevelFlags userLevel,
|
||||
ChatView *chatView)
|
||||
{
|
||||
showContextMenu(pos, userName, userLevel, true, -1, QString(), chatView);
|
||||
}
|
||||
|
||||
void UserContextMenu::showContextMenu(const QPoint &pos,
|
||||
const QString &userName,
|
||||
UserLevelFlags userLevel,
|
||||
bool online,
|
||||
int playerId,
|
||||
const QString &deckHash,
|
||||
ChatView *chatView)
|
||||
{
|
||||
QAction *aCopyToClipBoard = nullptr, *aRemoveMessages = nullptr;
|
||||
aUserName->setText(userName);
|
||||
|
||||
auto *menu = new QMenu(static_cast<QWidget *>(parent()));
|
||||
menu->addAction(aUserName);
|
||||
menu->addSeparator();
|
||||
if (!deckHash.isEmpty()) {
|
||||
aCopyToClipBoard = new QAction(tr("Copy hash to clipboard"), this);
|
||||
menu->addAction(aCopyToClipBoard);
|
||||
}
|
||||
menu->addAction(aDetails);
|
||||
menu->addAction(aShowGames);
|
||||
menu->addAction(aChat);
|
||||
if (userLevel.testFlag(ServerInfo_User::IsRegistered) && userListProxy->isOwnUserRegistered()) {
|
||||
menu->addSeparator();
|
||||
if (userListProxy->isUserBuddy(userName)) {
|
||||
menu->addAction(aRemoveFromBuddyList);
|
||||
} else {
|
||||
menu->addAction(aAddToBuddyList);
|
||||
}
|
||||
if (userListProxy->isUserIgnored(userName)) {
|
||||
menu->addAction(aRemoveFromIgnoreList);
|
||||
} else {
|
||||
menu->addAction(aAddToIgnoreList);
|
||||
}
|
||||
}
|
||||
if (chatView != nullptr) {
|
||||
aRemoveMessages = new QAction(tr("Remove this user's messages"), this);
|
||||
menu->addAction(aRemoveMessages);
|
||||
}
|
||||
if (game && (game->isHost() || !tabSupervisor->getAdminLocked())) {
|
||||
menu->addSeparator();
|
||||
menu->addAction(aKick);
|
||||
}
|
||||
if (!tabSupervisor->getAdminLocked()) {
|
||||
menu->addSeparator();
|
||||
menu->addAction(aWarnUser);
|
||||
menu->addAction(aWarnHistory);
|
||||
menu->addSeparator();
|
||||
menu->addAction(aBan);
|
||||
menu->addAction(aBanHistory);
|
||||
menu->addSeparator();
|
||||
menu->addAction(aGetAdminNotes);
|
||||
|
||||
menu->addSeparator();
|
||||
if (userLevel.testFlag(ServerInfo_User::IsModerator) &&
|
||||
(tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsAdmin)) {
|
||||
menu->addAction(aDemoteFromMod);
|
||||
|
||||
} else if (userLevel.testFlag(ServerInfo_User::IsRegistered) &&
|
||||
(tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsAdmin)) {
|
||||
menu->addAction(aPromoteToMod);
|
||||
}
|
||||
|
||||
if (userLevel.testFlag(ServerInfo_User::IsJudge) &&
|
||||
(tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsAdmin)) {
|
||||
menu->addAction(aDemoteFromJudge);
|
||||
|
||||
} else if (userLevel.testFlag(ServerInfo_User::IsRegistered) &&
|
||||
(tabSupervisor->getUserInfo()->user_level() & ServerInfo_User::IsAdmin)) {
|
||||
menu->addAction(aPromoteToJudge);
|
||||
}
|
||||
}
|
||||
bool anotherUser = userName != userListProxy->getOwnUsername();
|
||||
aDetails->setEnabled(true);
|
||||
aChat->setEnabled(anotherUser && online);
|
||||
aShowGames->setEnabled(online);
|
||||
aAddToBuddyList->setEnabled(anotherUser);
|
||||
aRemoveFromBuddyList->setEnabled(anotherUser);
|
||||
aAddToIgnoreList->setEnabled(anotherUser);
|
||||
aRemoveFromIgnoreList->setEnabled(anotherUser);
|
||||
aKick->setEnabled(anotherUser);
|
||||
aWarnUser->setEnabled(anotherUser);
|
||||
aWarnHistory->setEnabled(anotherUser);
|
||||
aBan->setEnabled(anotherUser);
|
||||
aBanHistory->setEnabled(anotherUser);
|
||||
aGetAdminNotes->setEnabled(anotherUser);
|
||||
aPromoteToMod->setEnabled(anotherUser);
|
||||
aDemoteFromMod->setEnabled(anotherUser);
|
||||
|
||||
QAction *actionClicked = menu->exec(pos);
|
||||
if (actionClicked == nullptr) {
|
||||
} else if (actionClicked == aDetails) {
|
||||
UserInfoBox *infoWidget =
|
||||
new UserInfoBox(client, false, static_cast<QWidget *>(parent()),
|
||||
Qt::Dialog | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
|
||||
infoWidget->setAttribute(Qt::WA_DeleteOnClose);
|
||||
infoWidget->updateInfo(userName);
|
||||
} else if (actionClicked == aChat) {
|
||||
emit openMessageDialog(userName, true);
|
||||
} else if (actionClicked == aShowGames) {
|
||||
Command_GetGamesOfUser cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::gamesOfUserReceived);
|
||||
|
||||
client->sendCommand(pend);
|
||||
} else if (actionClicked == aAddToBuddyList) {
|
||||
Command_AddToList cmd;
|
||||
cmd.set_list("buddy");
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
||||
client->sendCommand(client->prepareSessionCommand(cmd));
|
||||
} else if (actionClicked == aRemoveFromBuddyList) {
|
||||
Command_RemoveFromList cmd;
|
||||
cmd.set_list("buddy");
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
||||
client->sendCommand(client->prepareSessionCommand(cmd));
|
||||
} else if (actionClicked == aAddToIgnoreList) {
|
||||
Command_AddToList cmd;
|
||||
cmd.set_list("ignore");
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
||||
client->sendCommand(client->prepareSessionCommand(cmd));
|
||||
} else if (actionClicked == aRemoveFromIgnoreList) {
|
||||
Command_RemoveFromList cmd;
|
||||
cmd.set_list("ignore");
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
||||
client->sendCommand(client->prepareSessionCommand(cmd));
|
||||
} else if (actionClicked == aKick) {
|
||||
Command_KickFromGame cmd;
|
||||
cmd.set_player_id(playerId);
|
||||
|
||||
game->getGameEventHandler()->sendGameCommand(cmd);
|
||||
} else if (actionClicked == aBan) {
|
||||
Command_GetUserInfo cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::banUser_processUserInfoResponse);
|
||||
client->sendCommand(pend);
|
||||
} else if (actionClicked == aPromoteToMod || actionClicked == aDemoteFromMod) {
|
||||
Command_AdjustMod cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
cmd.set_should_be_mod(actionClicked == aPromoteToMod);
|
||||
|
||||
PendingCommand *pend = client->prepareAdminCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::adjustMod_processUserResponse);
|
||||
client->sendCommand(pend);
|
||||
} else if (actionClicked == aPromoteToJudge || actionClicked == aDemoteFromJudge) {
|
||||
Command_AdjustMod cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
cmd.set_should_be_judge(actionClicked == aPromoteToJudge);
|
||||
|
||||
PendingCommand *pend = client->prepareAdminCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::adjustMod_processUserResponse);
|
||||
client->sendCommand(pend);
|
||||
} else if (actionClicked == aBanHistory) {
|
||||
Command_GetBanHistory cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
PendingCommand *pend = client->prepareModeratorCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::banUserHistory_processResponse);
|
||||
client->sendCommand(pend);
|
||||
} else if (actionClicked == aWarnUser) {
|
||||
Command_GetUserInfo cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::warnUser_processUserInfoResponse);
|
||||
client->sendCommand(pend);
|
||||
} else if (actionClicked == aWarnHistory) {
|
||||
Command_GetWarnHistory cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
PendingCommand *pend = client->prepareModeratorCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::warnUserHistory_processResponse);
|
||||
client->sendCommand(pend);
|
||||
} else if (actionClicked == aGetAdminNotes) {
|
||||
Command_GetAdminNotes cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
auto *pend = client->prepareModeratorCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserContextMenu::getAdminNotes_processResponse);
|
||||
client->sendCommand(pend);
|
||||
|
||||
} else if (actionClicked == aCopyToClipBoard) {
|
||||
QClipboard *clipboard = QGuiApplication::clipboard();
|
||||
clipboard->setText(deckHash);
|
||||
} else if (actionClicked == aRemoveMessages) {
|
||||
chatView->redactMessages(userName, -1);
|
||||
}
|
||||
|
||||
delete menu;
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* @file user_context_menu.h
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef USER_CONTEXT_MENU_H
|
||||
#define USER_CONTEXT_MENU_H
|
||||
|
||||
#include <QObject>
|
||||
#include <libcockatrice/network/server/remote/user_level.h>
|
||||
|
||||
class AbstractGame;
|
||||
class UserListProxy;
|
||||
class AbstractClient;
|
||||
class ChatView;
|
||||
class CommandContainer;
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class QPoint;
|
||||
class Response;
|
||||
class ServerInfo_User;
|
||||
class TabSupervisor;
|
||||
|
||||
class UserContextMenu : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
AbstractClient *client;
|
||||
TabSupervisor *tabSupervisor;
|
||||
const UserListProxy *userListProxy;
|
||||
AbstractGame *game;
|
||||
|
||||
QAction *aUserName;
|
||||
QAction *aDetails;
|
||||
QAction *aShowGames;
|
||||
QAction *aChat;
|
||||
QAction *aAddToBuddyList, *aRemoveFromBuddyList;
|
||||
QAction *aAddToIgnoreList, *aRemoveFromIgnoreList;
|
||||
QAction *aKick;
|
||||
QAction *aBan, *aBanHistory;
|
||||
QAction *aPromoteToMod, *aDemoteFromMod;
|
||||
QAction *aPromoteToJudge, *aDemoteFromJudge;
|
||||
QAction *aWarnUser, *aWarnHistory;
|
||||
QAction *aGetAdminNotes;
|
||||
signals:
|
||||
void openMessageDialog(const QString &userName, bool focus);
|
||||
private slots:
|
||||
void banUser_processUserInfoResponse(const Response &resp);
|
||||
void warnUser_processGetWarningsListResponse(const Response &r);
|
||||
void warnUser_processUserInfoResponse(const Response &resp);
|
||||
void banUserHistory_processResponse(const Response &resp);
|
||||
void warnUserHistory_processResponse(const Response &resp);
|
||||
void getAdminNotes_processResponse(const Response &resp);
|
||||
void adjustMod_processUserResponse(const Response &resp, const CommandContainer &commandContainer);
|
||||
void banUser_dialogFinished();
|
||||
void warnUser_dialogFinished();
|
||||
void updateAdminNotes_dialogFinished();
|
||||
void gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer);
|
||||
|
||||
public:
|
||||
UserContextMenu(TabSupervisor *_tabSupervisor, QWidget *_parent, AbstractGame *_game = 0);
|
||||
void retranslateUi();
|
||||
void showContextMenu(const QPoint &pos,
|
||||
const QString &userName,
|
||||
UserLevelFlags userLevel,
|
||||
bool online = true,
|
||||
int playerId = -1);
|
||||
void showContextMenu(const QPoint &pos, const QString &userName, UserLevelFlags userLevel, ChatView *chatView);
|
||||
void showContextMenu(const QPoint &pos,
|
||||
const QString &userName,
|
||||
UserLevelFlags userLevel,
|
||||
bool online,
|
||||
int playerId,
|
||||
const QString &deckHash,
|
||||
ChatView *chatView = nullptr);
|
||||
};
|
||||
|
||||
#endif
|
||||
385
cockatrice/src/interface/widgets/server/user/user_info_box.cpp
Normal file
385
cockatrice/src/interface/widgets/server/user/user_info_box.cpp
Normal file
|
|
@ -0,0 +1,385 @@
|
|||
#include "user_info_box.h"
|
||||
|
||||
#include "../../dialogs/dlg_edit_avatar.h"
|
||||
#include "../../dialogs/dlg_edit_password.h"
|
||||
#include "../../dialogs/dlg_edit_user.h"
|
||||
#include "../../interface/pixel_map_generator.h"
|
||||
#include "../../interface/widgets/utility/get_text_with_max.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_user_info.pb.h>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
||||
#include <libcockatrice/protocol/pb/session_commands.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
#include <libcockatrice/utility/passwordhasher.h>
|
||||
|
||||
UserInfoBox::UserInfoBox(AbstractClient *_client, bool _editable, QWidget *parent, Qt::WindowFlags flags)
|
||||
: QWidget(parent, flags), client(_client), editable(_editable)
|
||||
{
|
||||
QFont nameFont = nameLabel.font();
|
||||
nameFont.setBold(true);
|
||||
nameFont.setPointSizeF(nameFont.pointSizeF() * 1.5);
|
||||
nameLabel.setFont(nameFont);
|
||||
|
||||
auto *userIconAndNameLayout = new QHBoxLayout;
|
||||
userIconAndNameLayout->addWidget(&userLevelIcon, 0, Qt::AlignCenter);
|
||||
userIconAndNameLayout->addWidget(&nameLabel, 1);
|
||||
userIconAndNameLayout->addStretch();
|
||||
|
||||
avatarPic.setMinimumSize(200, 200);
|
||||
avatarPic.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
avatarPic.setAlignment(Qt::AlignCenter);
|
||||
|
||||
auto *avatarLayout = new QHBoxLayout;
|
||||
avatarLayout->setContentsMargins(0, 0, 0, 0);
|
||||
avatarLayout->addStretch(1);
|
||||
avatarLayout->addWidget(&avatarPic, 3);
|
||||
avatarLayout->addStretch(1);
|
||||
|
||||
auto *mainLayout = new QGridLayout;
|
||||
mainLayout->addLayout(avatarLayout, 0, 0, 1, 3);
|
||||
mainLayout->addLayout(userIconAndNameLayout, 1, 0, 1, 3);
|
||||
mainLayout->addWidget(&realNameLabel1, 2, 0, 1, 1);
|
||||
mainLayout->addWidget(&realNameLabel2, 2, 1, 1, 2);
|
||||
mainLayout->addWidget(&countryLabel1, 3, 0, 1, 1);
|
||||
mainLayout->addWidget(&countryLabel2, 3, 1, 1, 1, Qt::AlignCenter);
|
||||
mainLayout->addWidget(&countryLabel3, 3, 2, 1, 1);
|
||||
mainLayout->addWidget(&userLevelLabel1, 4, 0, 1, 1);
|
||||
mainLayout->addWidget(&userLevelLabel2, 4, 1, 1, 2);
|
||||
mainLayout->addWidget(&accountAgeLabel1, 5, 0, 1, 1);
|
||||
mainLayout->addWidget(&accountAgeLabel2, 5, 1, 1, 2);
|
||||
mainLayout->setColumnStretch(2, 10);
|
||||
|
||||
if (editable) {
|
||||
auto *buttonsLayout = new QHBoxLayout;
|
||||
buttonsLayout->addWidget(&editButton);
|
||||
buttonsLayout->addWidget(&passwordButton);
|
||||
buttonsLayout->addWidget(&avatarButton);
|
||||
mainLayout->addLayout(buttonsLayout, 7, 0, 1, 3);
|
||||
|
||||
connect(&editButton, &QPushButton::clicked, this, &UserInfoBox::actEdit);
|
||||
connect(&passwordButton, &QPushButton::clicked, this, &UserInfoBox::actPassword);
|
||||
connect(&avatarButton, &QPushButton::clicked, this, &UserInfoBox::actAvatar);
|
||||
}
|
||||
|
||||
setWindowTitle(tr("User Information"));
|
||||
setLayout(mainLayout);
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void UserInfoBox::retranslateUi()
|
||||
{
|
||||
realNameLabel1.setText(tr("Real Name:"));
|
||||
countryLabel1.setText(tr("Location:"));
|
||||
userLevelLabel1.setText(tr("User Level:"));
|
||||
accountAgeLabel1.setText(tr("Account Age:"));
|
||||
|
||||
editButton.setText(tr("Edit"));
|
||||
passwordButton.setText(tr("Change password"));
|
||||
avatarButton.setText(tr("Change avatar"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the default profile pic that is used when the user doesn't have a custom pic
|
||||
*/
|
||||
static QPixmap createDefaultAvatar(int height, const ServerInfo_User &user)
|
||||
{
|
||||
return UserLevelPixmapGenerator::generatePixmap(height, UserLevelFlags(user.user_level()), user.pawn_colors(),
|
||||
false, QString::fromStdString(user.privlevel()));
|
||||
}
|
||||
|
||||
void UserInfoBox::updateInfo(const ServerInfo_User &user)
|
||||
{
|
||||
currentUserInfo = &user;
|
||||
|
||||
const UserLevelFlags userLevel(user.user_level());
|
||||
|
||||
const std::string &bmp = user.avatar_bmp();
|
||||
if (!avatarPixmap.loadFromData((const uchar *)bmp.data(), static_cast<uint>(bmp.size()))) {
|
||||
avatarPixmap = createDefaultAvatar(64, user);
|
||||
hasAvatar = false;
|
||||
} else {
|
||||
hasAvatar = true;
|
||||
}
|
||||
|
||||
nameLabel.setText(QString::fromStdString(user.name()));
|
||||
realNameLabel2.setText(QString::fromStdString(user.real_name()));
|
||||
QString country = QString::fromStdString(user.country());
|
||||
|
||||
if (country.length() != 0) {
|
||||
countryLabel2.setPixmap(CountryPixmapGenerator::generatePixmap(13, country));
|
||||
countryLabel3.setText(QString("%1").arg(country.toUpper()));
|
||||
} else {
|
||||
countryLabel2.setText("");
|
||||
countryLabel3.setText("");
|
||||
}
|
||||
|
||||
userLevelIcon.setPixmap(UserLevelPixmapGenerator::generatePixmap(15, userLevel, user.pawn_colors(), false,
|
||||
QString::fromStdString(user.privlevel())));
|
||||
QString userLevelText;
|
||||
if (userLevel.testFlag(ServerInfo_User::IsAdmin))
|
||||
userLevelText = tr("Administrator");
|
||||
else if (userLevel.testFlag(ServerInfo_User::IsModerator))
|
||||
userLevelText = tr("Moderator");
|
||||
else if (userLevel.testFlag(ServerInfo_User::IsRegistered))
|
||||
userLevelText = tr("Registered user");
|
||||
else
|
||||
userLevelText = tr("Unregistered user");
|
||||
|
||||
if (userLevel.testFlag(ServerInfo_User::IsJudge))
|
||||
userLevelText += " | " + tr("Judge");
|
||||
|
||||
if (user.has_privlevel() && user.privlevel() != "NONE") {
|
||||
userLevelText += " | " + QString("%1").arg(user.privlevel().c_str());
|
||||
}
|
||||
|
||||
userLevelLabel2.setText(userLevelText);
|
||||
|
||||
QString accountAgeString = tr("Unregistered user");
|
||||
if (userLevel.testFlag(ServerInfo_User::IsAdmin) || userLevel.testFlag(ServerInfo_User::IsModerator) ||
|
||||
userLevel.testFlag(ServerInfo_User::IsRegistered)) {
|
||||
accountAgeString = getAgeString(user.accountage_secs());
|
||||
}
|
||||
accountAgeLabel2.setText(accountAgeString);
|
||||
}
|
||||
|
||||
QString UserInfoBox::getAgeString(int ageSeconds)
|
||||
{
|
||||
QString accountAgeString = tr("Unknown");
|
||||
if (ageSeconds <= 0)
|
||||
return accountAgeString;
|
||||
|
||||
// secsSinceEpoch is in utc
|
||||
auto secsSinceEpoch = QDateTime::currentSecsSinceEpoch() - ageSeconds;
|
||||
// the date is in local time, fromSecsSinceEpoch expects a timestamp from utc and converts it to local time
|
||||
auto date = QDateTime::fromSecsSinceEpoch(secsSinceEpoch).date();
|
||||
if (!date.isValid())
|
||||
return accountAgeString;
|
||||
|
||||
// now can be local time as the date is also local time
|
||||
auto now = QDate::currentDate();
|
||||
auto daysAndYears = getDaysAndYearsBetween(date, now);
|
||||
|
||||
QString dateString = QLocale().toString(date, QLocale::ShortFormat);
|
||||
QString yearString;
|
||||
if (daysAndYears.second > 0) {
|
||||
yearString = tr("%n Year(s), ", "amount of years (only shown if more than 0)", daysAndYears.second);
|
||||
}
|
||||
accountAgeString =
|
||||
tr("%10%n Day(s) %20", "amount of years (if more than 0), amount of days, date in local short format",
|
||||
daysAndYears.first)
|
||||
.arg(yearString)
|
||||
.arg(dateString);
|
||||
return accountAgeString;
|
||||
}
|
||||
|
||||
void UserInfoBox::updateInfo(const QString &userName)
|
||||
{
|
||||
Command_GetUserInfo cmd;
|
||||
cmd.set_user_name(userName.toStdString());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserInfoBox::processResponse);
|
||||
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void UserInfoBox::processResponse(const Response &r)
|
||||
{
|
||||
const Response_GetUserInfo &response = r.GetExtension(Response_GetUserInfo::ext);
|
||||
updateInfo(response.user_info());
|
||||
resize(sizeHint());
|
||||
show();
|
||||
}
|
||||
|
||||
void UserInfoBox::actEdit()
|
||||
{
|
||||
Command_GetUserInfo cmd;
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserInfoBox::actEditInternal);
|
||||
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void UserInfoBox::actEditInternal(const Response &r)
|
||||
{
|
||||
const Response_GetUserInfo &response = r.GetExtension(Response_GetUserInfo::ext);
|
||||
const ServerInfo_User &user = response.user_info();
|
||||
|
||||
QString email = QString::fromStdString(user.email());
|
||||
QString country = QString::fromStdString(user.country());
|
||||
QString realName = QString::fromStdString(user.real_name());
|
||||
|
||||
DlgEditUser dlg(this, email, country, realName);
|
||||
if (!dlg.exec())
|
||||
return;
|
||||
|
||||
Command_AccountEdit cmd;
|
||||
cmd.set_real_name(dlg.getRealName().toStdString());
|
||||
if (client->getServerSupportsPasswordHash()) {
|
||||
if (email != dlg.getEmail()) {
|
||||
// real password is required to change email
|
||||
bool ok = false;
|
||||
QString password =
|
||||
getTextWithMax(this, tr("Enter Password"),
|
||||
tr("Password verification is required in order to change your email address"),
|
||||
QLineEdit::Password, "", &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
cmd.set_password_check(password.toStdString());
|
||||
cmd.set_email(dlg.getEmail().toStdString());
|
||||
} // servers that support password hash do not require all fields to be filled anymore
|
||||
} else {
|
||||
cmd.set_email(dlg.getEmail().toStdString());
|
||||
}
|
||||
cmd.set_country(dlg.getCountry().toStdString());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserInfoBox::processEditResponse);
|
||||
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void UserInfoBox::actPassword()
|
||||
{
|
||||
DlgEditPassword dlg(this);
|
||||
if (!dlg.exec())
|
||||
return;
|
||||
|
||||
auto oldPassword = dlg.getOldPassword();
|
||||
auto newPassword = dlg.getNewPassword();
|
||||
|
||||
if (client->getServerSupportsPasswordHash()) {
|
||||
Command_RequestPasswordSalt cmd;
|
||||
cmd.set_user_name(client->getUserName().toStdString());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, [=, this](const Response &response) {
|
||||
if (response.response_code() == Response::RespOk) {
|
||||
changePassword(oldPassword, newPassword);
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("An error occurred while trying to update your user information."));
|
||||
}
|
||||
});
|
||||
client->sendCommand(pend);
|
||||
} else {
|
||||
changePassword(oldPassword, newPassword);
|
||||
}
|
||||
}
|
||||
|
||||
void UserInfoBox::changePassword(const QString &oldPassword, const QString &newPassword)
|
||||
{
|
||||
Command_AccountPassword cmd;
|
||||
cmd.set_old_password(oldPassword.toStdString());
|
||||
if (client->getServerSupportsPasswordHash()) {
|
||||
auto passwordSalt = PasswordHasher::generateRandomSalt();
|
||||
QString hashedPassword = PasswordHasher::computeHash(newPassword, passwordSalt);
|
||||
cmd.set_hashed_new_password(hashedPassword.toStdString());
|
||||
} else {
|
||||
cmd.set_new_password(newPassword.toStdString());
|
||||
}
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserInfoBox::processPasswordResponse);
|
||||
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void UserInfoBox::actAvatar()
|
||||
{
|
||||
DlgEditAvatar dlg(this);
|
||||
if (!dlg.exec())
|
||||
return;
|
||||
|
||||
Command_AccountImage cmd;
|
||||
cmd.set_image(dlg.getImage().data(), dlg.getImage().size());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &UserInfoBox::processAvatarResponse);
|
||||
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void UserInfoBox::processEditResponse(const Response &r)
|
||||
{
|
||||
switch (r.response_code()) {
|
||||
case Response::RespOk:
|
||||
updateInfo(nameLabel.text());
|
||||
QMessageBox::information(this, tr("Information"), tr("User information updated."));
|
||||
break;
|
||||
case Response::RespFunctionNotAllowed:
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("This server does not permit you to update your user informations."));
|
||||
break;
|
||||
case Response::RespWrongPassword:
|
||||
QMessageBox::critical(this, tr("Error"), tr("The entered password does not match your account."));
|
||||
break;
|
||||
case Response::RespInternalError:
|
||||
default:
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("An error occurred while trying to update your user information."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UserInfoBox::processPasswordResponse(const Response &r)
|
||||
{
|
||||
switch (r.response_code()) {
|
||||
case Response::RespOk:
|
||||
QMessageBox::information(this, tr("Information"), tr("Password changed."));
|
||||
break;
|
||||
case Response::RespFunctionNotAllowed:
|
||||
QMessageBox::critical(this, tr("Error"), tr("This server does not permit you to change your password."));
|
||||
break;
|
||||
case Response::RespPasswordTooShort:
|
||||
QMessageBox::critical(this, tr("Error"), tr("The new password is too short."));
|
||||
break;
|
||||
case Response::RespWrongPassword:
|
||||
QMessageBox::critical(this, tr("Error"), tr("The old password is incorrect."));
|
||||
break;
|
||||
case Response::RespInternalError:
|
||||
default:
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("An error occurred while trying to update your user information."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UserInfoBox::processAvatarResponse(const Response &r)
|
||||
{
|
||||
switch (r.response_code()) {
|
||||
case Response::RespOk:
|
||||
updateInfo(nameLabel.text());
|
||||
QMessageBox::information(this, tr("Information"), tr("Avatar updated."));
|
||||
break;
|
||||
case Response::RespFunctionNotAllowed:
|
||||
QMessageBox::critical(this, tr("Error"), tr("This server does not permit you to update your avatar."));
|
||||
break;
|
||||
case Response::RespInternalError:
|
||||
default:
|
||||
QMessageBox::critical(this, tr("Error"), tr("An error occured while trying to updater your avatar."));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UserInfoBox::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QPixmap resizedPixmap;
|
||||
if (hasAvatar) {
|
||||
resizedPixmap = avatarPixmap.scaled(avatarPic.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
} else {
|
||||
int height = qMin(avatarPic.size().width(), avatarPic.size().height());
|
||||
resizedPixmap = createDefaultAvatar(height, *currentUserInfo);
|
||||
}
|
||||
avatarPic.setPixmap(resizedPixmap);
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
63
cockatrice/src/interface/widgets/server/user/user_info_box.h
Normal file
63
cockatrice/src/interface/widgets/server/user/user_info_box.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/**
|
||||
* @file user_info_box.h
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef USERINFOBOX_H
|
||||
#define USERINFOBOX_H
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
|
||||
class ServerInfo_User;
|
||||
class AbstractClient;
|
||||
class Response;
|
||||
|
||||
class UserInfoBox : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
AbstractClient *client;
|
||||
bool editable;
|
||||
QLabel avatarPic, userLevelIcon, nameLabel, realNameLabel1, realNameLabel2, countryLabel1, countryLabel2,
|
||||
countryLabel3, userLevelLabel1, userLevelLabel2, accountAgeLabel1, accountAgeLabel2;
|
||||
QPushButton editButton, passwordButton, avatarButton;
|
||||
QPixmap avatarPixmap;
|
||||
bool hasAvatar;
|
||||
const ServerInfo_User *currentUserInfo;
|
||||
|
||||
static QString getAgeString(int ageSeconds);
|
||||
|
||||
public:
|
||||
UserInfoBox(AbstractClient *_client, bool editable, QWidget *parent = nullptr, Qt::WindowFlags flags = {});
|
||||
void retranslateUi();
|
||||
|
||||
inline static QPair<int, int> getDaysAndYearsBetween(const QDate &then, const QDate &now)
|
||||
{
|
||||
int years = now.addDays(1 - then.dayOfYear()).year() - then.year(); // there is no yearsTo
|
||||
int days = then.addYears(years).daysTo(now);
|
||||
return {days, years};
|
||||
}
|
||||
private slots:
|
||||
void processResponse(const Response &r);
|
||||
void processEditResponse(const Response &r);
|
||||
void processPasswordResponse(const Response &r);
|
||||
void processAvatarResponse(const Response &r);
|
||||
|
||||
void actEdit();
|
||||
void actEditInternal(const Response &r);
|
||||
void actPassword();
|
||||
void actAvatar();
|
||||
public slots:
|
||||
void updateInfo(const ServerInfo_User &user);
|
||||
void updateInfo(const QString &userName);
|
||||
|
||||
private:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
void changePassword(const QString &oldPassword, const QString &newPassword);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
#include "user_info_connection.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <utility>
|
||||
|
||||
UserConnection_Information::UserConnection_Information() = default;
|
||||
|
||||
UserConnection_Information::UserConnection_Information(QString _saveName,
|
||||
QString _serverName,
|
||||
QString _portNum,
|
||||
QString _userName,
|
||||
QString _pass,
|
||||
bool _savePass,
|
||||
QString _site)
|
||||
: saveName(std::move(_saveName)), server(std::move(_serverName)), port(std::move(_portNum)),
|
||||
username(std::move(_userName)), password(std::move(_pass)), savePassword(_savePass), site(std::move(_site))
|
||||
{
|
||||
}
|
||||
|
||||
QMap<QString, std::pair<QString, UserConnection_Information>> UserConnection_Information::getServerInfo()
|
||||
{
|
||||
QMap<QString, std::pair<QString, UserConnection_Information>> serverList;
|
||||
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
|
||||
int size = servers.getValue("totalServers", "server", "server_details").toInt() + 1;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
QString _saveName = servers.getValue(QString("saveName%1").arg(i), "server", "server_details").toString();
|
||||
QString serverName = servers.getValue(QString("server%1").arg(i), "server", "server_details").toString();
|
||||
QString portNum = servers.getValue(QString("port%1").arg(i), "server", "server_details").toString();
|
||||
QString userName = servers.getValue(QString("username%1").arg(i), "server", "server_details").toString();
|
||||
QString pass = servers.getValue(QString("password%1").arg(i), "server", "server_details").toString();
|
||||
bool savePass = servers.getValue(QString("savePassword%1").arg(i), "server", "server_details").toBool();
|
||||
QString _site = servers.getValue(QString("site%1").arg(i), "server", "server_details").toString();
|
||||
|
||||
UserConnection_Information userInfo(_saveName, serverName, portNum, userName, pass, savePass, _site);
|
||||
serverList.insert(_saveName, std::make_pair(serverName, userInfo));
|
||||
}
|
||||
|
||||
return serverList;
|
||||
}
|
||||
|
||||
QStringList UserConnection_Information::getServerInfo(const QString &find)
|
||||
{
|
||||
QStringList _server;
|
||||
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
|
||||
int size = servers.getValue("totalServers", "server", "server_details").toInt() + 1;
|
||||
for (int i = 0; i < size; i++) {
|
||||
QString _saveName = servers.getValue(QString("saveName%1").arg(i), "server", "server_details").toString();
|
||||
|
||||
if (find != _saveName)
|
||||
continue;
|
||||
|
||||
QString serverName = servers.getValue(QString("server%1").arg(i), "server", "server_details").toString();
|
||||
QString portNum = servers.getValue(QString("port%1").arg(i), "server", "server_details").toString();
|
||||
QString userName = servers.getValue(QString("username%1").arg(i), "server", "server_details").toString();
|
||||
QString pass = servers.getValue(QString("password%1").arg(i), "server", "server_details").toString();
|
||||
bool savePass = servers.getValue(QString("savePassword%1").arg(i), "server", "server_details").toBool();
|
||||
QString _site = servers.getValue(QString("site%1").arg(i), "server", "server_details").toString();
|
||||
|
||||
_server.append(_saveName);
|
||||
_server.append(serverName);
|
||||
_server.append(portNum);
|
||||
_server.append(userName);
|
||||
_server.append(pass);
|
||||
_server.append(savePass ? "1" : "0");
|
||||
_server.append(_site);
|
||||
break;
|
||||
}
|
||||
|
||||
if (_server.empty())
|
||||
qCWarning(UserInfoConnectionLog) << "There was a problem!";
|
||||
|
||||
return _server;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/**
|
||||
* @file user_info_connection.h
|
||||
* @ingroup Client
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef USERCONNECTION_INFORMATION_H
|
||||
#define USERCONNECTION_INFORMATION_H
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QLoggingCategory>
|
||||
#include <QSettings>
|
||||
#include <QStandardPaths>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(UserInfoConnectionLog, "user_info_connection");
|
||||
|
||||
class UserConnection_Information
|
||||
{
|
||||
private:
|
||||
QString saveName;
|
||||
QString server;
|
||||
QString port;
|
||||
QString username;
|
||||
QString password;
|
||||
bool savePassword;
|
||||
QString site;
|
||||
|
||||
public:
|
||||
UserConnection_Information();
|
||||
UserConnection_Information(QString, QString, QString, QString, QString, bool, QString);
|
||||
QString getSaveName() const
|
||||
{
|
||||
return saveName;
|
||||
}
|
||||
QString getServer() const
|
||||
{
|
||||
return server;
|
||||
}
|
||||
QString getPort() const
|
||||
{
|
||||
return port;
|
||||
}
|
||||
QString getUsername() const
|
||||
{
|
||||
return username;
|
||||
}
|
||||
QString getPassword() const
|
||||
{
|
||||
return password;
|
||||
}
|
||||
bool getSavePassword() const
|
||||
{
|
||||
return savePassword;
|
||||
}
|
||||
QString getSite() const
|
||||
{
|
||||
return site;
|
||||
}
|
||||
QMap<QString, std::pair<QString, UserConnection_Information>> getServerInfo();
|
||||
QStringList getServerInfo(const QString &find);
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
#include "user_list_manager.h"
|
||||
|
||||
#include "../../client/sound_engine.h"
|
||||
#include "user_info_box.h"
|
||||
|
||||
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||
#include <libcockatrice/protocol/pb/event_add_to_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/event_remove_from_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/event_user_joined.pb.h>
|
||||
#include <libcockatrice/protocol/pb/event_user_left.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_list_users.pb.h>
|
||||
#include <libcockatrice/protocol/pb/session_commands.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
|
||||
UserListManager::UserListManager(AbstractClient *_client, QObject *parent)
|
||||
: QObject(parent), client(_client), ownUserInfo(nullptr)
|
||||
{
|
||||
connect(client, &AbstractClient::userJoinedEventReceived, this, &UserListManager::processUserJoinedEvent);
|
||||
connect(client, &AbstractClient::userLeftEventReceived, this, &UserListManager::processUserLeftEvent);
|
||||
connect(client, &AbstractClient::buddyListReceived, this, &UserListManager::buddyListReceived);
|
||||
connect(client, &AbstractClient::ignoreListReceived, this, &UserListManager::ignoreListReceived);
|
||||
connect(client, &AbstractClient::addToListEventReceived, this, &UserListManager::processAddToListEvent);
|
||||
connect(client, &AbstractClient::removeFromListEventReceived, this, &UserListManager::processRemoveFromListEvent);
|
||||
connect(client, &AbstractClient::userInfoChanged, this, &UserListManager::setOwnUserInfo);
|
||||
}
|
||||
|
||||
UserListManager::~UserListManager()
|
||||
{
|
||||
handleDisconnect();
|
||||
}
|
||||
|
||||
void UserListManager::handleConnect()
|
||||
{
|
||||
populateInitialOnlineUsers();
|
||||
}
|
||||
|
||||
void UserListManager::handleDisconnect()
|
||||
{
|
||||
onlineUsers.clear();
|
||||
buddyUsers.clear();
|
||||
ignoredUsers.clear();
|
||||
|
||||
delete ownUserInfo;
|
||||
ownUserInfo = nullptr;
|
||||
}
|
||||
|
||||
void UserListManager::setOwnUserInfo(const ServerInfo_User &userInfo)
|
||||
{
|
||||
ownUserInfo = new ServerInfo_User(userInfo);
|
||||
}
|
||||
|
||||
void UserListManager::populateInitialOnlineUsers()
|
||||
{
|
||||
PendingCommand *pend = client->prepareSessionCommand(Command_ListUsers());
|
||||
connect(pend, &PendingCommand::finished, this, &UserListManager::processListUsersResponse);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
void UserListManager::processListUsersResponse(const Response &response)
|
||||
{
|
||||
const auto &resp = response.GetExtension(Response_ListUsers::ext);
|
||||
|
||||
const int userListSize = resp.user_list_size();
|
||||
for (int i = 0; i < userListSize; ++i) {
|
||||
const ServerInfo_User &info = resp.user_list(i);
|
||||
const QString &userName = QString::fromStdString(info.name());
|
||||
onlineUsers.insert(userName, info);
|
||||
}
|
||||
}
|
||||
|
||||
void UserListManager::processUserJoinedEvent(const Event_UserJoined &event)
|
||||
{
|
||||
const auto &info = event.user_info();
|
||||
const QString &userName = QString::fromStdString(info.name());
|
||||
onlineUsers.insert(userName, info);
|
||||
}
|
||||
|
||||
void UserListManager::processUserLeftEvent(const Event_UserLeft &event)
|
||||
{
|
||||
const auto &userName = QString::fromStdString(event.name());
|
||||
onlineUsers.remove(userName);
|
||||
}
|
||||
|
||||
void UserListManager::buddyListReceived(const QList<ServerInfo_User> &_buddyList)
|
||||
{
|
||||
for (const auto &user : _buddyList) {
|
||||
const auto &userName = QString::fromStdString(user.name());
|
||||
buddyUsers.insert(userName, user);
|
||||
}
|
||||
}
|
||||
|
||||
void UserListManager::ignoreListReceived(const QList<ServerInfo_User> &_ignoreList)
|
||||
{
|
||||
for (const auto &user : _ignoreList) {
|
||||
const auto &userName = QString::fromStdString(user.name());
|
||||
ignoredUsers.insert(userName, user);
|
||||
}
|
||||
}
|
||||
|
||||
void UserListManager::processAddToListEvent(const Event_AddToList &event)
|
||||
{
|
||||
const auto &user = event.user_info();
|
||||
const auto &userName = QString::fromStdString(user.name());
|
||||
|
||||
const auto &userListType = QString::fromStdString(event.list_name());
|
||||
|
||||
QMap<QString, ServerInfo_User> *userMap;
|
||||
if (userListType == "buddy") {
|
||||
userMap = &buddyUsers;
|
||||
} else if (userListType == "ignore") {
|
||||
userMap = &ignoredUsers;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
userMap->insert(userName, user);
|
||||
}
|
||||
|
||||
void UserListManager::processRemoveFromListEvent(const Event_RemoveFromList &event)
|
||||
{
|
||||
const auto &userListType = QString::fromStdString(event.list_name());
|
||||
const auto &userName = QString::fromStdString(event.user_name());
|
||||
|
||||
QMap<QString, ServerInfo_User> *userMap;
|
||||
if (userListType == "buddy") {
|
||||
userMap = &buddyUsers;
|
||||
} else if (userListType == "ignore") {
|
||||
userMap = &ignoredUsers;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
userMap->remove(userName);
|
||||
}
|
||||
|
||||
bool UserListManager::isOwnUserRegistered() const
|
||||
{
|
||||
return ownUserInfo != nullptr && (ownUserInfo->user_level() & ServerInfo_User::IsRegistered) != 0;
|
||||
}
|
||||
|
||||
QString UserListManager::getOwnUsername() const
|
||||
{
|
||||
return ownUserInfo != nullptr ? QString::fromStdString(ownUserInfo->name()) : QString();
|
||||
}
|
||||
|
||||
bool UserListManager::isUserBuddy(const QString &userName) const
|
||||
{
|
||||
return buddyUsers.contains(userName);
|
||||
}
|
||||
|
||||
bool UserListManager::isUserIgnored(const QString &userName) const
|
||||
{
|
||||
return ignoredUsers.contains(userName);
|
||||
}
|
||||
|
||||
const ServerInfo_User *UserListManager::getOnlineUser(const QString &userName) const
|
||||
{
|
||||
const QString &userNameToMatchLower = userName.toLower();
|
||||
|
||||
const auto it =
|
||||
std::find_if(onlineUsers.begin(), onlineUsers.end(), [&userNameToMatchLower](const ServerInfo_User &user) {
|
||||
return userNameToMatchLower == QString::fromStdString(user.name()).toLower();
|
||||
});
|
||||
|
||||
if (it != onlineUsers.end()) {
|
||||
return &*it;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
};
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/**
|
||||
* @file user_list_manager.h
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_USER_LIST_MANAGER_H
|
||||
#define COCKATRICE_USER_LIST_MANAGER_H
|
||||
|
||||
#include "user_list_proxy.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
||||
|
||||
class AbstractClient;
|
||||
class Event_AddToList;
|
||||
class Event_ListRooms;
|
||||
class Event_RemoveFromList;
|
||||
class Event_UserJoined;
|
||||
class Event_UserLeft;
|
||||
class Response;
|
||||
class ServerInfo_User;
|
||||
class TabSupervisor;
|
||||
|
||||
class UserListManager : public QObject, public UserListProxy
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
AbstractClient *client;
|
||||
ServerInfo_User *ownUserInfo;
|
||||
QMap<QString, ServerInfo_User> onlineUsers, buddyUsers, ignoredUsers;
|
||||
|
||||
private slots:
|
||||
void setOwnUserInfo(const ServerInfo_User &userInfo);
|
||||
void populateInitialOnlineUsers();
|
||||
void processListUsersResponse(const Response &response);
|
||||
void processUserJoinedEvent(const Event_UserJoined &event);
|
||||
void processUserLeftEvent(const Event_UserLeft &event);
|
||||
void buddyListReceived(const QList<ServerInfo_User> &_buddyList);
|
||||
void ignoreListReceived(const QList<ServerInfo_User> &_ignoreList);
|
||||
void processAddToListEvent(const Event_AddToList &event);
|
||||
void processRemoveFromListEvent(const Event_RemoveFromList &event);
|
||||
|
||||
public:
|
||||
explicit UserListManager(AbstractClient *_client, QObject *parent = nullptr);
|
||||
~UserListManager() override;
|
||||
|
||||
[[nodiscard]] QMap<QString, ServerInfo_User> getAllUsersList() const
|
||||
{
|
||||
return onlineUsers;
|
||||
}
|
||||
[[nodiscard]] QMap<QString, ServerInfo_User> getBuddyList() const
|
||||
{
|
||||
return buddyUsers;
|
||||
}
|
||||
[[nodiscard]] QMap<QString, ServerInfo_User> getIgnoreList() const
|
||||
{
|
||||
return ignoredUsers;
|
||||
}
|
||||
|
||||
bool isOwnUserRegistered() const override;
|
||||
QString getOwnUsername() const override;
|
||||
bool isUserBuddy(const QString &userName) const override;
|
||||
bool isUserIgnored(const QString &userName) const override;
|
||||
const ServerInfo_User *getOnlineUser(const QString &userName) const override;
|
||||
|
||||
public slots:
|
||||
void handleConnect();
|
||||
void handleDisconnect();
|
||||
|
||||
signals:
|
||||
void userLeft(const QString &userName);
|
||||
void userJoined(const ServerInfo_User &userInfo);
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_USER_LIST_MANAGER_H
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* @file user_list_proxy.h
|
||||
* @ingroup UI
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef COCKATRICE_USERLISTPROXY_H
|
||||
#define COCKATRICE_USERLISTPROXY_H
|
||||
|
||||
class QString;
|
||||
class ServerInfo_User;
|
||||
|
||||
/**
|
||||
* Responsible for providing a bare-bones minimal interface into userlist information,
|
||||
* including your current connection to the server as well as buddy/ignore/alluser lists.
|
||||
*/
|
||||
class UserListProxy
|
||||
{
|
||||
public:
|
||||
virtual bool isOwnUserRegistered() const = 0;
|
||||
virtual QString getOwnUsername() const = 0;
|
||||
virtual bool isUserBuddy(const QString &userName) const = 0;
|
||||
virtual bool isUserIgnored(const QString &userName) const = 0;
|
||||
virtual const ServerInfo_User *getOnlineUser(const QString &userName) const = 0; // Can return nullptr
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_USERLISTPROXY_H
|
||||
|
|
@ -0,0 +1,539 @@
|
|||
#include "user_list_widget.h"
|
||||
|
||||
#include "../../interface/pixel_map_generator.h"
|
||||
#include "../../tabs/tab_account.h"
|
||||
#include "../../tabs/tab_supervisor.h"
|
||||
#include "../game_selector.h"
|
||||
#include "user_context_menu.h"
|
||||
#include "user_list_manager.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QMouseEvent>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QSpinBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
#include <libcockatrice/network/client/abstract/abstract_client.h>
|
||||
#include <libcockatrice/protocol/pb/moderator_commands.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_games_of_user.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_user_info.pb.h>
|
||||
#include <libcockatrice/protocol/pb/session_commands.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
BanDialog::BanDialog(const ServerInfo_User &info, QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
nameBanCheckBox = new QCheckBox(tr("ban &user name"));
|
||||
nameBanCheckBox->setChecked(true);
|
||||
nameBanEdit = new QLineEdit(QString::fromStdString(info.name()));
|
||||
nameBanEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
ipBanCheckBox = new QCheckBox(tr("ban &IP address"));
|
||||
ipBanCheckBox->setChecked(true);
|
||||
ipBanEdit = new QLineEdit(QString::fromStdString(info.address()));
|
||||
ipBanEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
idBanCheckBox = new QCheckBox(tr("ban client I&D"));
|
||||
idBanCheckBox->setChecked(true);
|
||||
idBanEdit = new QLineEdit(QString::fromStdString(info.clientid()));
|
||||
idBanEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
if (QString::fromStdString(info.clientid()).isEmpty())
|
||||
idBanCheckBox->setChecked(false);
|
||||
|
||||
QGridLayout *banTypeGrid = new QGridLayout;
|
||||
banTypeGrid->addWidget(nameBanCheckBox, 0, 0);
|
||||
banTypeGrid->addWidget(nameBanEdit, 0, 1);
|
||||
banTypeGrid->addWidget(ipBanCheckBox, 1, 0);
|
||||
banTypeGrid->addWidget(ipBanEdit, 1, 1);
|
||||
banTypeGrid->addWidget(idBanCheckBox, 2, 0);
|
||||
banTypeGrid->addWidget(idBanEdit, 2, 1);
|
||||
QGroupBox *banTypeGroupBox = new QGroupBox(tr("Ban type"));
|
||||
banTypeGroupBox->setLayout(banTypeGrid);
|
||||
|
||||
permanentRadio = new QRadioButton(tr("&permanent ban"));
|
||||
temporaryRadio = new QRadioButton(tr("&temporary ban"));
|
||||
temporaryRadio->setChecked(true);
|
||||
connect(temporaryRadio, &QRadioButton::toggled, this, &BanDialog::enableTemporaryEdits);
|
||||
daysLabel = new QLabel(tr("&Days:"));
|
||||
daysEdit = new QSpinBox;
|
||||
daysEdit->setMinimum(0);
|
||||
daysEdit->setValue(0);
|
||||
daysEdit->setMaximum(10000);
|
||||
daysLabel->setBuddy(daysEdit);
|
||||
hoursLabel = new QLabel(tr("&Hours:"));
|
||||
hoursEdit = new QSpinBox;
|
||||
hoursEdit->setMinimum(0);
|
||||
hoursEdit->setValue(0);
|
||||
hoursEdit->setMaximum(24);
|
||||
hoursLabel->setBuddy(hoursEdit);
|
||||
minutesLabel = new QLabel(tr("&Minutes:"));
|
||||
minutesEdit = new QSpinBox;
|
||||
minutesEdit->setMinimum(0);
|
||||
minutesEdit->setValue(5);
|
||||
minutesEdit->setMaximum(60);
|
||||
minutesLabel->setBuddy(minutesEdit);
|
||||
QGridLayout *durationLayout = new QGridLayout;
|
||||
durationLayout->addWidget(permanentRadio, 0, 0, 1, 6);
|
||||
durationLayout->addWidget(temporaryRadio, 1, 0, 1, 6);
|
||||
durationLayout->addWidget(daysLabel, 2, 0);
|
||||
durationLayout->addWidget(daysEdit, 2, 1);
|
||||
durationLayout->addWidget(hoursLabel, 2, 2);
|
||||
durationLayout->addWidget(hoursEdit, 2, 3);
|
||||
durationLayout->addWidget(minutesLabel, 2, 4);
|
||||
durationLayout->addWidget(minutesEdit, 2, 5);
|
||||
QGroupBox *durationGroupBox = new QGroupBox(tr("Duration of the ban"));
|
||||
durationGroupBox->setLayout(durationLayout);
|
||||
|
||||
QLabel *reasonLabel = new QLabel(tr("Please enter the reason for the ban.\nThis is only saved for moderators and "
|
||||
"cannot be seen by the banned person."));
|
||||
reasonEdit = new QPlainTextEdit;
|
||||
|
||||
QLabel *visibleReasonLabel =
|
||||
new QLabel(tr("Please enter the reason for the ban that will be visible to the banned person."));
|
||||
visibleReasonEdit = new QPlainTextEdit;
|
||||
|
||||
deleteMessages = new QCheckBox(tr("Redact all messages from this user in all rooms"));
|
||||
|
||||
QPushButton *okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setAutoDefault(true);
|
||||
connect(okButton, &QPushButton::clicked, this, &BanDialog::okClicked);
|
||||
QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
|
||||
connect(cancelButton, &QPushButton::clicked, this, &BanDialog::reject);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(banTypeGroupBox);
|
||||
vbox->addWidget(durationGroupBox);
|
||||
vbox->addWidget(reasonLabel);
|
||||
vbox->addWidget(reasonEdit);
|
||||
vbox->addWidget(visibleReasonLabel);
|
||||
vbox->addWidget(visibleReasonEdit);
|
||||
vbox->addWidget(deleteMessages);
|
||||
vbox->addLayout(buttonLayout);
|
||||
|
||||
setLayout(vbox);
|
||||
setWindowTitle(tr("Ban user from server"));
|
||||
}
|
||||
|
||||
WarningDialog::WarningDialog(const QString userName, const QString clientID, QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
descriptionLabel = new QLabel(tr("Which warning would you like to send?"));
|
||||
nameWarning = new QLineEdit(userName);
|
||||
nameWarning->setMaxLength(MAX_NAME_LENGTH);
|
||||
warnClientID = new QLineEdit(clientID);
|
||||
warnClientID->setMaxLength(MAX_NAME_LENGTH);
|
||||
warningOption = new QComboBox();
|
||||
warningOption->addItem("");
|
||||
|
||||
deleteMessages = new QCheckBox(tr("Redact all messages from this user in all rooms"));
|
||||
|
||||
QPushButton *okButton = new QPushButton(tr("&OK"));
|
||||
okButton->setAutoDefault(true);
|
||||
connect(okButton, &QPushButton::clicked, this, &WarningDialog::okClicked);
|
||||
QPushButton *cancelButton = new QPushButton(tr("&Cancel"));
|
||||
connect(cancelButton, &QPushButton::clicked, this, &WarningDialog::reject);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(okButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(descriptionLabel);
|
||||
vbox->addWidget(nameWarning);
|
||||
vbox->addWidget(warningOption);
|
||||
vbox->addWidget(deleteMessages);
|
||||
vbox->addLayout(buttonLayout);
|
||||
setLayout(vbox);
|
||||
setWindowTitle(tr("Warn user for misconduct"));
|
||||
}
|
||||
|
||||
void WarningDialog::okClicked()
|
||||
{
|
||||
if (nameWarning->text().simplified().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("User name to send a warning to can not be blank, please specify a user to warn."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (warningOption->currentText().simplified().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Warning to use can not be blank, please select a valid warning to send."));
|
||||
return;
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
QString WarningDialog::getName() const
|
||||
{
|
||||
return nameWarning->text().simplified();
|
||||
}
|
||||
|
||||
QString WarningDialog::getWarnID() const
|
||||
{
|
||||
return warnClientID->text().simplified();
|
||||
}
|
||||
|
||||
QString WarningDialog::getReason() const
|
||||
{
|
||||
return warningOption->currentText().simplified();
|
||||
}
|
||||
|
||||
int WarningDialog::getDeleteMessages() const
|
||||
{
|
||||
return deleteMessages->isChecked() ? -1 : 0;
|
||||
}
|
||||
|
||||
void WarningDialog::addWarningOption(const QString warning)
|
||||
{
|
||||
warningOption->addItem(warning);
|
||||
}
|
||||
|
||||
void BanDialog::okClicked()
|
||||
{
|
||||
if (!nameBanCheckBox->isChecked() && !ipBanCheckBox->isChecked() && !idBanCheckBox->isChecked()) {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("You have to select a name-based, IP-based, clientId based, or some combination of "
|
||||
"the three to place a ban."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (nameBanCheckBox->isChecked())
|
||||
if (nameBanEdit->text().simplified() == "") {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("You must have a value in the name ban when selecting the name ban checkbox."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ipBanCheckBox->isChecked())
|
||||
if (ipBanEdit->text().simplified() == "") {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("You must have a value in the ip ban when selecting the ip ban checkbox."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (idBanCheckBox->isChecked())
|
||||
if (idBanEdit->text().simplified() == "") {
|
||||
QMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("You must have a value in the clientid ban when selecting the clientid ban checkbox."));
|
||||
return;
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
void BanDialog::enableTemporaryEdits(bool enabled)
|
||||
{
|
||||
daysLabel->setEnabled(enabled);
|
||||
daysEdit->setEnabled(enabled);
|
||||
hoursLabel->setEnabled(enabled);
|
||||
hoursEdit->setEnabled(enabled);
|
||||
minutesLabel->setEnabled(enabled);
|
||||
minutesEdit->setEnabled(enabled);
|
||||
}
|
||||
|
||||
QString BanDialog::getBanId() const
|
||||
{
|
||||
return idBanCheckBox->isChecked() ? idBanEdit->text() : QString();
|
||||
}
|
||||
|
||||
QString BanDialog::getBanName() const
|
||||
{
|
||||
return nameBanCheckBox->isChecked() ? nameBanEdit->text() : QString();
|
||||
}
|
||||
|
||||
QString BanDialog::getBanIP() const
|
||||
{
|
||||
return ipBanCheckBox->isChecked() ? ipBanEdit->text() : QString();
|
||||
}
|
||||
|
||||
int BanDialog::getMinutes() const
|
||||
{
|
||||
return permanentRadio->isChecked() ? 0
|
||||
: (daysEdit->value() * 24 * 60 + hoursEdit->value() * 60 + minutesEdit->value());
|
||||
}
|
||||
|
||||
QString BanDialog::getReason() const
|
||||
{
|
||||
return reasonEdit->toPlainText();
|
||||
}
|
||||
|
||||
QString BanDialog::getVisibleReason() const
|
||||
{
|
||||
return visibleReasonEdit->toPlainText();
|
||||
}
|
||||
|
||||
int BanDialog::getDeleteMessages() const
|
||||
{
|
||||
return deleteMessages->isChecked() ? -1 : 0;
|
||||
}
|
||||
|
||||
AdminNotesDialog::AdminNotesDialog(const QString &_userName, const QString &_notes, QWidget *_parent)
|
||||
: QDialog(_parent), userName(_userName)
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
auto *updateButton = new QPushButton(tr("Update Notes"));
|
||||
updateButton->setEnabled(false);
|
||||
connect(updateButton, &QPushButton::clicked, this, &AdminNotesDialog::accept);
|
||||
|
||||
notes = new QPlainTextEdit(_notes);
|
||||
notes->setMinimumWidth(500);
|
||||
connect(notes, &QPlainTextEdit::textChanged, this, [=]() { updateButton->setEnabled(true); });
|
||||
|
||||
auto *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(notes);
|
||||
vbox->addWidget(updateButton);
|
||||
|
||||
setLayout(vbox);
|
||||
setWindowTitle(tr("Admin Notes for %1").arg(_userName));
|
||||
}
|
||||
|
||||
QString AdminNotesDialog::getNotes() const
|
||||
{
|
||||
return notes->toPlainText();
|
||||
}
|
||||
|
||||
UserListItemDelegate::UserListItemDelegate(QObject *const parent) : QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool UserListItemDelegate::editorEvent(QEvent *event,
|
||||
QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index)
|
||||
{
|
||||
if ((event->type() == QEvent::MouseButtonPress) && index.isValid()) {
|
||||
QMouseEvent *const mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
static_cast<UserListWidget *>(parent())->showContextMenu(mouseEvent->globalPosition().toPoint(), index);
|
||||
#else
|
||||
static_cast<UserListWidget *>(parent())->showContextMenu(mouseEvent->globalPos(), index);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
}
|
||||
|
||||
UserListTWI::UserListTWI(const ServerInfo_User &_userInfo) : QTreeWidgetItem(Type)
|
||||
{
|
||||
setUserInfo(_userInfo);
|
||||
}
|
||||
|
||||
void UserListTWI::setUserInfo(const ServerInfo_User &_userInfo)
|
||||
{
|
||||
userInfo = _userInfo;
|
||||
|
||||
setData(0, Qt::UserRole, userInfo.user_level());
|
||||
setIcon(0, UserLevelPixmapGenerator::generateIcon(18, UserLevelFlags(userInfo.user_level()), userInfo.pawn_colors(),
|
||||
false, QString::fromStdString(userInfo.privlevel())));
|
||||
setIcon(1, QIcon(CountryPixmapGenerator::generatePixmap(18, QString::fromStdString(userInfo.country()))));
|
||||
setData(2, Qt::UserRole, QString::fromStdString(userInfo.name()));
|
||||
setData(2, Qt::DisplayRole, QString::fromStdString(userInfo.name()));
|
||||
setData(3, Qt::InitialSortOrderRole, QString::fromStdString(userInfo.privlevel()));
|
||||
}
|
||||
|
||||
void UserListTWI::setOnline(bool online)
|
||||
{
|
||||
setData(0, Qt::UserRole + 1, online);
|
||||
setData(2, Qt::ForegroundRole, online ? qApp->palette().brush(QPalette::WindowText) : QBrush(Qt::gray));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort Users in the following order
|
||||
* 1) Online Users > Offline Users
|
||||
* 2) Admins, judge/vip/donator status ignored
|
||||
* 3) Moderators, judge/vip/donator status ignored
|
||||
* 4) Judges
|
||||
* 5) VIPs
|
||||
* 6) Donators
|
||||
* 7) Everyone else
|
||||
* @param other RHS to compare to
|
||||
* @return Left is less than the Right
|
||||
*/
|
||||
bool UserListTWI::operator<(const QTreeWidgetItem &other) const
|
||||
{
|
||||
// Sort by online/offline
|
||||
if (data(0, Qt::UserRole + 1) != other.data(0, Qt::UserRole + 1)) {
|
||||
return data(0, Qt::UserRole + 1).toBool();
|
||||
}
|
||||
|
||||
const auto &lhsUserLevelFlags = UserLevelFlags(data(0, Qt::UserRole).toInt());
|
||||
const auto &rhsUserLevelFlags = UserLevelFlags(other.data(0, Qt::UserRole).toInt());
|
||||
|
||||
// Admins & Mods need no additional comparison checks, just to see if they're an admin or a moderator
|
||||
static const QList<ServerInfo_User_UserLevelFlag> userLevelWithNoOtherPrefOrder = {
|
||||
ServerInfo_User_UserLevelFlag_IsAdmin, ServerInfo_User_UserLevelFlag_IsModerator};
|
||||
for (const auto &userLevelEntry : userLevelWithNoOtherPrefOrder) {
|
||||
if (lhsUserLevelFlags.testFlag(userLevelEntry) &&
|
||||
lhsUserLevelFlags.testFlag(userLevelEntry) == rhsUserLevelFlags.testFlag(userLevelEntry)) {
|
||||
return QString::localeAwareCompare(data(2, Qt::UserRole).toString(),
|
||||
other.data(2, Qt::UserRole).toString()) < 0;
|
||||
} else if (lhsUserLevelFlags.testFlag(userLevelEntry) != rhsUserLevelFlags.testFlag(userLevelEntry)) {
|
||||
return lhsUserLevelFlags.testFlag(userLevelEntry) > rhsUserLevelFlags.testFlag(userLevelEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// Judges can be sorted by their additional ranks
|
||||
static const QList<ServerInfo_User_UserLevelFlag> userLevelOrder = {ServerInfo_User_UserLevelFlag_IsJudge,
|
||||
ServerInfo_User_UserLevelFlag_IsRegistered,
|
||||
ServerInfo_User_UserLevelFlag_IsUser};
|
||||
for (const auto &userLevelEntry : userLevelOrder) {
|
||||
if (lhsUserLevelFlags.testFlag(userLevelEntry) != rhsUserLevelFlags.testFlag(userLevelEntry)) {
|
||||
return lhsUserLevelFlags.testFlag(userLevelEntry) > rhsUserLevelFlags.testFlag(userLevelEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort by VIP > Donator > None
|
||||
static const QMap<QString, int> privilegeOrder = {{"VIP", 3}, {"DONATOR", 2}, {"NONE", 1}, {"UNKNOWN", 0}};
|
||||
const auto &lhsUserPrivLevel = privilegeOrder.value(data(3, Qt::InitialSortOrderRole).toString(), 0);
|
||||
const auto &rhsUserPrivLevel = privilegeOrder.value(other.data(3, Qt::InitialSortOrderRole).toString(), 0);
|
||||
if (lhsUserPrivLevel != rhsUserPrivLevel) {
|
||||
return lhsUserPrivLevel > rhsUserPrivLevel;
|
||||
}
|
||||
|
||||
// Sort by name
|
||||
return QString::localeAwareCompare(data(2, Qt::UserRole).toString(), other.data(2, Qt::UserRole).toString()) < 0;
|
||||
}
|
||||
|
||||
UserListWidget::UserListWidget(TabSupervisor *_tabSupervisor,
|
||||
AbstractClient *_client,
|
||||
UserListType _type,
|
||||
QWidget *parent)
|
||||
: QGroupBox(parent), tabSupervisor(_tabSupervisor), client(_client), type(_type), onlineCount(0)
|
||||
{
|
||||
itemDelegate = new UserListItemDelegate(this);
|
||||
userContextMenu = new UserContextMenu(tabSupervisor, this);
|
||||
connect(userContextMenu, &UserContextMenu::openMessageDialog, this, &UserListWidget::openMessageDialog);
|
||||
|
||||
userTree = new QTreeWidget;
|
||||
userTree->setColumnCount(3);
|
||||
userTree->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||
userTree->header()->setMinimumSectionSize(0);
|
||||
userTree->setHeaderHidden(true);
|
||||
userTree->setRootIsDecorated(false);
|
||||
userTree->setIconSize(QSize(20, 18));
|
||||
userTree->setItemDelegate(itemDelegate);
|
||||
userTree->setAlternatingRowColors(true);
|
||||
connect(userTree, &QTreeWidget::itemActivated, this, &UserListWidget::userClicked);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(userTree);
|
||||
|
||||
setLayout(vbox);
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void UserListWidget::retranslateUi()
|
||||
{
|
||||
userContextMenu->retranslateUi();
|
||||
switch (type) {
|
||||
case AllUsersList:
|
||||
titleStr = tr("Users connected to server: %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 UserListWidget::processUserInfo(const ServerInfo_User &user, bool online)
|
||||
{
|
||||
const QString userName = QString::fromStdString(user.name());
|
||||
UserListTWI *item = users.value(userName);
|
||||
if (item)
|
||||
item->setUserInfo(user);
|
||||
else {
|
||||
item = new UserListTWI(user);
|
||||
users.insert(userName, item);
|
||||
userTree->addTopLevelItem(item);
|
||||
if (online)
|
||||
++onlineCount;
|
||||
updateCount();
|
||||
}
|
||||
item->setOnline(online);
|
||||
}
|
||||
|
||||
bool UserListWidget::deleteUser(const QString &userName)
|
||||
{
|
||||
UserListTWI *twi = users.value(userName);
|
||||
if (twi) {
|
||||
users.remove(userName);
|
||||
userTree->takeTopLevelItem(userTree->indexOfTopLevelItem(twi));
|
||||
if (twi->data(0, Qt::UserRole + 1).toBool())
|
||||
--onlineCount;
|
||||
delete twi;
|
||||
updateCount();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void UserListWidget::setUserOnline(const QString &userName, bool online)
|
||||
{
|
||||
UserListTWI *twi = users.value(userName);
|
||||
if (!twi)
|
||||
return;
|
||||
|
||||
twi->setOnline(online);
|
||||
if (online)
|
||||
++onlineCount;
|
||||
else
|
||||
--onlineCount;
|
||||
updateCount();
|
||||
}
|
||||
|
||||
void UserListWidget::updateCount()
|
||||
{
|
||||
QString str = titleStr;
|
||||
if ((type == BuddyList) || (type == IgnoreList))
|
||||
str = str.arg(onlineCount);
|
||||
setTitle(str.arg(userTree->topLevelItemCount()));
|
||||
}
|
||||
|
||||
void UserListWidget::userClicked(QTreeWidgetItem *item, int /*column*/)
|
||||
{
|
||||
emit openMessageDialog(item->data(2, Qt::UserRole).toString(), true);
|
||||
}
|
||||
|
||||
void UserListWidget::showContextMenu(const QPoint &pos, const QModelIndex &index)
|
||||
{
|
||||
const ServerInfo_User &userInfo = static_cast<UserListTWI *>(userTree->topLevelItem(index.row()))->getUserInfo();
|
||||
bool online = index.sibling(index.row(), 0).data(Qt::UserRole + 1).toBool();
|
||||
|
||||
userContextMenu->showContextMenu(pos, QString::fromStdString(userInfo.name()),
|
||||
UserLevelFlags(userInfo.user_level()), online);
|
||||
}
|
||||
|
||||
void UserListWidget::sortItems()
|
||||
{
|
||||
userTree->sortItems(1, Qt::AscendingOrder);
|
||||
}
|
||||
170
cockatrice/src/interface/widgets/server/user/user_list_widget.h
Normal file
170
cockatrice/src/interface/widgets/server/user/user_list_widget.h
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
/**
|
||||
* @file user_list_widget.h
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef USERLIST_H
|
||||
#define USERLIST_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QTextEdit>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <libcockatrice/network/server/remote/user_level.h>
|
||||
#include <libcockatrice/protocol/pb/moderator_commands.pb.h>
|
||||
|
||||
class QTreeWidget;
|
||||
class ServerInfo_User;
|
||||
class AbstractClient;
|
||||
class TabSupervisor;
|
||||
class QLabel;
|
||||
class QCheckBox;
|
||||
class QSpinBox;
|
||||
class QRadioButton;
|
||||
class QPlainTextEdit;
|
||||
class Response;
|
||||
class CommandContainer;
|
||||
class UserContextMenu;
|
||||
|
||||
class BanDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QLabel *daysLabel, *hoursLabel, *minutesLabel;
|
||||
QCheckBox *nameBanCheckBox, *ipBanCheckBox, *idBanCheckBox, *deleteMessages;
|
||||
QLineEdit *nameBanEdit, *ipBanEdit, *idBanEdit;
|
||||
QSpinBox *daysEdit, *hoursEdit, *minutesEdit;
|
||||
QRadioButton *permanentRadio, *temporaryRadio;
|
||||
QPlainTextEdit *reasonEdit, *visibleReasonEdit;
|
||||
private slots:
|
||||
void okClicked();
|
||||
void enableTemporaryEdits(bool enabled);
|
||||
|
||||
public:
|
||||
explicit BanDialog(const ServerInfo_User &info, QWidget *parent = nullptr);
|
||||
QString getBanName() const;
|
||||
QString getBanIP() const;
|
||||
QString getBanId() const;
|
||||
int getMinutes() const;
|
||||
QString getReason() const;
|
||||
QString getVisibleReason() const;
|
||||
int getDeleteMessages() const;
|
||||
};
|
||||
|
||||
class WarningDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QLabel *descriptionLabel;
|
||||
QLineEdit *nameWarning;
|
||||
QComboBox *warningOption;
|
||||
QLineEdit *warnClientID;
|
||||
QCheckBox *deleteMessages;
|
||||
private slots:
|
||||
void okClicked();
|
||||
|
||||
public:
|
||||
WarningDialog(const QString userName, const QString clientID, QWidget *parent = nullptr);
|
||||
QString getName() const;
|
||||
QString getWarnID() const;
|
||||
QString getReason() const;
|
||||
int getDeleteMessages() const;
|
||||
void addWarningOption(const QString warning);
|
||||
};
|
||||
|
||||
class AdminNotesDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QString userName;
|
||||
QPlainTextEdit *notes;
|
||||
|
||||
public:
|
||||
explicit AdminNotesDialog(const QString &_userName, const QString &_notes, QWidget *_parent = nullptr);
|
||||
QString getName() const
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
QString getNotes() const;
|
||||
};
|
||||
|
||||
class UserListItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit UserListItemDelegate(QObject *const parent);
|
||||
bool editorEvent(QEvent *event,
|
||||
QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) override;
|
||||
};
|
||||
|
||||
class UserListTWI : public QTreeWidgetItem
|
||||
{
|
||||
private:
|
||||
ServerInfo_User userInfo;
|
||||
|
||||
public:
|
||||
explicit UserListTWI(const ServerInfo_User &_userInfo);
|
||||
const ServerInfo_User &getUserInfo() const
|
||||
{
|
||||
return userInfo;
|
||||
}
|
||||
void setUserInfo(const ServerInfo_User &_userInfo);
|
||||
void setOnline(bool online);
|
||||
bool operator<(const QTreeWidgetItem &other) const override;
|
||||
};
|
||||
|
||||
class UserListWidget : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum UserListType
|
||||
{
|
||||
AllUsersList,
|
||||
RoomList,
|
||||
BuddyList,
|
||||
IgnoreList
|
||||
};
|
||||
|
||||
private:
|
||||
QMap<QString, UserListTWI *> users;
|
||||
TabSupervisor *tabSupervisor;
|
||||
AbstractClient *client;
|
||||
UserListType type;
|
||||
QTreeWidget *userTree;
|
||||
UserListItemDelegate *itemDelegate;
|
||||
UserContextMenu *userContextMenu;
|
||||
int onlineCount;
|
||||
QString titleStr;
|
||||
void updateCount();
|
||||
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:
|
||||
UserListWidget(TabSupervisor *_tabSupervisor,
|
||||
AbstractClient *_client,
|
||||
UserListType _type,
|
||||
QWidget *parent = nullptr);
|
||||
void retranslateUi();
|
||||
void processUserInfo(const ServerInfo_User &user, bool online);
|
||||
bool deleteUser(const QString &userName);
|
||||
void setUserOnline(const QString &userName, bool online);
|
||||
const QMap<QString, UserListTWI *> &getUsers() const
|
||||
{
|
||||
return users;
|
||||
}
|
||||
void showContextMenu(const QPoint &pos, const QModelIndex &index);
|
||||
void sortItems();
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue