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

View file

@ -306,14 +306,41 @@ RemoteReplayList_TreeWidget::RemoteReplayList_TreeWidget(AbstractClient *_client
setSortingEnabled(true); setSortingEnabled(true);
proxyModel->sort(0, Qt::AscendingOrder); proxyModel->sort(0, Qt::AscendingOrder);
header()->setSortIndicator(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: public:
RemoteReplayList_TreeWidget(AbstractClient *_client, QWidget *parent = nullptr); RemoteReplayList_TreeWidget(AbstractClient *_client, QWidget *parent = nullptr);
ServerInfo_Replay const *getCurrentReplay() const; QList<ServerInfo_Replay const *> getSelectedReplays() const;
ServerInfo_ReplayMatch const *getCurrentReplayMatch() const; QSet<ServerInfo_ReplayMatch const *> getSelectedReplayMatches() const;
void refreshTree(); void refreshTree();
void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo) void addMatchInfo(const ServerInfo_ReplayMatch &matchInfo)
{ {