support multi-select for remote replays in game replays tab (#5310)

This commit is contained in:
RickyRister 2024-12-23 17:38:47 -08:00 committed by GitHub
parent 69379334f9
commit 705b1e0c2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 91 additions and 47 deletions

View file

@ -168,17 +168,21 @@ void TabReplays::actDeleteLocalReplay()
void TabReplays::actOpenRemoteReplay()
{
ServerInfo_Replay const *curRight = serverDirView->getCurrentReplay();
if (!curRight)
return;
auto const curRights = serverDirView->getSelectedReplays();
Command_ReplayDownload cmd;
cmd.set_replay_id(curRight->replay_id());
for (const auto curRight : curRights) {
if (!curRight) {
continue;
}
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
SLOT(openRemoteReplayFinished(const Response &)));
client->sendCommand(pend);
Command_ReplayDownload cmd;
cmd.set_replay_id(curRight->replay_id());
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
SLOT(openRemoteReplayFinished(const Response &)));
client->sendCommand(pend);
}
}
void TabReplays::openRemoteReplayFinished(const Response &r)
@ -195,34 +199,37 @@ void TabReplays::openRemoteReplayFinished(const Response &r)
void TabReplays::actDownload()
{
QString filePath;
QString dirPath;
QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
if (!curLeft.isValid())
filePath = localDirModel->rootPath();
dirPath = localDirModel->rootPath();
else {
while (!localDirModel->isDir(curLeft))
curLeft = curLeft.parent();
filePath = localDirModel->filePath(curLeft);
dirPath = localDirModel->filePath(curLeft);
}
ServerInfo_Replay const *curRight = serverDirView->getCurrentReplay();
const auto curRights = serverDirView->getSelectedReplays();
if (!curRight) {
const auto isNull = [](const auto *replay) { return !replay; };
if (std::any_of(curRights.begin(), curRights.end(), isNull)) {
QMessageBox::information(this, tr("Downloading Replays"),
tr("Folder download is not yet supported. Please download replays individually."));
return;
}
filePath += QString("/replay_%1.cor").arg(curRight->replay_id());
for (const auto curRight : curRights) {
const QString filePath = dirPath + QString("/replay_%1.cor").arg(curRight->replay_id());
Command_ReplayDownload cmd;
cmd.set_replay_id(curRight->replay_id());
Command_ReplayDownload cmd;
cmd.set_replay_id(curRight->replay_id());
PendingCommand *pend = client->prepareSessionCommand(cmd);
pend->setExtraData(filePath);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
SLOT(downloadFinished(Response, CommandContainer, QVariant)));
client->sendCommand(pend);
PendingCommand *pend = client->prepareSessionCommand(cmd);
pend->setExtraData(filePath);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
SLOT(downloadFinished(Response, CommandContainer, QVariant)));
client->sendCommand(pend);
}
}
void TabReplays::downloadFinished(const Response &r,
@ -244,18 +251,22 @@ void TabReplays::downloadFinished(const Response &r,
void TabReplays::actKeepRemoteReplay()
{
ServerInfo_ReplayMatch const *curRight = serverDirView->getCurrentReplayMatch();
if (!curRight)
const auto curRights = serverDirView->getSelectedReplayMatches();
if (curRights.isEmpty()) {
return;
}
Command_ReplayModifyMatch cmd;
cmd.set_game_id(curRight->game_id());
cmd.set_do_not_hide(!curRight->do_not_hide());
for (const auto curRight : curRights) {
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(Response, CommandContainer, QVariant)), this,
SLOT(keepRemoteReplayFinished(Response, CommandContainer)));
client->sendCommand(pend);
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
SLOT(keepRemoteReplayFinished(Response, CommandContainer)));
client->sendCommand(pend);
}
}
void TabReplays::keepRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer)
@ -274,21 +285,27 @@ void TabReplays::keepRemoteReplayFinished(const Response &r, const CommandContai
void TabReplays::actDeleteRemoteReplay()
{
ServerInfo_ReplayMatch const *curRight = serverDirView->getCurrentReplayMatch();
if (!curRight)
const auto curRights = serverDirView->getSelectedReplayMatches();
if (curRights.isEmpty()) {
return;
}
if (QMessageBox::warning(this, tr("Delete remote replay"),
tr("Are you sure you want to delete the replay of game %1?").arg(curRight->game_id()),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
tr("Are you sure you want to delete the selected replays?"),
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
return;
}
Command_ReplayDeleteMatch cmd;
cmd.set_game_id(curRight->game_id());
for (const auto curRight : curRights) {
Command_ReplayDeleteMatch cmd;
cmd.set_game_id(curRight->game_id());
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
SLOT(deleteRemoteReplayFinished(Response, CommandContainer)));
client->sendCommand(pend);
PendingCommand *pend = client->prepareSessionCommand(cmd);
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
SLOT(deleteRemoteReplayFinished(Response, CommandContainer)));
client->sendCommand(pend);
}
}
void TabReplays::deleteRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer)

View file

@ -306,14 +306,41 @@ RemoteReplayList_TreeWidget::RemoteReplayList_TreeWidget(AbstractClient *_client
setSortingEnabled(true);
proxyModel->sort(0, Qt::AscendingOrder);
header()->setSortIndicator(0, Qt::AscendingOrder);
setSelectionMode(QAbstractItemView::ExtendedSelection);
}
ServerInfo_Replay const *RemoteReplayList_TreeWidget::getCurrentReplay() const
/**
* Gets all currently selected replays.
* Any selection that isn't a replay file (e.g. a folder) will appear as a nullptr in the list.
* Make sure to check the list for nullptr before using it.
*
* @return A List of pointers to the selected replays, as well as nullptr for any selection that isn't a replay.
*/
QList<ServerInfo_Replay const *> RemoteReplayList_TreeWidget::getSelectedReplays() const
{
return treeModel->getReplay(proxyModel->mapToSource(selectionModel()->currentIndex()));
const auto selection = selectionModel()->selectedRows();
auto replays = QList<ServerInfo_Replay const *>();
for (const auto &row : selection) {
replays << treeModel->getReplay(proxyModel->mapToSource(row));
}
return replays;
}
ServerInfo_ReplayMatch const *RemoteReplayList_TreeWidget::getCurrentReplayMatch() const
/**
* Gets all currently selected replayMatches.
*
* @return A Set of pointers to the selected replayMatches.
*/
QSet<ServerInfo_ReplayMatch const *> RemoteReplayList_TreeWidget::getSelectedReplayMatches() const
{
return treeModel->getReplayMatch(proxyModel->mapToSource(selectionModel()->currentIndex()));
const auto selection = selectionModel()->selectedRows();
auto replayMatches = QSet<ServerInfo_ReplayMatch const *>();
for (const auto &row : selection) {
if (const auto replayMatch = treeModel->getReplayMatch(proxyModel->mapToSource(row))) {
replayMatches << replayMatch;
}
}
return replayMatches;
}

View file

@ -111,8 +111,8 @@ private:
public:
RemoteReplayList_TreeWidget(AbstractClient *_client, QWidget *parent = nullptr);
ServerInfo_Replay const *getCurrentReplay() const;
ServerInfo_ReplayMatch const *getCurrentReplayMatch() const;
QList<ServerInfo_Replay const *> getSelectedReplays() const;
QSet<ServerInfo_ReplayMatch const *> getSelectedReplayMatches() const;
void refreshTree();
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo)
{