#include #include #include #include #include #include #include #include #include #include #include #include #include "dlg_creategame.h" #include "tab_room.h" #include "userlist.h" #include "abstractclient.h" #include "protocol_items.h" #include "gamesmodel.h" GameSelector::GameSelector(AbstractClient *_client, int _roomId, QWidget *parent) : QGroupBox(parent), client(_client), roomId(_roomId) { gameListView = new QTreeView; gameListModel = new GamesModel(this); gameListProxyModel = new GamesProxyModel(this); gameListProxyModel->setSourceModel(gameListModel); gameListView->setModel(gameListProxyModel); gameListView->header()->setResizeMode(0, QHeaderView::ResizeToContents); showFullGamesCheckBox = new QCheckBox; createButton = new QPushButton; joinButton = new QPushButton; spectateButton = new QPushButton; QHBoxLayout *buttonLayout = new QHBoxLayout; buttonLayout->addWidget(showFullGamesCheckBox); buttonLayout->addStretch(); buttonLayout->addWidget(createButton); buttonLayout->addWidget(joinButton); buttonLayout->addWidget(spectateButton); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(gameListView); mainLayout->addLayout(buttonLayout); retranslateUi(); setLayout(mainLayout); setMinimumWidth(gameListView->columnWidth(0) * gameListModel->columnCount()); setMinimumHeight(400); connect(showFullGamesCheckBox, SIGNAL(stateChanged(int)), this, SLOT(showFullGamesChanged(int))); connect(createButton, SIGNAL(clicked()), this, SLOT(actCreate())); connect(joinButton, SIGNAL(clicked()), this, SLOT(actJoin())); connect(spectateButton, SIGNAL(clicked()), this, SLOT(actJoin())); } void GameSelector::showFullGamesChanged(int state) { gameListProxyModel->setFullGamesVisible(state); } void GameSelector::actCreate() { DlgCreateGame dlg(client, roomId, this); dlg.exec(); } void GameSelector::checkResponse(ResponseCode response) { createButton->setEnabled(true); joinButton->setEnabled(true); spectateButton->setEnabled(true); switch (response) { case RespWrongPassword: QMessageBox::critical(this, tr("Error"), tr("Wrong password.")); break; case RespSpectatorsNotAllowed: QMessageBox::critical(this, tr("Error"), tr("Spectators are not allowed in this game.")); break; case RespGameFull: QMessageBox::critical(this, tr("Error"), tr("The game is already full.")); break; case RespNameNotFound: QMessageBox::critical(this, tr("Error"), tr("The game does not exist any more.")); break; default: ; } } void GameSelector::actJoin() { bool spectator = sender() == spectateButton; QModelIndex ind = gameListView->currentIndex(); if (!ind.isValid()) return; ServerInfo_Game *game = gameListModel->getGame(ind.data(Qt::UserRole).toInt()); QString password; if (game->getHasPassword() && !(spectator && !game->getSpectatorsNeedPassword())) { bool ok; password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok); if (!ok) return; } Command_JoinGame *commandJoinGame = new Command_JoinGame(roomId, game->getGameId(), password, spectator); connect(commandJoinGame, SIGNAL(finished(ResponseCode)), this, SLOT(checkResponse(ResponseCode))); client->sendCommand(commandJoinGame); createButton->setEnabled(false); joinButton->setEnabled(false); spectateButton->setEnabled(false); } void GameSelector::retranslateUi() { setTitle(tr("Games")); showFullGamesCheckBox->setText(tr("Show &full games")); createButton->setText(tr("C&reate")); joinButton->setText(tr("&Join")); spectateButton->setText(tr("J&oin as spectator")); } void GameSelector::processGameInfo(ServerInfo_Game *info) { gameListModel->updateGameList(info); } TabRoom::TabRoom(AbstractClient *_client, ServerInfo_Room *info) : Tab(), client(_client), roomId(info->getRoomId()), roomName(info->getName()) { gameSelector = new GameSelector(client, roomId); userList = new UserList(false); textEdit = new QTextEdit; textEdit->setReadOnly(true); sayLabel = new QLabel; sayEdit = new QLineEdit; sayLabel->setBuddy(sayEdit); connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage())); QHBoxLayout *sayHbox = new QHBoxLayout; sayHbox->addWidget(sayLabel); sayHbox->addWidget(sayEdit); QVBoxLayout *chatVbox = new QVBoxLayout; chatVbox->addWidget(textEdit); chatVbox->addLayout(sayHbox); chatGroupBox = new QGroupBox; chatGroupBox->setLayout(chatVbox); QVBoxLayout *vbox = new QVBoxLayout; vbox->addWidget(gameSelector); vbox->addWidget(chatGroupBox); QHBoxLayout *hbox = new QHBoxLayout; hbox->addLayout(vbox, 3); hbox->addWidget(userList, 1); aLeaveRoom = new QAction(this); connect(aLeaveRoom, SIGNAL(triggered()), this, SLOT(actLeaveRoom())); tabMenu = new QMenu(this); tabMenu->addAction(aLeaveRoom); retranslateUi(); setLayout(hbox); const QList users = info->getUserList(); for (int i = 0; i < users.size(); ++i) userList->processUserInfo(users[i]); } TabRoom::~TabRoom() { emit roomClosing(this); } void TabRoom::retranslateUi() { sayLabel->setText(tr("&Say:")); chatGroupBox->setTitle(tr("Chat")); tabMenu->setTitle(tr("&Room")); aLeaveRoom->setText(tr("&Leave room")); } QString TabRoom::sanitizeHtml(QString dirty) const { return dirty .replace("&", "&") .replace("<", "<") .replace(">", ">"); } void TabRoom::sendMessage() { if (sayEdit->text().isEmpty()) return; client->sendCommand(new Command_RoomSay(roomId, sayEdit->text())); sayEdit->clear(); } void TabRoom::actLeaveRoom() { client->sendCommand(new Command_LeaveRoom(roomId)); deleteLater(); } void TabRoom::processRoomEvent(RoomEvent *event) { switch (event->getItemId()) { case ItemId_Event_ListGames: processListGamesEvent(qobject_cast(event)); break; case ItemId_Event_JoinRoom: processJoinRoomEvent(qobject_cast(event)); break; case ItemId_Event_LeaveRoom: processLeaveRoomEvent(qobject_cast(event)); break; case ItemId_Event_RoomSay: processSayEvent(qobject_cast(event)); break; default: ; } } void TabRoom::processListGamesEvent(Event_ListGames *event) { const QList &gameList = event->getGameList(); for (int i = 0; i < gameList.size(); ++i) gameSelector->processGameInfo(gameList[i]); } void TabRoom::processJoinRoomEvent(Event_JoinRoom *event) { textEdit->append(tr("%1 has joined the room.").arg(sanitizeHtml(event->getUserInfo()->getName()))); userList->processUserInfo(event->getUserInfo()); emit userEvent(); } void TabRoom::processLeaveRoomEvent(Event_LeaveRoom *event) { textEdit->append(tr("%1 has left the room.").arg(sanitizeHtml(event->getPlayerName()))); userList->deleteUser(event->getPlayerName()); emit userEvent(); } void TabRoom::processSayEvent(Event_RoomSay *event) { if (event->getPlayerName().isEmpty()) textEdit->append(QString("%1getMessage()))); else textEdit->append(QString("%1: %2").arg(sanitizeHtml(event->getPlayerName())).arg(sanitizeHtml(event->getMessage()))); emit userEvent(); }