2022-12-04 11:03:45 +00:00
|
|
|
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
|
|
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
|
|
|
|
2019-12-31 06:17:17 +00:00
|
|
|
#include "gamelistsettingswidget.h"
|
2023-08-13 06:28:28 +00:00
|
|
|
#include "core/game_list.h"
|
2020-08-01 17:03:25 +00:00
|
|
|
#include "gamelistsearchdirectoriesmodel.h"
|
2022-07-11 13:03:29 +00:00
|
|
|
#include "mainwindow.h"
|
|
|
|
#include "qthost.h"
|
2019-12-31 06:17:17 +00:00
|
|
|
#include "qtutils.h"
|
2023-08-13 06:28:28 +00:00
|
|
|
|
|
|
|
#include "common/assert.h"
|
|
|
|
#include "common/file_system.h"
|
|
|
|
#include "common/string_util.h"
|
|
|
|
|
2019-12-31 06:17:17 +00:00
|
|
|
#include <QtCore/QAbstractTableModel>
|
2020-01-24 04:51:25 +00:00
|
|
|
#include <QtCore/QDebug>
|
2019-12-31 06:17:17 +00:00
|
|
|
#include <QtCore/QSettings>
|
2020-01-24 04:51:25 +00:00
|
|
|
#include <QtCore/QUrl>
|
2019-12-31 06:17:17 +00:00
|
|
|
#include <QtWidgets/QFileDialog>
|
|
|
|
#include <QtWidgets/QHeaderView>
|
2020-07-28 16:51:52 +00:00
|
|
|
#include <QtWidgets/QMenu>
|
2019-12-31 06:17:17 +00:00
|
|
|
#include <QtWidgets/QMessageBox>
|
|
|
|
#include <algorithm>
|
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
GameListSettingsWidget::GameListSettingsWidget(SettingsDialog* dialog, QWidget* parent) : QWidget(parent)
|
2019-12-31 06:17:17 +00:00
|
|
|
{
|
|
|
|
m_ui.setupUi(this);
|
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
m_search_directories_model = new GameListSearchDirectoriesModel(g_emu_thread);
|
2019-12-31 06:17:17 +00:00
|
|
|
m_ui.searchDirectoryList->setModel(m_search_directories_model);
|
|
|
|
m_ui.searchDirectoryList->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
|
|
m_ui.searchDirectoryList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
|
|
m_ui.searchDirectoryList->setAlternatingRowColors(true);
|
|
|
|
m_ui.searchDirectoryList->setShowGrid(false);
|
2019-12-31 06:40:20 +00:00
|
|
|
m_ui.searchDirectoryList->horizontalHeader()->setHighlightSections(false);
|
2019-12-31 06:17:17 +00:00
|
|
|
m_ui.searchDirectoryList->verticalHeader()->hide();
|
|
|
|
m_ui.searchDirectoryList->setCurrentIndex({});
|
2020-07-28 16:51:52 +00:00
|
|
|
m_ui.searchDirectoryList->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
2019-12-31 06:17:17 +00:00
|
|
|
|
2019-12-31 06:40:20 +00:00
|
|
|
connect(m_ui.searchDirectoryList, &QTableView::clicked, this, &GameListSettingsWidget::onDirectoryListItemClicked);
|
2020-07-28 16:51:52 +00:00
|
|
|
connect(m_ui.searchDirectoryList, &QTableView::customContextMenuRequested, this,
|
|
|
|
&GameListSettingsWidget::onDirectoryListContextMenuRequested);
|
2020-07-17 15:33:36 +00:00
|
|
|
connect(m_ui.addSearchDirectoryButton, &QPushButton::clicked, this,
|
2020-07-17 10:50:02 +00:00
|
|
|
&GameListSettingsWidget::onAddSearchDirectoryButtonClicked);
|
2020-07-17 15:33:36 +00:00
|
|
|
connect(m_ui.removeSearchDirectoryButton, &QPushButton::clicked, this,
|
2020-07-17 10:50:02 +00:00
|
|
|
&GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked);
|
2021-07-02 02:24:37 +00:00
|
|
|
connect(m_ui.addExcludedPath, &QPushButton::clicked, this, &GameListSettingsWidget::onAddExcludedPathButtonClicked);
|
|
|
|
connect(m_ui.removeExcludedPath, &QPushButton::clicked, this,
|
|
|
|
&GameListSettingsWidget::onRemoveExcludedPathButtonClicked);
|
2020-07-17 15:33:36 +00:00
|
|
|
connect(m_ui.rescanAllGames, &QPushButton::clicked, this, &GameListSettingsWidget::onRescanAllGamesClicked);
|
|
|
|
connect(m_ui.scanForNewGames, &QPushButton::clicked, this, &GameListSettingsWidget::onScanForNewGamesClicked);
|
2021-07-02 02:24:37 +00:00
|
|
|
|
|
|
|
refreshExclusionList();
|
2019-12-31 06:17:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GameListSettingsWidget::~GameListSettingsWidget() = default;
|
|
|
|
|
2021-07-02 02:24:37 +00:00
|
|
|
bool GameListSettingsWidget::addExcludedPath(const std::string& path)
|
|
|
|
{
|
2022-07-11 13:03:29 +00:00
|
|
|
if (!Host::AddValueToBaseStringListSetting("GameList", "ExcludedPaths", path.c_str()))
|
2021-07-02 02:24:37 +00:00
|
|
|
return false;
|
|
|
|
|
2022-09-17 05:51:05 +00:00
|
|
|
Host::CommitBaseSettingChanges();
|
2021-07-02 02:24:37 +00:00
|
|
|
m_ui.excludedPaths->addItem(QString::fromStdString(path));
|
2022-07-11 13:03:29 +00:00
|
|
|
g_main_window->refreshGameList(false);
|
2021-07-02 02:24:37 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameListSettingsWidget::refreshExclusionList()
|
|
|
|
{
|
|
|
|
m_ui.excludedPaths->clear();
|
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
const std::vector<std::string> paths(Host::GetBaseStringListSetting("GameList", "ExcludedPaths"));
|
2021-07-02 02:24:37 +00:00
|
|
|
for (const std::string& path : paths)
|
|
|
|
m_ui.excludedPaths->addItem(QString::fromStdString(path));
|
|
|
|
}
|
|
|
|
|
2019-12-31 06:17:17 +00:00
|
|
|
void GameListSettingsWidget::resizeEvent(QResizeEvent* event)
|
|
|
|
{
|
|
|
|
QWidget::resizeEvent(event);
|
|
|
|
|
|
|
|
QtUtils::ResizeColumnsForTableView(m_ui.searchDirectoryList, {-1, 100});
|
|
|
|
}
|
|
|
|
|
2019-12-31 06:40:20 +00:00
|
|
|
void GameListSettingsWidget::onDirectoryListItemClicked(const QModelIndex& index)
|
|
|
|
{
|
|
|
|
if (!index.isValid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
const int row = index.row();
|
|
|
|
const int column = index.column();
|
|
|
|
if (column != 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_search_directories_model->setEntryRecursive(row, !m_search_directories_model->isEntryRecursive(row));
|
|
|
|
}
|
|
|
|
|
2020-07-28 16:51:52 +00:00
|
|
|
void GameListSettingsWidget::onDirectoryListContextMenuRequested(const QPoint& point)
|
|
|
|
{
|
|
|
|
QModelIndexList selection = m_ui.searchDirectoryList->selectionModel()->selectedIndexes();
|
|
|
|
if (selection.size() < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const int row = selection[0].row();
|
|
|
|
|
|
|
|
QMenu menu;
|
|
|
|
menu.addAction(tr("Remove"), [this, row]() { m_search_directories_model->removeEntry(row); });
|
|
|
|
menu.addSeparator();
|
|
|
|
menu.addAction(tr("Open Directory..."),
|
|
|
|
[this, row]() { m_search_directories_model->openEntryInExplorer(this, row); });
|
|
|
|
menu.exec(m_ui.searchDirectoryList->mapToGlobal(point));
|
|
|
|
}
|
|
|
|
|
2020-01-24 04:50:53 +00:00
|
|
|
void GameListSettingsWidget::addSearchDirectory(QWidget* parent_widget)
|
2019-12-31 06:17:17 +00:00
|
|
|
{
|
2020-07-18 01:43:30 +00:00
|
|
|
QString dir =
|
|
|
|
QDir::toNativeSeparators(QFileDialog::getExistingDirectory(parent_widget, tr("Select Search Directory")));
|
|
|
|
|
2019-12-31 06:17:17 +00:00
|
|
|
if (dir.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
QMessageBox::StandardButton selection =
|
|
|
|
QMessageBox::question(this, tr("Scan Recursively?"),
|
|
|
|
tr("Would you like to scan the directory \"%1\" recursively?\n\nScanning recursively takes "
|
|
|
|
"more time, but will identify files in subdirectories.")
|
|
|
|
.arg(dir),
|
|
|
|
QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
|
|
|
|
if (selection == QMessageBox::Cancel)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const bool recursive = (selection == QMessageBox::Yes);
|
|
|
|
m_search_directories_model->addEntry(dir, recursive);
|
2020-01-24 04:50:53 +00:00
|
|
|
}
|
|
|
|
|
2020-07-17 10:50:02 +00:00
|
|
|
void GameListSettingsWidget::onAddSearchDirectoryButtonClicked()
|
2020-01-24 04:50:53 +00:00
|
|
|
{
|
|
|
|
addSearchDirectory(this);
|
2019-12-31 06:17:17 +00:00
|
|
|
}
|
|
|
|
|
2020-07-17 10:50:02 +00:00
|
|
|
void GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked()
|
2019-12-31 06:17:17 +00:00
|
|
|
{
|
|
|
|
QModelIndexList selection = m_ui.searchDirectoryList->selectionModel()->selectedIndexes();
|
|
|
|
if (selection.size() < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
const int row = selection[0].row();
|
|
|
|
m_search_directories_model->removeEntry(row);
|
|
|
|
}
|
|
|
|
|
2021-07-02 02:24:37 +00:00
|
|
|
void GameListSettingsWidget::onAddExcludedPathButtonClicked()
|
|
|
|
{
|
|
|
|
QString path =
|
|
|
|
QDir::toNativeSeparators(QFileDialog::getOpenFileName(QtUtils::GetRootWidget(this), tr("Select Path")));
|
|
|
|
if (path.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
addExcludedPath(path.toStdString());
|
|
|
|
}
|
|
|
|
|
|
|
|
void GameListSettingsWidget::onRemoveExcludedPathButtonClicked()
|
|
|
|
{
|
|
|
|
const int row = m_ui.excludedPaths->currentRow();
|
|
|
|
QListWidgetItem* item = (row >= 0) ? m_ui.excludedPaths->takeItem(row) : 0;
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
2022-09-17 05:51:05 +00:00
|
|
|
if (Host::RemoveValueFromBaseStringListSetting("GameList", "ExcludedPaths", item->text().toUtf8().constData()))
|
|
|
|
Host::CommitBaseSettingChanges();
|
2021-07-02 02:24:37 +00:00
|
|
|
delete item;
|
|
|
|
|
2022-07-11 13:03:29 +00:00
|
|
|
g_main_window->refreshGameList(false);
|
2021-07-02 02:24:37 +00:00
|
|
|
}
|
|
|
|
|
2020-07-17 10:50:02 +00:00
|
|
|
void GameListSettingsWidget::onRescanAllGamesClicked()
|
2019-12-31 06:17:17 +00:00
|
|
|
{
|
2022-07-11 13:03:29 +00:00
|
|
|
g_main_window->refreshGameList(true);
|
2020-06-10 15:48:54 +00:00
|
|
|
}
|
|
|
|
|
2020-07-17 10:50:02 +00:00
|
|
|
void GameListSettingsWidget::onScanForNewGamesClicked()
|
2020-06-10 15:48:54 +00:00
|
|
|
{
|
2022-07-11 13:03:29 +00:00
|
|
|
g_main_window->refreshGameList(false);
|
2019-12-31 06:17:17 +00:00
|
|
|
}
|