summaryrefslogtreecommitdiff
path: root/src/citra_qt/game_list.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/citra_qt/game_list.cpp')
-rw-r--r--src/citra_qt/game_list.cpp65
1 files changed, 28 insertions, 37 deletions
diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp
index 1910da3ac..07bc35308 100644
--- a/src/citra_qt/game_list.cpp
+++ b/src/citra_qt/game_list.cpp
@@ -5,19 +5,15 @@
5#include <QHeaderView> 5#include <QHeaderView>
6#include <QThreadPool> 6#include <QThreadPool>
7#include <QVBoxLayout> 7#include <QVBoxLayout>
8
9#include "game_list.h"
10#include "game_list_p.h"
11#include "ui_settings.h"
12
13#include "core/loader/loader.h"
14
15#include "common/common_paths.h" 8#include "common/common_paths.h"
16#include "common/logging/log.h" 9#include "common/logging/log.h"
17#include "common/string_util.h" 10#include "common/string_util.h"
11#include "core/loader/loader.h"
12#include "game_list.h"
13#include "game_list_p.h"
14#include "ui_settings.h"
18 15
19GameList::GameList(QWidget* parent) 16GameList::GameList(QWidget* parent) {
20{
21 QVBoxLayout* layout = new QVBoxLayout; 17 QVBoxLayout* layout = new QVBoxLayout;
22 18
23 tree_view = new QTreeView; 19 tree_view = new QTreeView;
@@ -38,9 +34,11 @@ GameList::GameList(QWidget* parent)
38 item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type"); 34 item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type");
39 item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size"); 35 item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size");
40 36
41 connect(tree_view, SIGNAL(activated(const QModelIndex&)), this, SLOT(ValidateEntry(const QModelIndex&))); 37 connect(tree_view, SIGNAL(activated(const QModelIndex&)), this,
38 SLOT(ValidateEntry(const QModelIndex&)));
42 39
43 // We must register all custom types with the Qt Automoc system so that we are able to use it with 40 // We must register all custom types with the Qt Automoc system so that we are able to use it
41 // with
44 // signals/slots. In this case, QList falls under the umbrells of custom types. 42 // signals/slots. In this case, QList falls under the umbrells of custom types.
45 qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>"); 43 qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
46 44
@@ -48,18 +46,15 @@ GameList::GameList(QWidget* parent)
48 setLayout(layout); 46 setLayout(layout);
49} 47}
50 48
51GameList::~GameList() 49GameList::~GameList() {
52{
53 emit ShouldCancelWorker(); 50 emit ShouldCancelWorker();
54} 51}
55 52
56void GameList::AddEntry(QList<QStandardItem*> entry_items) 53void GameList::AddEntry(QList<QStandardItem*> entry_items) {
57{
58 item_model->invisibleRootItem()->appendRow(entry_items); 54 item_model->invisibleRootItem()->appendRow(entry_items);
59} 55}
60 56
61void GameList::ValidateEntry(const QModelIndex& item) 57void GameList::ValidateEntry(const QModelIndex& item) {
62{
63 // We don't care about the individual QStandardItem that was selected, but its row. 58 // We don't care about the individual QStandardItem that was selected, but its row.
64 int row = item_model->itemFromIndex(item)->row(); 59 int row = item_model->itemFromIndex(item)->row();
65 QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME); 60 QStandardItem* child_file = item_model->invisibleRootItem()->child(row, COLUMN_NAME);
@@ -73,14 +68,13 @@ void GameList::ValidateEntry(const QModelIndex& item)
73 emit GameChosen(file_path); 68 emit GameChosen(file_path);
74} 69}
75 70
76void GameList::DonePopulating() 71void GameList::DonePopulating() {
77{
78 tree_view->setEnabled(true); 72 tree_view->setEnabled(true);
79} 73}
80 74
81void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) 75void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
82{ 76 if (!FileUtil::Exists(dir_path.toStdString()) ||
83 if (!FileUtil::Exists(dir_path.toStdString()) || !FileUtil::IsDirectory(dir_path.toStdString())) { 77 !FileUtil::IsDirectory(dir_path.toStdString())) {
84 LOG_ERROR(Frontend, "Could not find game list folder at %s", dir_path.toLocal8Bit().data()); 78 LOG_ERROR(Frontend, "Could not find game list folder at %s", dir_path.toLocal8Bit().data());
85 return; 79 return;
86 } 80 }
@@ -92,22 +86,22 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan)
92 emit ShouldCancelWorker(); 86 emit ShouldCancelWorker();
93 GameListWorker* worker = new GameListWorker(dir_path, deep_scan); 87 GameListWorker* worker = new GameListWorker(dir_path, deep_scan);
94 88
95 connect(worker, SIGNAL(EntryReady(QList<QStandardItem*>)), this, SLOT(AddEntry(QList<QStandardItem*>)), Qt::QueuedConnection); 89 connect(worker, SIGNAL(EntryReady(QList<QStandardItem*>)), this,
90 SLOT(AddEntry(QList<QStandardItem*>)), Qt::QueuedConnection);
96 connect(worker, SIGNAL(Finished()), this, SLOT(DonePopulating()), Qt::QueuedConnection); 91 connect(worker, SIGNAL(Finished()), this, SLOT(DonePopulating()), Qt::QueuedConnection);
97 // Use DirectConnection here because worker->Cancel() is thread-safe and we want it to cancel without delay. 92 // Use DirectConnection here because worker->Cancel() is thread-safe and we want it to cancel
93 // without delay.
98 connect(this, SIGNAL(ShouldCancelWorker()), worker, SLOT(Cancel()), Qt::DirectConnection); 94 connect(this, SIGNAL(ShouldCancelWorker()), worker, SLOT(Cancel()), Qt::DirectConnection);
99 95
100 QThreadPool::globalInstance()->start(worker); 96 QThreadPool::globalInstance()->start(worker);
101 current_worker = std::move(worker); 97 current_worker = std::move(worker);
102} 98}
103 99
104void GameList::SaveInterfaceLayout() 100void GameList::SaveInterfaceLayout() {
105{
106 UISettings::values.gamelist_header_state = tree_view->header()->saveState(); 101 UISettings::values.gamelist_header_state = tree_view->header()->saveState();
107} 102}
108 103
109void GameList::LoadInterfaceLayout() 104void GameList::LoadInterfaceLayout() {
110{
111 auto header = tree_view->header(); 105 auto header = tree_view->header();
112 if (!header->restoreState(UISettings::values.gamelist_header_state)) { 106 if (!header->restoreState(UISettings::values.gamelist_header_state)) {
113 // We are using the name column to display icons and titles 107 // We are using the name column to display icons and titles
@@ -118,10 +112,8 @@ void GameList::LoadInterfaceLayout()
118 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder()); 112 item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
119} 113}
120 114
121void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) 115void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion) {
122{ 116 const auto callback = [this, recursion](unsigned* num_entries_out, const std::string& directory,
123 const auto callback = [this, recursion](unsigned* num_entries_out,
124 const std::string& directory,
125 const std::string& virtual_name) -> bool { 117 const std::string& virtual_name) -> bool {
126 std::string physical_name = directory + DIR_SEP + virtual_name; 118 std::string physical_name = directory + DIR_SEP + virtual_name;
127 119
@@ -138,7 +130,8 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
138 130
139 emit EntryReady({ 131 emit EntryReady({
140 new GameListItemPath(QString::fromStdString(physical_name), smdh), 132 new GameListItemPath(QString::fromStdString(physical_name), smdh),
141 new GameListItem(QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))), 133 new GameListItem(
134 QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
142 new GameListItemSize(FileUtil::GetSize(physical_name)), 135 new GameListItemSize(FileUtil::GetSize(physical_name)),
143 }); 136 });
144 } else if (recursion > 0) { 137 } else if (recursion > 0) {
@@ -151,15 +144,13 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
151 FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback); 144 FileUtil::ForeachDirectoryEntry(nullptr, dir_path, callback);
152} 145}
153 146
154void GameListWorker::run() 147void GameListWorker::run() {
155{
156 stop_processing = false; 148 stop_processing = false;
157 AddFstEntriesToGameList(dir_path.toStdString(), deep_scan ? 256 : 0); 149 AddFstEntriesToGameList(dir_path.toStdString(), deep_scan ? 256 : 0);
158 emit Finished(); 150 emit Finished();
159} 151}
160 152
161void GameListWorker::Cancel() 153void GameListWorker::Cancel() {
162{
163 disconnect(this, 0, 0, 0); 154 disconnect(this, 0, 0, 0);
164 stop_processing = true; 155 stop_processing = true;
165} 156}