mirror of
https://github.com/stenzek/duckstation.git
synced 2026-07-11 01:24:11 +02:00
Qt: Use item view for game list directories
Less duplication.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QItemSelectionModel>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtWidgets/QCheckBox>
|
||||
@@ -27,18 +28,194 @@
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
GameListSearchDirectoriesModel::GameListSearchDirectoriesModel(QObject* parent) : QAbstractTableModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GameListSearchDirectoriesModel::~GameListSearchDirectoriesModel() = default;
|
||||
|
||||
int GameListSearchDirectoriesModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : static_cast<int>(m_rows.size());
|
||||
}
|
||||
|
||||
int GameListSearchDirectoriesModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
return parent.isValid() ? 0 : 2;
|
||||
}
|
||||
|
||||
QVariant GameListSearchDirectoriesModel::data(const QModelIndex& index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_rows.size()))
|
||||
return {};
|
||||
|
||||
const Row& row = m_rows[index.row()];
|
||||
if (index.column() == 0)
|
||||
{
|
||||
if (role == Qt::DisplayRole)
|
||||
return QString::fromStdString(row.path);
|
||||
else if (role == Qt::DecorationRole)
|
||||
{
|
||||
return QIcon(row.recursive ? u":/icons/monochrome/svg/folder-open-line.svg"_s :
|
||||
u":/icons/monochrome/svg/folder-line.svg"_s);
|
||||
}
|
||||
}
|
||||
else if (index.column() == 1 && role == Qt::CheckStateRole)
|
||||
{
|
||||
return row.recursive ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant GameListSearchDirectoriesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation != Qt::Horizontal || role != Qt::DisplayRole)
|
||||
return {};
|
||||
|
||||
switch (section)
|
||||
{
|
||||
case 0:
|
||||
return tr("Search Directory");
|
||||
case 1:
|
||||
return tr("Scan Recursively");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags GameListSearchDirectoriesModel::flags(const QModelIndex& index) const
|
||||
{
|
||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
||||
if (index.isValid() && index.column() == 1)
|
||||
flags |= Qt::ItemIsUserCheckable;
|
||||
return flags;
|
||||
}
|
||||
|
||||
bool GameListSearchDirectoriesModel::setData(const QModelIndex& index, const QVariant& value, int role)
|
||||
{
|
||||
if (!index.isValid() || index.column() != 1 || role != Qt::CheckStateRole || index.row() < 0 ||
|
||||
index.row() >= static_cast<int>(m_rows.size()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Row& row = m_rows[index.row()];
|
||||
const bool recursive = (value.toInt() == Qt::Checked);
|
||||
if (recursive == row.recursive)
|
||||
return false;
|
||||
|
||||
row.recursive = recursive;
|
||||
emit dataChanged(this->index(index.row(), 0), this->index(index.row(), 1), {Qt::DecorationRole, Qt::CheckStateRole});
|
||||
save();
|
||||
return true;
|
||||
}
|
||||
|
||||
void GameListSearchDirectoriesModel::reload()
|
||||
{
|
||||
std::vector<std::string> paths = Core::GetBaseStringListSetting("GameList", "Paths");
|
||||
std::vector<std::string> recursive_paths = Core::GetBaseStringListSetting("GameList", "RecursivePaths");
|
||||
|
||||
beginResetModel();
|
||||
m_rows.clear();
|
||||
m_rows.reserve(paths.size() + recursive_paths.size());
|
||||
for (std::string& path : paths)
|
||||
m_rows.push_back({std::move(path), false});
|
||||
for (std::string& path : recursive_paths)
|
||||
m_rows.push_back({std::move(path), true});
|
||||
std::sort(m_rows.begin(), m_rows.end(), [](const Row& lhs, const Row& rhs) {
|
||||
return QString::localeAwareCompare(QString::fromStdString(lhs.path), QString::fromStdString(rhs.path)) < 0;
|
||||
});
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void GameListSearchDirectoriesModel::addPath(std::string path, bool recursive)
|
||||
{
|
||||
const auto existing =
|
||||
std::find_if(m_rows.begin(), m_rows.end(), [&path](const Row& row) { return row.path == path; });
|
||||
if (existing != m_rows.end())
|
||||
{
|
||||
const int row = static_cast<int>(std::distance(m_rows.begin(), existing));
|
||||
if (existing->recursive != recursive)
|
||||
{
|
||||
existing->recursive = recursive;
|
||||
emit dataChanged(index(row, 0), index(row, 1), {Qt::DecorationRole, Qt::CheckStateRole});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto insert_position =
|
||||
std::lower_bound(m_rows.begin(), m_rows.end(), path, [](const Row& row, const std::string& value) {
|
||||
return QString::localeAwareCompare(QString::fromStdString(row.path), QString::fromStdString(value)) < 0;
|
||||
});
|
||||
const int row = static_cast<int>(std::distance(m_rows.begin(), insert_position));
|
||||
beginInsertRows({}, row, row);
|
||||
m_rows.insert(insert_position, {std::move(path), recursive});
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
void GameListSearchDirectoriesModel::removePath(const QModelIndex& index)
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast<int>(m_rows.size()))
|
||||
return;
|
||||
|
||||
beginRemoveRows({}, index.row(), index.row());
|
||||
m_rows.erase(m_rows.begin() + index.row());
|
||||
endRemoveRows();
|
||||
save();
|
||||
}
|
||||
|
||||
void GameListSearchDirectoriesModel::removePath(const std::string& path)
|
||||
{
|
||||
const auto existing = std::ranges::find_if(m_rows, [&path](const Row& row) { return row.path == path; });
|
||||
if (existing != m_rows.end())
|
||||
{
|
||||
const int row = static_cast<int>(std::distance(m_rows.begin(), existing));
|
||||
beginRemoveRows({}, row, row);
|
||||
m_rows.erase(existing);
|
||||
endRemoveRows();
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
const std::string& GameListSearchDirectoriesModel::pathForIndex(const QModelIndex& index) const
|
||||
{
|
||||
DebugAssert(index.isValid() && index.row() >= 0 && index.row() < static_cast<int>(m_rows.size()));
|
||||
return m_rows[index.row()].path;
|
||||
}
|
||||
|
||||
void GameListSearchDirectoriesModel::save()
|
||||
{
|
||||
std::vector<std::string> paths;
|
||||
std::vector<std::string> recursive_paths;
|
||||
paths.reserve(m_rows.size());
|
||||
recursive_paths.reserve(m_rows.size());
|
||||
for (const Row& row : m_rows)
|
||||
(row.recursive ? recursive_paths : paths).push_back(row.path);
|
||||
|
||||
Core::SetBaseStringListSettingValue("GameList", "Paths", paths);
|
||||
Core::SetBaseStringListSettingValue("GameList", "RecursivePaths", recursive_paths);
|
||||
Host::CommitBaseSettingChanges();
|
||||
emit settingsChanged();
|
||||
}
|
||||
|
||||
GameListSettingsWidget::GameListSettingsWidget(SettingsWindow* dialog, QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
m_directory_model = new GameListSearchDirectoriesModel(this);
|
||||
m_ui.searchDirectoryList->setModel(m_directory_model);
|
||||
QtUtils::SetColumnWidthsForTreeView(m_ui.searchDirectoryList, {-1, 120});
|
||||
|
||||
connect(m_ui.searchDirectoryList, &QTreeWidget::itemSelectionChanged, this,
|
||||
connect(m_ui.searchDirectoryList->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&GameListSettingsWidget::onDirectoryListSelectionChanged);
|
||||
connect(m_ui.searchDirectoryList, &QTreeWidget::itemChanged, this,
|
||||
&GameListSettingsWidget::onDirectoryListItemChanged);
|
||||
connect(m_ui.searchDirectoryList, &QTreeWidget::customContextMenuRequested, this,
|
||||
connect(m_ui.searchDirectoryList, &QTreeView::customContextMenuRequested, this,
|
||||
&GameListSettingsWidget::onDirectoryListContextMenuRequested);
|
||||
connect(m_directory_model, &GameListSearchDirectoriesModel::settingsChanged, this,
|
||||
[]() { g_main_window->refreshGameList(false); });
|
||||
connect(m_ui.addSearchDirectoryButton, &QPushButton::clicked, this,
|
||||
&GameListSettingsWidget::onAddSearchDirectoryButtonClicked);
|
||||
connect(m_ui.removeSearchDirectoryButton, &QPushButton::clicked, this,
|
||||
@@ -85,55 +262,15 @@ void GameListSettingsWidget::refreshExclusionList()
|
||||
m_ui.removeExcludedPath->setEnabled(false);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::addPathToTable(const std::string& path, bool recursive)
|
||||
{
|
||||
QTreeWidgetItem* const item = new QTreeWidgetItem();
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setIcon(0, QIcon(recursive ? u":/icons/monochrome/svg/folder-open-line.svg"_s : u":/icons/monochrome/svg/folder-line.svg"_s));
|
||||
item->setText(0, QString::fromStdString(path));
|
||||
item->setCheckState(1, recursive ? Qt::Checked : Qt::Unchecked);
|
||||
m_ui.searchDirectoryList->addTopLevelItem(item);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::refreshDirectoryList()
|
||||
{
|
||||
QSignalBlocker sb(m_ui.searchDirectoryList);
|
||||
m_ui.searchDirectoryList->clear();
|
||||
|
||||
std::vector<std::string> path_list = Core::GetBaseStringListSetting("GameList", "Paths");
|
||||
for (const std::string& entry : path_list)
|
||||
addPathToTable(entry, false);
|
||||
|
||||
path_list = Core::GetBaseStringListSetting("GameList", "RecursivePaths");
|
||||
for (const std::string& entry : path_list)
|
||||
addPathToTable(entry, true);
|
||||
|
||||
m_ui.searchDirectoryList->sortByColumn(0, Qt::AscendingOrder);
|
||||
m_directory_model->reload();
|
||||
m_ui.removeSearchDirectoryButton->setEnabled(false);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::addSearchDirectory(const QString& path, bool recursive)
|
||||
{
|
||||
const std::string spath(path.toStdString());
|
||||
Core::RemoveValueFromBaseStringListSetting("GameList", recursive ? "Paths" : "RecursivePaths", spath.c_str());
|
||||
Core::AddValueToBaseStringListSetting("GameList", recursive ? "RecursivePaths" : "Paths", spath.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
refreshDirectoryList();
|
||||
g_main_window->refreshGameList(false);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::removeSearchDirectory(const QString& path)
|
||||
{
|
||||
const std::string spath(path.toStdString());
|
||||
if (!Core::RemoveValueFromBaseStringListSetting("GameList", "Paths", spath.c_str()) &&
|
||||
!Core::RemoveValueFromBaseStringListSetting("GameList", "RecursivePaths", spath.c_str()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Host::CommitBaseSettingChanges();
|
||||
refreshDirectoryList();
|
||||
g_main_window->refreshGameList(false);
|
||||
m_directory_model->addPath(path.toStdString(), recursive);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onDirectoryListSelectionChanged()
|
||||
@@ -141,47 +278,20 @@ void GameListSettingsWidget::onDirectoryListSelectionChanged()
|
||||
m_ui.removeSearchDirectoryButton->setEnabled(m_ui.searchDirectoryList->selectionModel()->hasSelection());
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onDirectoryListItemChanged(QTreeWidgetItem* item, int column)
|
||||
{
|
||||
if (column != 1)
|
||||
return;
|
||||
|
||||
const std::string path = item->text(0).toStdString();
|
||||
const bool recursive = (item->checkState(1) == Qt::Checked);
|
||||
|
||||
item->setIcon(0, QIcon(recursive ? u":/icons/monochrome/svg/folder-open-line.svg"_s : u":/icons/monochrome/svg/folder-line.svg"_s));
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
Core::RemoveValueFromBaseStringListSetting("GameList", "Paths", path.c_str());
|
||||
Core::AddValueToBaseStringListSetting("GameList", "RecursivePaths", path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Core::RemoveValueFromBaseStringListSetting("GameList", "RecursivePaths", path.c_str());
|
||||
Core::AddValueToBaseStringListSetting("GameList", "Paths", path.c_str());
|
||||
}
|
||||
Host::CommitBaseSettingChanges();
|
||||
g_main_window->refreshGameList(false);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onDirectoryListContextMenuRequested(const QPoint& point)
|
||||
{
|
||||
QModelIndexList selection = m_ui.searchDirectoryList->selectionModel()->selectedIndexes();
|
||||
if (selection.size() < 1)
|
||||
const QModelIndex index = m_ui.searchDirectoryList->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
const int row = selection[0].row();
|
||||
const QString path = QString::fromStdString(m_directory_model->pathForIndex(index));
|
||||
|
||||
QMenu* const menu = QtUtils::NewPopupMenu(this);
|
||||
menu->addAction(QIcon(u":/icons/monochrome/svg/folder-reduce-line.svg"_s), tr("Remove"), this,
|
||||
&GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked);
|
||||
[this, path]() { m_directory_model->removePath(path.toStdString()); });
|
||||
menu->addSeparator();
|
||||
menu->addAction(QIcon(u":/icons/monochrome/svg/folder-open-line.svg"_s), tr("Open Directory..."), [this, row]() {
|
||||
const QTreeWidgetItem* const item = m_ui.searchDirectoryList->topLevelItem(row);
|
||||
if (item)
|
||||
QtUtils::OpenURL(this, QUrl::fromLocalFile(item->text(0)));
|
||||
});
|
||||
menu->addAction(QIcon(u":/icons/monochrome/svg/folder-open-line.svg"_s), tr("Open Directory..."),
|
||||
[this, path]() { QtUtils::OpenURL(this, QUrl::fromLocalFile(path)); });
|
||||
menu->popup(m_ui.searchDirectoryList->mapToGlobal(point));
|
||||
}
|
||||
|
||||
@@ -214,12 +324,10 @@ void GameListSettingsWidget::onAddSearchDirectoryButtonClicked()
|
||||
void GameListSettingsWidget::onRemoveSearchDirectoryButtonClicked()
|
||||
{
|
||||
const QModelIndex index = m_ui.searchDirectoryList->currentIndex();
|
||||
const QTreeWidgetItem* const item = m_ui.searchDirectoryList->takeTopLevelItem(index.row());
|
||||
if (!item)
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
removeSearchDirectory(item->text(0));
|
||||
delete item;
|
||||
m_directory_model->removePath(index);
|
||||
}
|
||||
|
||||
void GameListSettingsWidget::onAddExcludedFileButtonClicked()
|
||||
|
||||
@@ -2,13 +2,51 @@
|
||||
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
|
||||
|
||||
#pragma once
|
||||
#include <QtCore/QAbstractTableModel>
|
||||
#include <QtWidgets/QWidget>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "ui_gamelistsettingswidget.h"
|
||||
|
||||
class SettingsWindow;
|
||||
|
||||
class GameListSearchDirectoriesModel final : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GameListSearchDirectoriesModel(QObject* parent = nullptr);
|
||||
~GameListSearchDirectoriesModel() override;
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
Qt::ItemFlags flags(const QModelIndex& index) const override;
|
||||
bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override;
|
||||
|
||||
void reload();
|
||||
void addPath(std::string path, bool recursive);
|
||||
void removePath(const QModelIndex& index);
|
||||
void removePath(const std::string& path);
|
||||
const std::string& pathForIndex(const QModelIndex& index) const;
|
||||
|
||||
Q_SIGNALS:
|
||||
void settingsChanged();
|
||||
|
||||
private:
|
||||
struct Row
|
||||
{
|
||||
std::string path;
|
||||
bool recursive;
|
||||
};
|
||||
|
||||
void save();
|
||||
|
||||
std::vector<Row> m_rows;
|
||||
};
|
||||
|
||||
class GameListSettingsWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -23,13 +61,10 @@ public:
|
||||
void addSearchDirectory(QWidget* parent_widget);
|
||||
|
||||
private:
|
||||
void addPathToTable(const std::string& path, bool recursive);
|
||||
void refreshDirectoryList();
|
||||
void addSearchDirectory(const QString& path, bool recursive);
|
||||
void removeSearchDirectory(const QString& path);
|
||||
|
||||
void onDirectoryListSelectionChanged();
|
||||
void onDirectoryListItemChanged(QTreeWidgetItem* item, int column);
|
||||
void onDirectoryListContextMenuRequested(const QPoint& point);
|
||||
void onAddSearchDirectoryButtonClicked();
|
||||
void onRemoveSearchDirectoryButtonClicked();
|
||||
@@ -41,4 +76,5 @@ private:
|
||||
void onRescanAllGamesClicked();
|
||||
|
||||
Ui::GameListSettingsWidget m_ui;
|
||||
GameListSearchDirectoriesModel* m_directory_model;
|
||||
};
|
||||
|
||||
@@ -82,13 +82,16 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="searchDirectoryList">
|
||||
<widget class="QTreeView" name="searchDirectoryList">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::ContextMenuPolicy::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
@@ -101,16 +104,6 @@
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Search Directory</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Scan Recursively</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "biossettingswidget.h"
|
||||
#include "controllerbindingwidgets.h"
|
||||
#include "controllersettingwidgetbinder.h"
|
||||
#include "gamelistsettingswidget.h"
|
||||
#include "gamelistwidget.h"
|
||||
#include "graphicssettingswidget.h"
|
||||
#include "interfacesettingswidget.h"
|
||||
@@ -27,6 +28,7 @@
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <QtCore/QItemSelectionModel>
|
||||
#include <QtWidgets/QButtonGroup>
|
||||
|
||||
#include "moc_setupwizarddialog.cpp"
|
||||
@@ -65,7 +67,7 @@ bool SetupWizardDialog::canShowNextPage()
|
||||
|
||||
case Page_GameList:
|
||||
{
|
||||
if (m_ui.searchDirectoryList->topLevelItemCount() == 0)
|
||||
if (m_directory_model->rowCount() == 0)
|
||||
{
|
||||
if (QtUtils::MessageBoxQuestion(
|
||||
this, tr("No Game Directories Selected"),
|
||||
@@ -240,40 +242,36 @@ void SetupWizardDialog::refreshBiosList()
|
||||
|
||||
void SetupWizardDialog::setupGameListPage()
|
||||
{
|
||||
m_ui.searchDirectoryList->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
|
||||
m_directory_model = new GameListSearchDirectoriesModel(this);
|
||||
m_ui.searchDirectoryList->setModel(m_directory_model);
|
||||
QtUtils::SetColumnWidthsForTreeView(m_ui.searchDirectoryList, {-1, 100});
|
||||
|
||||
connect(m_ui.searchDirectoryList, &QTreeWidget::customContextMenuRequested, this,
|
||||
connect(m_ui.searchDirectoryList, &QTreeView::customContextMenuRequested, this,
|
||||
&SetupWizardDialog::onDirectoryListContextMenuRequested);
|
||||
connect(m_ui.addSearchDirectoryButton, &QPushButton::clicked, this,
|
||||
&SetupWizardDialog::onAddSearchDirectoryButtonClicked);
|
||||
connect(m_ui.removeSearchDirectoryButton, &QPushButton::clicked, this,
|
||||
&SetupWizardDialog::onRemoveSearchDirectoryButtonClicked);
|
||||
connect(m_ui.searchDirectoryList, &QTreeWidget::itemSelectionChanged, this,
|
||||
connect(m_ui.searchDirectoryList->selectionModel(), &QItemSelectionModel::selectionChanged, this,
|
||||
&SetupWizardDialog::onSearchDirectoryListSelectionChanged);
|
||||
connect(m_ui.searchDirectoryList, &QTreeWidget::itemChanged, this,
|
||||
&SetupWizardDialog::onSearchDirectoryListItemChanged);
|
||||
|
||||
refreshDirectoryList();
|
||||
}
|
||||
|
||||
void SetupWizardDialog::onDirectoryListContextMenuRequested(const QPoint& point)
|
||||
{
|
||||
QModelIndexList selection = m_ui.searchDirectoryList->selectionModel()->selectedIndexes();
|
||||
if (selection.size() < 1)
|
||||
const QModelIndex index = m_ui.searchDirectoryList->currentIndex();
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
const int row = selection[0].row();
|
||||
const QString path = QString::fromStdString(m_directory_model->pathForIndex(index));
|
||||
|
||||
QMenu* const menu = QtUtils::NewPopupMenu(this);
|
||||
menu->addAction(QIcon(u":/icons/monochrome/svg/folder-reduce-line.svg"_s), tr("Remove"), this,
|
||||
&SetupWizardDialog::onRemoveSearchDirectoryButtonClicked);
|
||||
menu->addSeparator();
|
||||
menu->addAction(QIcon(u":/icons/monochrome/svg/folder-open-line.svg"_s), tr("Open Directory..."), [this, row]() {
|
||||
const QTreeWidgetItem* const item = m_ui.searchDirectoryList->topLevelItem(row);
|
||||
if (item)
|
||||
QtUtils::OpenURL(this, QUrl::fromLocalFile(item->text(0)));
|
||||
});
|
||||
menu->addAction(QIcon(u":/icons/monochrome/svg/folder-open-line.svg"_s), tr("Open Directory..."),
|
||||
[this, path]() { QtUtils::OpenURL(this, QUrl::fromLocalFile(path)); });
|
||||
menu->popup(m_ui.searchDirectoryList->mapToGlobal(point));
|
||||
}
|
||||
|
||||
@@ -293,89 +291,26 @@ void SetupWizardDialog::onAddSearchDirectoryButtonClicked()
|
||||
if (selection != QMessageBox::Yes && selection != QMessageBox::No)
|
||||
return;
|
||||
|
||||
const bool recursive = (selection == QMessageBox::Yes);
|
||||
const std::string spath = dir.toStdString();
|
||||
Core::RemoveValueFromBaseStringListSetting("GameList", recursive ? "Paths" : "RecursivePaths", spath.c_str());
|
||||
Core::AddValueToBaseStringListSetting("GameList", recursive ? "RecursivePaths" : "Paths", spath.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
refreshDirectoryList();
|
||||
m_directory_model->addPath(dir.toStdString(), selection == QMessageBox::Yes);
|
||||
}
|
||||
|
||||
void SetupWizardDialog::onRemoveSearchDirectoryButtonClicked()
|
||||
{
|
||||
const QModelIndex index = m_ui.searchDirectoryList->currentIndex();
|
||||
const QTreeWidgetItem* const item = m_ui.searchDirectoryList->takeTopLevelItem(index.row());
|
||||
if (!item)
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
const std::string spath = item->text(0).toStdString();
|
||||
delete item;
|
||||
|
||||
if (!Core::RemoveValueFromBaseStringListSetting("GameList", "Paths", spath.c_str()) &&
|
||||
!Core::RemoveValueFromBaseStringListSetting("GameList", "RecursivePaths", spath.c_str()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Host::CommitBaseSettingChanges();
|
||||
refreshDirectoryList();
|
||||
m_directory_model->removePath(index);
|
||||
}
|
||||
|
||||
void SetupWizardDialog::onSearchDirectoryListSelectionChanged()
|
||||
{
|
||||
m_ui.removeSearchDirectoryButton->setEnabled(!m_ui.searchDirectoryList->selectedItems().isEmpty());
|
||||
}
|
||||
|
||||
void SetupWizardDialog::onSearchDirectoryListItemChanged(QTreeWidgetItem* item, int column)
|
||||
{
|
||||
if (column != 1)
|
||||
return;
|
||||
|
||||
const std::string path = item->text(0).toStdString();
|
||||
const bool recursive = (item->checkState(1) == Qt::Checked);
|
||||
|
||||
item->setIcon(0, QIcon(recursive ? u":/icons/monochrome/svg/folder-open-line.svg"_s :
|
||||
u":/icons/monochrome/svg/folder-line.svg"_s));
|
||||
|
||||
if (recursive)
|
||||
{
|
||||
Core::RemoveValueFromBaseStringListSetting("GameList", "Paths", path.c_str());
|
||||
Core::AddValueToBaseStringListSetting("GameList", "RecursivePaths", path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
Core::RemoveValueFromBaseStringListSetting("GameList", "RecursivePaths", path.c_str());
|
||||
Core::AddValueToBaseStringListSetting("GameList", "Paths", path.c_str());
|
||||
}
|
||||
|
||||
Host::CommitBaseSettingChanges();
|
||||
}
|
||||
|
||||
void SetupWizardDialog::addPathToTable(const std::string& path, bool recursive)
|
||||
{
|
||||
QTreeWidgetItem* const item = new QTreeWidgetItem();
|
||||
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
|
||||
item->setIcon(0, QIcon(recursive ? u":/icons/monochrome/svg/folder-open-line.svg"_s :
|
||||
u":/icons/monochrome/svg/folder-line.svg"_s));
|
||||
item->setText(0, QString::fromStdString(path));
|
||||
item->setCheckState(1, recursive ? Qt::Checked : Qt::Unchecked);
|
||||
m_ui.searchDirectoryList->addTopLevelItem(item);
|
||||
m_ui.removeSearchDirectoryButton->setEnabled(m_ui.searchDirectoryList->selectionModel()->hasSelection());
|
||||
}
|
||||
|
||||
void SetupWizardDialog::refreshDirectoryList()
|
||||
{
|
||||
QSignalBlocker sb(m_ui.searchDirectoryList);
|
||||
m_ui.searchDirectoryList->clear();
|
||||
|
||||
std::vector<std::string> path_list = Core::GetBaseStringListSetting("GameList", "Paths");
|
||||
for (const std::string& entry : path_list)
|
||||
addPathToTable(entry, false);
|
||||
|
||||
path_list = Core::GetBaseStringListSetting("GameList", "RecursivePaths");
|
||||
for (const std::string& entry : path_list)
|
||||
addPathToTable(entry, true);
|
||||
|
||||
m_ui.searchDirectoryList->sortByColumn(0, Qt::AscendingOrder);
|
||||
m_directory_model->reload();
|
||||
m_ui.removeSearchDirectoryButton->setEnabled(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
class GameListSearchDirectoriesModel;
|
||||
|
||||
class SetupWizardDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -63,13 +65,10 @@ private:
|
||||
void onAddSearchDirectoryButtonClicked();
|
||||
void onRemoveSearchDirectoryButtonClicked();
|
||||
void onSearchDirectoryListSelectionChanged();
|
||||
void onSearchDirectoryListItemChanged(QTreeWidgetItem* item, int column);
|
||||
void refreshDirectoryList();
|
||||
|
||||
void doMultipleDeviceAutomaticBinding(u32 port, QLabel* update_label);
|
||||
|
||||
void addPathToTable(const std::string& path, bool recursive);
|
||||
|
||||
QString findCurrentDeviceForPort(u32 port) const;
|
||||
void openAutomaticMappingMenu(u32 port, QLabel* update_label);
|
||||
void doDeviceAutomaticBinding(u32 port, QLabel* update_label, const QString& device);
|
||||
@@ -85,6 +84,7 @@ private:
|
||||
|
||||
private:
|
||||
Ui::SetupWizardDialog m_ui;
|
||||
GameListSearchDirectoriesModel* m_directory_model;
|
||||
|
||||
std::array<QLabel*, Page_Count> m_page_labels;
|
||||
};
|
||||
|
||||
@@ -555,13 +555,16 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="searchDirectoryList">
|
||||
<widget class="QTreeView" name="searchDirectoryList">
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::ContextMenuPolicy::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectionBehavior::SelectRows</enum>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
@@ -574,16 +577,6 @@
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Search Directory</string>
|
||||
</property>
|
||||
</column>
|
||||
<column>
|
||||
<property name="text">
|
||||
<string>Scan Recursively</string>
|
||||
</property>
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user