Commit 6bbc76af authored by Max-Wilhelm Bruker's avatar Max-Wilhelm Bruker
Browse files

Merge branch 'devel' into servernetwork

parents 50e53fbe b0378544
<RCC>
<qresource prefix="/" >
<file alias="back.svg" >resources/back.svg</file>
<file>resources/lock.svg</file>
<file>resources/icon_delete.svg</file>
<file>resources/icon_tab_changed.svg</file>
<file>resources/icon_config_general.svg</file>
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -14,6 +14,7 @@
#include "pb/event_user_joined.pb.h"
#include "pb/event_user_left.pb.h"
#include "pb/event_game_joined.pb.h"
#include "pb/event_replay_added.pb.h"
#include "get_pb_extension.h"
#include <google/protobuf/descriptor.h>
......@@ -55,6 +56,7 @@ void AbstractClient::processProtocolItem(const ServerMessage &item)
case SessionEvent::USER_JOINED: emit userJoinedEventReceived(event.GetExtension(Event_UserJoined::ext)); break;
case SessionEvent::USER_LEFT: emit userLeftEventReceived(event.GetExtension(Event_UserLeft::ext)); break;
case SessionEvent::GAME_JOINED: emit gameJoinedEventReceived(event.GetExtension(Event_GameJoined::ext)); break;
case SessionEvent::REPLAY_ADDED: emit replayAddedEventReceived(event.GetExtension(Event_ReplayAdded::ext)); break;
}
break;
}
......
......@@ -22,6 +22,7 @@ class Event_GameJoined;
class Event_UserMessage;
class Event_ConnectionClosed;
class Event_ServerShutdown;
class Event_ReplayAdded;
enum ClientStatus {
StatusDisconnected,
......@@ -57,6 +58,7 @@ signals:
void userInfoChanged(const ServerInfo_User &userInfo);
void buddyListReceived(const QList<ServerInfo_User> &buddyList);
void ignoreListReceived(const QList<ServerInfo_User> &ignoreList);
void replayAddedEventReceived(const Event_ReplayAdded &event);
private:
int nextCmdId;
protected slots:
......
#include <QSettings>
#include <QLabel>
#include <QPushButton>
#include <QCheckBox>
#include <QGridLayout>
#include <QHBoxLayout>
#include "dlg_connect.h"
......@@ -27,6 +28,9 @@ DlgConnect::DlgConnect(QWidget *parent)
passwordEdit = new QLineEdit(settings.value("password").toString());
passwordLabel->setBuddy(passwordEdit);
passwordEdit->setEchoMode(QLineEdit::Password);
savePasswordCheckBox = new QCheckBox(tr("&Save password"));
savePasswordCheckBox->setChecked(settings.value("save_password", 1).toInt());
okButton = new QPushButton(tr("&OK"));
okButton->setDefault(true);
......@@ -41,6 +45,7 @@ DlgConnect::DlgConnect(QWidget *parent)
grid->addWidget(playernameEdit, 2, 1);
grid->addWidget(passwordLabel, 3, 0);
grid->addWidget(passwordEdit, 3, 1);
grid->addWidget(savePasswordCheckBox, 4, 0, 1, 2);
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch();
......@@ -67,7 +72,8 @@ void DlgConnect::actOk()
settings.setValue("hostname", hostEdit->text());
settings.setValue("port", portEdit->text());
settings.setValue("playername", playernameEdit->text());
settings.setValue("password", passwordEdit->text());
settings.setValue("password", savePasswordCheckBox->isChecked() ? passwordEdit->text() : QString());
settings.setValue("save_password", savePasswordCheckBox->isChecked() ? 1 : 0);
settings.endGroup();
accept();
......
......@@ -6,6 +6,7 @@
class QLabel;
class QPushButton;
class QCheckBox;
class DlgConnect : public QDialog {
Q_OBJECT
......@@ -20,6 +21,7 @@ private slots:
private:
QLabel *hostLabel, *portLabel, *playernameLabel, *passwordLabel;
QLineEdit *hostEdit, *portEdit, *playernameEdit, *passwordEdit;
QCheckBox *savePasswordCheckBox;
QPushButton *okButton, *cancelButton;
};
......
......@@ -20,6 +20,7 @@ private:
Response::ResponseCode cmdDeckDownload(const Command_DeckDownload & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
Response::ResponseCode cmdReplayList(const Command_ReplayList & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
Response::ResponseCode cmdReplayDownload(const Command_ReplayDownload & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
Response::ResponseCode cmdReplayModifyMatch(const Command_ReplayModifyMatch &cmd, ResponseContainer &rc) { return Response::RespFunctionNotAllowed; }
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage & /*cmd*/, ResponseContainer & /*rc*/) { return Response::RespFunctionNotAllowed; }
......
......@@ -9,58 +9,106 @@
#include "pb/response_replay_list.pb.h"
#include "pb/serverinfo_replay.pb.h"
const int RemoteReplayList_TreeModel::numberOfColumns = 6;
RemoteReplayList_TreeModel::MatchNode::MatchNode(const ServerInfo_ReplayMatch &_matchInfo)
: RemoteReplayList_TreeModel::Node(QString::fromStdString(_matchInfo.game_name())), matchInfo(_matchInfo)
{
for (int i = 0; i < matchInfo.replay_list_size(); ++i)
append(new ReplayNode(matchInfo.replay_list(i), this));
}
RemoteReplayList_TreeModel::MatchNode::~MatchNode()
{
for (int i = 0; i < size(); ++i)
delete at(i);
}
void RemoteReplayList_TreeModel::MatchNode::updateMatchInfo(const ServerInfo_ReplayMatch &_matchInfo)
{
matchInfo.MergeFrom(_matchInfo);
}
RemoteReplayList_TreeModel::RemoteReplayList_TreeModel(AbstractClient *_client, QObject *parent)
: QAbstractItemModel(parent), client(_client)
{
QFileIconProvider fip;
dirIcon = fip.icon(QFileIconProvider::Folder);
fileIcon = fip.icon(QFileIconProvider::File);
lockIcon = QIcon(":/resources/lock.svg");
refreshTree();
}
RemoteReplayList_TreeModel::~RemoteReplayList_TreeModel()
{
clearTree();
}
int RemoteReplayList_TreeModel::rowCount(const QModelIndex &parent) const
{
return parent.isValid() ? 0 : replays.size();
}
int RemoteReplayList_TreeModel::columnCount(const QModelIndex &/*parent*/) const
{
return 6;
if (!parent.isValid())
return replayMatches.size();
MatchNode *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(parent.internalPointer()));
if (matchNode)
return matchNode->size();
else
return 0;
}
QVariant RemoteReplayList_TreeModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.column() > 5)
if (index.column() >= numberOfColumns)
return QVariant();
ServerInfo_Replay *replayInfo = static_cast<ServerInfo_Replay *>(index.internalPointer());
switch (role) {
case Qt::TextAlignmentRole:
return index.column() == 0 ? Qt::AlignRight : Qt::AlignLeft;
case Qt::DisplayRole: {
switch (index.column()) {
case 0: return replayInfo->game_id();
case 1: return QString::fromStdString(replayInfo->game_name());
case 2: return QString::fromStdString(replayInfo->replay_name());
case 3: {
QStringList playerList;
for (int i = 0; i < replayInfo->player_names_size(); ++i)
playerList.append(QString::fromStdString(replayInfo->player_names(i)));
return playerList.join(", ");
ReplayNode *replayNode = dynamic_cast<ReplayNode *>(static_cast<Node *>(index.internalPointer()));
if (replayNode) {
const ServerInfo_Replay &replayInfo = replayNode->getReplayInfo();
switch (role) {
case Qt::TextAlignmentRole:
return index.column() == 0 ? Qt::AlignRight : Qt::AlignLeft;
case Qt::DisplayRole: {
switch (index.column()) {
case 0: return replayInfo.replay_id();
case 1: return QString::fromStdString(replayInfo.replay_name());
case 5: return replayInfo.duration();
default: return QVariant();
}
}
case Qt::DecorationRole:
return index.column() == 0 ? fileIcon : QVariant();
}
} else {
MatchNode *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(index.internalPointer()));
const ServerInfo_ReplayMatch &matchInfo = matchNode->getMatchInfo();
switch (role) {
case Qt::TextAlignmentRole:
return index.column() == 0 ? Qt::AlignRight : Qt::AlignLeft;
case Qt::DisplayRole: {
switch (index.column()) {
case 0: return matchInfo.game_id();
case 1: return QString::fromStdString(matchInfo.game_name());
case 2: {
QStringList playerList;
for (int i = 0; i < matchInfo.player_names_size(); ++i)
playerList.append(QString::fromStdString(matchInfo.player_names(i)));
return playerList.join(", ");
}
case 4: return QDateTime::fromTime_t(matchInfo.time_started());
case 5: return matchInfo.length();
default: return QVariant();
}
case 4: return QDateTime::fromTime_t(replayInfo->time_started());
case 5: return replayInfo->length();
default: return QVariant();
}
case Qt::DecorationRole:
switch (index.column()) {
case 0: return dirIcon;
case 3: return matchInfo.do_not_hide() ? lockIcon : QVariant();
default: return QVariant();
}
}
case Qt::DecorationRole:
return index.column() == 0 ? fileIcon : QVariant();
}
return QVariant();
}
......@@ -74,10 +122,10 @@ QVariant RemoteReplayList_TreeModel::headerData(int section, Qt::Orientation ori
return section == 0 ? Qt::AlignRight : Qt::AlignLeft;
case Qt::DisplayRole: {
switch (section) {
case 0: return tr("Game ID");
case 1: return tr("Game name");
case 2: return tr("Replay name");
case 3: return tr("Players");
case 0: return tr("ID");
case 1: return tr("Name");
case 2: return tr("Players");
case 3: return tr("Keep");
case 4: return tr("Time started");
case 5: return tr("Duration (sec)");
default: return QVariant();
......@@ -91,13 +139,28 @@ QModelIndex RemoteReplayList_TreeModel::index(int row, int column, const QModelI
{
if (!hasIndex(row, column, parent))
return QModelIndex();
return createIndex(row, column, (void *) &(replays[row]));
MatchNode *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(parent.internalPointer()));
if (matchNode) {
if (row >= matchNode->size())
return QModelIndex();
return createIndex(row, column, (void *) matchNode->at(row));
} else {
if (row >= replayMatches.size())
return QModelIndex();
return createIndex(row, column, (void *) replayMatches[row]);
}
}
QModelIndex RemoteReplayList_TreeModel::parent(const QModelIndex &ind) const
{
return QModelIndex();
MatchNode const *matchNode = dynamic_cast<MatchNode *>(static_cast<Node *>(ind.internalPointer()));
if (matchNode)
return QModelIndex();
else {
ReplayNode *replayNode = dynamic_cast<ReplayNode *>(static_cast<Node *>(ind.internalPointer()));
return createIndex(replayNode->getParent()->indexOf(replayNode), 0, replayNode);
}
}
Qt::ItemFlags RemoteReplayList_TreeModel::flags(const QModelIndex &index) const
......@@ -108,12 +171,37 @@ Qt::ItemFlags RemoteReplayList_TreeModel::flags(const QModelIndex &index) const
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
ServerInfo_Replay const* RemoteReplayList_TreeModel::getNode(const QModelIndex &index) const
ServerInfo_Replay const* RemoteReplayList_TreeModel::getReplay(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
ReplayNode *node = dynamic_cast<ReplayNode *>(static_cast<Node *>(index.internalPointer()));
if (!node)
return 0;
return &node->getReplayInfo();
}
ServerInfo_ReplayMatch const* RemoteReplayList_TreeModel::getReplayMatch(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
return &(replays[index.row()]);
MatchNode *node = dynamic_cast<MatchNode *>(static_cast<Node *>(index.internalPointer()));
if (!node) {
ReplayNode *node = dynamic_cast<ReplayNode *>(static_cast<Node *>(index.internalPointer()));
if (!node)
return 0;
return &node->getParent()->getMatchInfo();
} else
return &node->getMatchInfo();
}
void RemoteReplayList_TreeModel::clearTree()
{
for (int i = 0; i < replayMatches.size(); ++i)
delete replayMatches[i];
replayMatches.clear();
}
void RemoteReplayList_TreeModel::refreshTree()
......@@ -124,15 +212,34 @@ void RemoteReplayList_TreeModel::refreshTree()
client->sendCommand(pend);
}
void RemoteReplayList_TreeModel::addMatchInfo(const ServerInfo_ReplayMatch &matchInfo)
{
beginInsertRows(QModelIndex(), replayMatches.size(), replayMatches.size());
replayMatches.append(new MatchNode(matchInfo));
endInsertRows();
emit treeRefreshed();
}
void RemoteReplayList_TreeModel::updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo)
{
for (int i = 0; i < replayMatches.size(); ++i)
if (replayMatches[i]->getMatchInfo().game_id() == gameId) {
replayMatches[i]->updateMatchInfo(matchInfo);
emit dataChanged(createIndex(i, 0, (void *) replayMatches[i]), createIndex(i, numberOfColumns - 1, (void *) replayMatches[i]));
break;
}
}
void RemoteReplayList_TreeModel::replayListFinished(const Response &r)
{
const Response_ReplayList &resp = r.GetExtension(Response_ReplayList::ext);
beginResetModel();
replays.clear();
clearTree();
for (int i = 0; i < resp.replay_list_size(); ++i)
replays.append(resp.replay_list(i));
for (int i = 0; i < resp.match_list_size(); ++i)
replayMatches.append(new MatchNode(resp.match_list(i)));
endResetModel();
emit treeRefreshed();
......@@ -156,12 +263,12 @@ RemoteReplayList_TreeWidget::RemoteReplayList_TreeWidget(AbstractClient *_client
header()->setSortIndicator(0, Qt::AscendingOrder);
}
ServerInfo_Replay const *RemoteReplayList_TreeWidget::getNode(const QModelIndex &ind) const
ServerInfo_Replay const *RemoteReplayList_TreeWidget::getCurrentReplay() const
{
return treeModel->getNode(proxyModel->mapToSource(ind));
return treeModel->getReplay(proxyModel->mapToSource(selectionModel()->currentIndex()));
}
ServerInfo_Replay const *RemoteReplayList_TreeWidget::getCurrentItem() const
ServerInfo_ReplayMatch const *RemoteReplayList_TreeWidget::getCurrentReplayMatch() const
{
return getNode(selectionModel()->currentIndex());
return treeModel->getReplayMatch(proxyModel->mapToSource(selectionModel()->currentIndex()));
}
......@@ -5,6 +5,7 @@
#include <QDateTime>
#include <QTreeView>
#include "pb/serverinfo_replay.pb.h"
#include "pb/serverinfo_replay_match.pb.h"
class Response;
class AbstractClient;
......@@ -13,10 +14,45 @@ class QSortFilterProxyModel;
class RemoteReplayList_TreeModel : public QAbstractItemModel {
Q_OBJECT
private:
class MatchNode;
class ReplayNode;
class Node {
protected:
QString name;
public:
Node(const QString &_name)
: name(_name) { }
virtual ~Node() { };
QString getName() const { return name; }
};
class MatchNode : public Node, public QList<ReplayNode *> {
private:
ServerInfo_ReplayMatch matchInfo;
public:
MatchNode(const ServerInfo_ReplayMatch &_matchInfo);
~MatchNode();
void clearTree();
const ServerInfo_ReplayMatch &getMatchInfo() { return matchInfo; }
void updateMatchInfo(const ServerInfo_ReplayMatch &_matchInfo);
};
class ReplayNode : public Node {
private:
MatchNode *parent;
ServerInfo_Replay replayInfo;
public:
ReplayNode(const ServerInfo_Replay &_replayInfo, MatchNode *_parent)
: Node(QString::fromStdString(_replayInfo.replay_name())), parent(_parent), replayInfo(_replayInfo) { }
MatchNode *getParent() const { return parent; }
const ServerInfo_Replay &getReplayInfo() { return replayInfo; }
};
AbstractClient *client;
QList<ServerInfo_Replay> replays;
QList<MatchNode *> replayMatches;
QIcon dirIcon, fileIcon, lockIcon;
void clearTree();
QIcon fileIcon;
static const int numberOfColumns;
signals:
void treeRefreshed();
private slots:
......@@ -25,14 +61,17 @@ public:
RemoteReplayList_TreeModel(AbstractClient *_client, QObject *parent = 0);
~RemoteReplayList_TreeModel();
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const;
int columnCount(const QModelIndex &/*parent*/ = QModelIndex()) const { return numberOfColumns; }
QVariant data(const QModelIndex &index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
void refreshTree();
ServerInfo_Replay const *getNode(const QModelIndex &index) const;
ServerInfo_Replay const* getReplay(const QModelIndex &index) const;
ServerInfo_ReplayMatch const* getReplayMatch(const QModelIndex &index) const;
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo);
void updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo);
};
class RemoteReplayList_TreeWidget : public QTreeView {
......@@ -42,8 +81,11 @@ private:
ServerInfo_Replay const *getNode(const QModelIndex &ind) const;
public:
RemoteReplayList_TreeWidget(AbstractClient *_client, QWidget *parent = 0);
ServerInfo_Replay const *getCurrentItem() const;
ServerInfo_Replay const *getCurrentReplay() const;
ServerInfo_ReplayMatch const *getCurrentReplayMatch() const;
void refreshTree();
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo) { treeModel->addMatchInfo(matchInfo); }
void updateMatchInfo(int gameId, const ServerInfo_ReplayMatch &matchInfo) { treeModel->updateMatchInfo(gameId, matchInfo); }
};
#endif
......@@ -63,6 +63,11 @@ QSize ReplayTimelineWidget::sizeHint() const
return QSize(-1, 50);
}
QSize ReplayTimelineWidget::minimumSizeHint() const
{
return QSize(400, 50);
}
void ReplayTimelineWidget::replayTimerTimeout()
{
currentTime += 200;
......
......@@ -27,6 +27,7 @@ public:
ReplayTimelineWidget(QWidget *parent = 0);
void setTimeline(const QList<int> &_replayTimeline);
QSize sizeHint() const;
QSize minimumSizeHint() const;
void setTimeScaleFactor(qreal _timeScaleFactor);
int getCurrentEvent() const { return currentEvent; }
public slots:
......
......@@ -198,7 +198,7 @@ void DeckViewContainer::setDeck(DeckList *deck)
deckView->setDeck(deck);
readyStartButton->setEnabled(true);
}
#include <QDebug>
TabGame::TabGame(GameReplay *_replay)
: Tab(0),
hostId(-1),
......@@ -213,6 +213,8 @@ TabGame::TabGame(GameReplay *_replay)
replay(_replay),
currentReplayStep(0)
{
setAttribute(Qt::WA_DeleteOnClose);
gameId = replay->game_info().game_id();
gameDescription = QString::fromStdString(replay->game_info().description());
......@@ -323,12 +325,13 @@ TabGame::TabGame(GameReplay *_replay)
aNextTurn = 0;
aRemoveLocalArrows = 0;
aConcede = 0;
aLeaveGame = new QAction(this);
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
aLeaveGame = 0;
aCloseReplay = new QAction(this);
connect(aCloseReplay, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
phasesMenu = 0;
tabMenu = new QMenu(this);
tabMenu->addAction(aLeaveGame);
tabMenu->addAction(aCloseReplay);
retranslateUi();
setLayout(superMainLayout);
......@@ -424,6 +427,7 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, QList<AbstractClient *> &_client
connect(aConcede, SIGNAL(triggered()), this, SLOT(actConcede()));
aLeaveGame = new QAction(this);
connect(aLeaveGame, SIGNAL(triggered()), this, SLOT(actLeaveGame()));
aCloseReplay = 0;
phasesMenu = new QMenu(this);
for (int i = 0; i < phasesToolbar->phaseCount(); ++i) {
......@@ -502,8 +506,14 @@ void TabGame::retranslateUi()
aConcede->setText(tr("&Concede"));
aConcede->setShortcut(tr("F2"));
}
aLeaveGame->setText(tr("&Leave game"));
aLeaveGame->setShortcut(tr("Ctrl+Q"));
if (aLeaveGame) {
aLeaveGame->setText(tr("&Leave game"));
aLeaveGame->setShortcut(tr("Ctrl+Q"));
}
if (aCloseReplay) {
aCloseReplay->setText(tr("C&lose replay"));
aCloseReplay->setShortcut(tr("Ctrl+Q"));
}
if (sayLabel)
sayLabel->setText(tr("&Say:"));
......@@ -613,8 +623,9 @@ void TabGame::actLeaveGame()
if (!spectator)
if (QMessageBox::question(this, tr("Leave game"), tr("Are you sure you want to leave this game?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes)
return;
sendGameCommand(Command_LeaveGame());
if (!replay)
sendGameCommand(Command_LeaveGame());
deleteLater();
}
......
......@@ -134,7 +134,7 @@ private:
ZoneViewLayout *zoneLayout;
QAction *playersSeparator;
QMenu *phasesMenu;
QAction *aConcede, *aLeaveGame, *aNextPhase, *aNextTurn, *aRemoveLocalArrows;
QAction *aConcede, *aLeaveGame, *aCloseReplay, *aNextPhase, *aNextTurn, *aRemoveLocalArrows;
QList<QAction *> phaseActions;
Player *addPlayer(int playerId, const ServerInfo_User &info);
......
......@@ -20,6 +20,8 @@
#include "pb/response.pb.h"
#include "pb/response_replay_download.pb.h"
#include "pb/command_replay_download.pb.h"
#include "pb/command_replay_modify_match.pb.h"
#include "pb/event_replay_added.pb.h"
TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client)
: Tab(_tabSupervisor), client(_client)
......@@ -83,13 +85,19 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client)
aDownload = new QAction(this);
aDownload->setIcon(QIcon(":/resources/arrow_left_green.svg"));
connect(aDownload, SIGNAL(triggered()), this, SLOT(actDownload()));
aKeep = new QAction(this);
aKeep->setIcon(QIcon(":/resources/lock.svg"));
connect(aKeep, SIGNAL(triggered()), this, SLOT(actKeepRemoteReplay()));
leftToolBar->addAction(aOpenLocalReplay);
rightToolBar->addAction(aOpenRemoteReplay);
rightToolBar->addAction(aDownload);
rightToolBar->addAction(aKeep);
retranslateUi();
setLayout(hbox);
connect(client, SIGNAL(replayAddedEventReceived(const Event_ReplayAdded &)), this, SLOT(replayAddedEventReceived(const Event_ReplayAdded &)));
}
void TabReplays::retranslateUi()
......@@ -100,6 +108,7 @@ void TabReplays::retranslateUi()
aOpenLocalReplay->setText(tr("Watch replay"));
aOpenRemoteReplay->setText(tr("Watch replay"));
aDownload->setText(tr("Download replay"));
aKeep->setText(tr("Toggle expiration lock"));
}
void TabReplays::actOpenLocalReplay()
......@@ -123,12 +132,12 @@ void TabReplays::actOpenLocalReplay()
void TabReplays::actOpenRemoteReplay()
{
ServerInfo_Replay const *curRight = serverDirView->getCurrentItem();
ServerInfo_Replay const *curRight = serverDirView->getCurrentReplay();
if (!curRight)
return;
Command_ReplayDownload cmd;
cmd.set_game_id(curRight->game_id());
cmd.set_replay_id(curRight->replay_id());
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(const Response &)), this, SLOT(openRemoteReplayFinished(const Response &)));
......@@ -156,13 +165,13 @@ void TabReplays::actDownload()
filePath = localDirModel->filePath(curLeft);
}
ServerInfo_Replay const *curRight = serverDirView->getCurrentItem();
ServerInfo_Replay const *curRight = serverDirView->getCurrentReplay();
if (!curRight)
return;
filePath += QString("/game_%1.cor").arg(curRight->game_id());
filePath += QString("/replay_%1.cor").arg(curRight->replay_id());
Command_ReplayDownload cmd;
cmd.set_game_id(curRight->game_id());
cmd.set_replay_id(curRight->replay_id());
PendingCommand *pend = client->prepareSessionCommand(cmd);
pend->setExtraData(filePath);
......@@ -183,3 +192,37 @@ void TabReplays::downloadFinished(const Response &r)
f.write((const char *) data.data(), data.size());
f.close();
}
void TabReplays::actKeepRemoteReplay()
{
ServerInfo_ReplayMatch const *curRight = serverDirView->getCurrentReplayMatch();
if (!curRight)
return;
Command_ReplayModifyMatch cmd;
cmd.set_game_id(curRight->game_id());
cmd.set_do_not_hide(!curRight->do_not_hide());
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(const Response &)), this, SLOT(keepRemoteReplayFinished(const Response &)));
client->sendCommand(pend);
}
void TabReplays::keepRemoteReplayFinished(const Response &r)
{
if (r.response_code() != Response::RespOk)
return;
PendingCommand *pend = static_cast<PendingCommand *>(sender());
const Command_ReplayModifyMatch &cmd = pend->getCommandContainer().session_command(0).GetExtension(Command_ReplayModifyMatch::ext);
ServerInfo_ReplayMatch temp;
temp.set_do_not_hide(cmd.do_not_hide());
serverDirView->updateMatchInfo(cmd.game_id(), temp);
}
void TabReplays::replayAddedEventReceived(const Event_ReplayAdded &event)
{
serverDirView->addMatchInfo(event.match_info());
}
......@@ -2,8 +2,8 @@
#define TAB_REPLAYS_H
#include "tab.h"
#include "pb/response.pb.h"
class Response;
class AbstractClient;
class QTreeView;
class QFileSystemModel;
......@@ -12,6 +12,7 @@ class QToolBar;
class QGroupBox;
class RemoteReplayList_TreeWidget;
class GameReplay;
class Event_ReplayAdded;
class TabReplays : public Tab {
Q_OBJECT
......@@ -24,7 +25,7 @@ private:
RemoteReplayList_TreeWidget *serverDirView;
QGroupBox *leftGroupBox, *rightGroupBox;
QAction *aOpenLocalReplay, *aOpenRemoteReplay, *aDownload;
QAction *aOpenLocalReplay, *aOpenRemoteReplay, *aDownload, *aKeep;
private slots:
void actOpenLocalReplay();
......@@ -33,6 +34,11 @@ private slots:
void actDownload();
void downloadFinished(const Response &r);
void actKeepRemoteReplay();
void keepRemoteReplayFinished(const Response &r);
void replayAddedEventReceived(const Event_ReplayAdded &event);
signals:
void openReplay(GameReplay *replay);
public:
......
......@@ -209,6 +209,11 @@ void TabSupervisor::stop()
gameIterator.next().value()->deleteLater();
gameTabs.clear();
QListIterator<TabGame *> replayIterator(replayTabs);
while (replayIterator.hasNext())
replayIterator.next()->deleteLater();
replayTabs.clear();
QMapIterator<QString, TabMessage *> messageIterator(messageTabs);
while (messageIterator.hasNext())
messageIterator.next().value()->deleteLater();
......@@ -272,7 +277,8 @@ void TabSupervisor::localGameJoined(const Event_GameJoined &event)
void TabSupervisor::gameLeft(TabGame *tab)
{
emit setMenu(0);
if (tab == currentWidget())
emit setMenu(0);
gameTabs.remove(tab->getGameId());
removeTab(indexOf(tab));
......@@ -295,12 +301,31 @@ void TabSupervisor::addRoomTab(const ServerInfo_Room &info, bool setCurrent)
void TabSupervisor::roomLeft(TabRoom *tab)
{
emit setMenu(0);
if (tab == currentWidget())
emit setMenu(0);
roomTabs.remove(tab->getRoomId());
removeTab(indexOf(tab));
}
void TabSupervisor::openReplay(GameReplay *replay)
{
TabGame *replayTab = new TabGame(replay);
connect(replayTab, SIGNAL(gameClosing(TabGame *)), this, SLOT(replayLeft(TabGame *)));
int tabIndex = myAddTab(replayTab);
addCloseButtonToTab(replayTab, tabIndex);
replayTabs.append(replayTab);
setCurrentWidget(replayTab);
}
void TabSupervisor::replayLeft(TabGame *tab)
{
if (tab == currentWidget())
emit setMenu(0);
replayTabs.removeAt(replayTabs.indexOf(tab));
}
TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus)
{
if (receiverName == QString::fromStdString(userInfo->name()))
......@@ -316,15 +341,10 @@ TabMessage *TabSupervisor::addMessageTab(const QString &receiverName, bool focus
return tab;
}
void TabSupervisor::openReplay(GameReplay *replay)
{
TabGame *replayTab = new TabGame(replay);
myAddTab(replayTab);
}
void TabSupervisor::talkLeft(TabMessage *tab)
{
emit setMenu(0);
if (tab == currentWidget())
emit setMenu(0);
messageTabs.remove(tab->getUserName());
removeTab(indexOf(tab));
......
......@@ -50,6 +50,7 @@ private:
TabAdmin *tabAdmin;
QMap<int, TabRoom *> roomTabs;
QMap<int, TabGame *> gameTabs;
QList<TabGame *> replayTabs;
QMap<QString, TabMessage *> messageTabs;
int myAddTab(Tab *tab);
void addCloseButtonToTab(Tab *tab, int tabIndex);
......@@ -81,6 +82,7 @@ private slots:
void roomLeft(TabRoom *tab);
TabMessage *addMessageTab(const QString &userName, bool focus);
void openReplay(GameReplay *replay);
void replayLeft(TabGame *tab);
void processUserLeft(const QString &userName);
void processUserJoined(const QString &userName);
void talkLeft(TabMessage *tab);
......
......@@ -38,6 +38,8 @@ void SearchLineEdit::keyPressEvent(QKeyEvent *event)
WndDeckEditor::WndDeckEditor(QWidget *parent)
: QMainWindow(parent)
{
setAttribute(Qt::WA_DeleteOnClose);
aSearch = new QAction(tr("&Search..."), this);
aSearch->setIcon(QIcon(":/resources/icon_search.svg"));
connect(aSearch, SIGNAL(triggered()), this, SLOT(actSearch()));
......
[Dolphin]
Timestamp=2012,1,1,23,11,32
Timestamp=2012,3,4,11,22,24
Version=2
ViewMode=1
......@@ -32,6 +32,7 @@ SET(PROTO_FILES
command_ready_start.proto
command_replay_list.proto
command_replay_download.proto
command_replay_modify_match.proto
command_reveal_cards.proto
command_roll_die.proto
command_set_active_phase.proto
......@@ -78,6 +79,7 @@ SET(PROTO_FILES
event_move_card.proto
event_player_properties_changed.proto
event_remove_from_list.proto
event_replay_added.proto
event_reveal_cards.proto
event_roll_die.proto
event_room_say.proto
......@@ -126,6 +128,7 @@ SET(PROTO_FILES
serverinfo_playerproperties.proto
serverinfo_player.proto
serverinfo_replay.proto
serverinfo_replay_match.proto
serverinfo_room.proto
serverinfo_user.proto
serverinfo_zone.proto
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment