mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-20 09:22:15 -07:00
Merge branch 'master' into remote-decks-multi
This commit is contained in:
commit
9c914e6217
8 changed files with 1669 additions and 1158 deletions
|
|
@ -41,6 +41,7 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor, AbstractClient *_c
|
||||||
localDirView->setColumnHidden(1, true);
|
localDirView->setColumnHidden(1, true);
|
||||||
localDirView->setRootIndex(localDirModel->index(localDirModel->rootPath(), 0));
|
localDirView->setRootIndex(localDirModel->index(localDirModel->rootPath(), 0));
|
||||||
localDirView->setSortingEnabled(true);
|
localDirView->setSortingEnabled(true);
|
||||||
|
localDirView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
localDirView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
localDirView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
localDirView->header()->setSortIndicator(0, Qt::AscendingOrder);
|
localDirView->header()->setSortIndicator(0, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
|
@ -149,41 +150,50 @@ QString TabDeckStorage::getTargetPath() const
|
||||||
|
|
||||||
void TabDeckStorage::actOpenLocalDeck()
|
void TabDeckStorage::actOpenLocalDeck()
|
||||||
{
|
{
|
||||||
QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
|
QModelIndexList curLefts = localDirView->selectionModel()->selectedRows();
|
||||||
if (localDirModel->isDir(curLeft))
|
for (const auto &curLeft : curLefts) {
|
||||||
return;
|
if (localDirModel->isDir(curLeft))
|
||||||
QString filePath = localDirModel->filePath(curLeft);
|
return;
|
||||||
|
QString filePath = localDirModel->filePath(curLeft);
|
||||||
|
|
||||||
DeckLoader deckLoader;
|
DeckLoader deckLoader;
|
||||||
if (!deckLoader.loadFromFile(filePath, DeckLoader::CockatriceFormat))
|
if (!deckLoader.loadFromFile(filePath, DeckLoader::CockatriceFormat))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
emit openDeckEditor(&deckLoader);
|
emit openDeckEditor(&deckLoader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabDeckStorage::actUpload()
|
void TabDeckStorage::actUpload()
|
||||||
{
|
{
|
||||||
QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
|
QModelIndexList curLefts = localDirView->selectionModel()->selectedRows();
|
||||||
if (localDirModel->isDir(curLeft))
|
if (curLefts.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QString targetPath = getTargetPath();
|
QString targetPath = getTargetPath();
|
||||||
if (targetPath.length() > MAX_NAME_LENGTH) {
|
if (targetPath.length() > MAX_NAME_LENGTH) {
|
||||||
qCritical() << "target path to upload to is too long" << targetPath;
|
qCritical() << "target path to upload to is too long" << targetPath;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString filePath = localDirModel->filePath(curLeft);
|
for (const auto &curLeft : curLefts) {
|
||||||
|
if (localDirModel->isDir(curLeft)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString filePath = localDirModel->filePath(curLeft);
|
||||||
|
uploadDeck(filePath, targetPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TabDeckStorage::uploadDeck(const QString &filePath, const QString &targetPath)
|
||||||
|
{
|
||||||
QFile deckFile(filePath);
|
QFile deckFile(filePath);
|
||||||
QFileInfo deckFileInfo(deckFile);
|
QFileInfo deckFileInfo(deckFile);
|
||||||
|
|
||||||
QString deckString;
|
|
||||||
DeckLoader deck;
|
DeckLoader deck;
|
||||||
bool error = !deck.loadFromFile(filePath, DeckLoader::CockatriceFormat);
|
if (!deck.loadFromFile(filePath, DeckLoader::CockatriceFormat)) {
|
||||||
if (!error) {
|
|
||||||
deckString = deck.writeToString_Native();
|
|
||||||
error = deckString.length() > MAX_FILE_LENGTH;
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
QMessageBox::critical(this, tr("Error"), tr("Invalid deck file"));
|
QMessageBox::critical(this, tr("Error"), tr("Invalid deck file"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -202,6 +212,12 @@ void TabDeckStorage::actUpload()
|
||||||
deck.setName(deck.getName().left(MAX_NAME_LENGTH));
|
deck.setName(deck.getName().left(MAX_NAME_LENGTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString deckString = deck.writeToString_Native();
|
||||||
|
if (deckString.length() > MAX_FILE_LENGTH) {
|
||||||
|
QMessageBox::critical(this, tr("Error"), tr("Invalid deck file"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Command_DeckUpload cmd;
|
Command_DeckUpload cmd;
|
||||||
cmd.set_path(targetPath.toStdString());
|
cmd.set_path(targetPath.toStdString());
|
||||||
cmd.set_deck_list(deckString.toStdString());
|
cmd.set_deck_list(deckString.toStdString());
|
||||||
|
|
@ -228,16 +244,22 @@ void TabDeckStorage::uploadFinished(const Response &r, const CommandContainer &c
|
||||||
|
|
||||||
void TabDeckStorage::actDeleteLocalDeck()
|
void TabDeckStorage::actDeleteLocalDeck()
|
||||||
{
|
{
|
||||||
QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
|
const QModelIndexList curLefts = localDirView->selectionModel()->selectedRows();
|
||||||
if (localDirModel->isDir(curLeft))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (QMessageBox::warning(this, tr("Delete local file"),
|
auto isDir = [&](const auto &curLeft) { return localDirModel->isDir(curLeft); };
|
||||||
tr("Are you sure you want to delete \"%1\"?").arg(localDirModel->fileName(curLeft)),
|
if (curLefts.isEmpty() || std::all_of(curLefts.begin(), curLefts.end(), isDir)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QMessageBox::warning(this, tr("Delete local file"), tr("Are you sure you want to delete the selected files?"),
|
||||||
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
|
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
localDirModel->remove(curLeft);
|
for (const auto &curLeft : curLefts) {
|
||||||
|
if (!localDirModel->isDir(curLeft)) {
|
||||||
|
localDirModel->remove(curLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabDeckStorage::actOpenRemoteDeck()
|
void TabDeckStorage::actOpenRemoteDeck()
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ private:
|
||||||
QAction *aOpenLocalDeck, *aUpload, *aDeleteLocalDeck, *aOpenRemoteDeck, *aDownload, *aNewFolder, *aDeleteRemoteDeck;
|
QAction *aOpenLocalDeck, *aUpload, *aDeleteLocalDeck, *aOpenRemoteDeck, *aDownload, *aNewFolder, *aDeleteRemoteDeck;
|
||||||
QString getTargetPath() const;
|
QString getTargetPath() const;
|
||||||
|
|
||||||
|
void uploadDeck(const QString &filePath, const QString &targetPath);
|
||||||
void deleteRemoteDeck(const RemoteDeckList_TreeModel::Node *node);
|
void deleteRemoteDeck(const RemoteDeckList_TreeModel::Node *node);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client) :
|
||||||
localDirView->setColumnHidden(1, true);
|
localDirView->setColumnHidden(1, true);
|
||||||
localDirView->setRootIndex(localDirModel->index(localDirModel->rootPath(), 0));
|
localDirView->setRootIndex(localDirModel->index(localDirModel->rootPath(), 0));
|
||||||
localDirView->setSortingEnabled(true);
|
localDirView->setSortingEnabled(true);
|
||||||
|
localDirView->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||||
localDirView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
localDirView->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
localDirView->header()->setSortIndicator(0, Qt::AscendingOrder);
|
localDirView->header()->setSortIndicator(0, Qt::AscendingOrder);
|
||||||
|
|
||||||
|
|
@ -126,50 +127,62 @@ void TabReplays::retranslateUi()
|
||||||
|
|
||||||
void TabReplays::actOpenLocalReplay()
|
void TabReplays::actOpenLocalReplay()
|
||||||
{
|
{
|
||||||
QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
|
QModelIndexList curLefts = localDirView->selectionModel()->selectedRows();
|
||||||
if (localDirModel->isDir(curLeft))
|
for (const auto &curLeft : curLefts) {
|
||||||
return;
|
if (localDirModel->isDir(curLeft))
|
||||||
QString filePath = localDirModel->filePath(curLeft);
|
continue;
|
||||||
|
QString filePath = localDirModel->filePath(curLeft);
|
||||||
|
|
||||||
QFile f(filePath);
|
QFile f(filePath);
|
||||||
if (!f.open(QIODevice::ReadOnly))
|
if (!f.open(QIODevice::ReadOnly))
|
||||||
return;
|
continue;
|
||||||
QByteArray _data = f.readAll();
|
QByteArray _data = f.readAll();
|
||||||
f.close();
|
f.close();
|
||||||
|
|
||||||
GameReplay *replay = new GameReplay;
|
GameReplay *replay = new GameReplay;
|
||||||
replay->ParseFromArray(_data.data(), _data.size());
|
replay->ParseFromArray(_data.data(), _data.size());
|
||||||
|
|
||||||
emit openReplay(replay);
|
emit openReplay(replay);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TabReplays::actDeleteLocalReplay()
|
void TabReplays::actDeleteLocalReplay()
|
||||||
{
|
{
|
||||||
QModelIndex curLeft = localDirView->selectionModel()->currentIndex();
|
QModelIndexList curLefts = localDirView->selectionModel()->selectedRows();
|
||||||
if (!curLeft.isValid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (QMessageBox::warning(this, tr("Delete local file"),
|
if (curLefts.isEmpty()) {
|
||||||
tr("Are you sure you want to delete \"%1\"?").arg(localDirModel->fileName(curLeft)),
|
|
||||||
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
localDirModel->remove(curLeft);
|
if (QMessageBox::warning(this, tr("Delete local file"), tr("Are you sure you want to delete the selected files?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto &curLeft : curLefts) {
|
||||||
|
if (curLeft.isValid()) {
|
||||||
|
localDirModel->remove(curLeft);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
|
|
@ -186,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,
|
||||||
|
|
@ -235,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)
|
||||||
|
|
@ -265,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)
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,22 @@
|
||||||
#include "shortcuts_settings.h"
|
#include "shortcuts_settings.h"
|
||||||
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QSortFilterProxyModel>
|
|
||||||
|
ShortcutFilterProxyModel::ShortcutFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if this row or its parent matches the search string
|
||||||
|
*/
|
||||||
|
bool ShortcutFilterProxyModel::filterAcceptsRow(const int sourceRow, const QModelIndex &sourceParent) const
|
||||||
|
{
|
||||||
|
QModelIndex nameIndex = sourceModel()->index(sourceRow, filterKeyColumn(), sourceParent);
|
||||||
|
QModelIndex parentIndex = sourceModel()->index(sourceParent.row(), filterKeyColumn(), sourceParent.parent());
|
||||||
|
|
||||||
|
return sourceModel()->data(nameIndex).toString().contains(filterRegularExpression()) ||
|
||||||
|
sourceModel()->data(parentIndex).toString().contains(filterRegularExpression());
|
||||||
|
}
|
||||||
|
|
||||||
ShortcutTreeView::ShortcutTreeView(QWidget *parent) : QTreeView(parent)
|
ShortcutTreeView::ShortcutTreeView(QWidget *parent) : QTreeView(parent)
|
||||||
{
|
{
|
||||||
|
|
@ -14,7 +29,7 @@ ShortcutTreeView::ShortcutTreeView(QWidget *parent) : QTreeView(parent)
|
||||||
populateShortcutsModel();
|
populateShortcutsModel();
|
||||||
|
|
||||||
// filter proxy
|
// filter proxy
|
||||||
proxyModel = new QSortFilterProxyModel(this);
|
proxyModel = new ShortcutFilterProxyModel(this);
|
||||||
proxyModel->setRecursiveFilteringEnabled(true);
|
proxyModel->setRecursiveFilteringEnabled(true);
|
||||||
proxyModel->setSourceModel(shortcutsModel);
|
proxyModel->setSourceModel(shortcutsModel);
|
||||||
proxyModel->setDynamicSortFilter(true);
|
proxyModel->setDynamicSortFilter(true);
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,23 @@
|
||||||
#define SHORTCUT_TREEVIEW_H
|
#define SHORTCUT_TREEVIEW_H
|
||||||
|
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
/**
|
||||||
|
* Custom implementation of QSortFilterProxyModel that also searches in the parent's string when filtering
|
||||||
|
*/
|
||||||
|
class ShortcutFilterProxyModel : public QSortFilterProxyModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ShortcutFilterProxyModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||||
|
};
|
||||||
|
|
||||||
class ShortcutTreeView : public QTreeView
|
class ShortcutTreeView : public QTreeView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -21,7 +34,7 @@ public slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStandardItemModel *shortcutsModel;
|
QStandardItemModel *shortcutsModel;
|
||||||
QSortFilterProxyModel *proxyModel;
|
ShortcutFilterProxyModel *proxyModel;
|
||||||
void populateShortcutsModel();
|
void populateShortcutsModel();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue