| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -11,6 +11,7 @@
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <QJsonDocument>
 | 
					 | 
					 | 
					 | 
					#include <QJsonDocument>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <QJsonObject>
 | 
					 | 
					 | 
					 | 
					#include <QJsonObject>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <QKeyEvent>
 | 
					 | 
					 | 
					 | 
					#include <QKeyEvent>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					#include <QList>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <QMenu>
 | 
					 | 
					 | 
					 | 
					#include <QMenu>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <QThreadPool>
 | 
					 | 
					 | 
					 | 
					#include <QThreadPool>
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					#include <fmt/format.h>
 | 
					 | 
					 | 
					 | 
					#include <fmt/format.h>
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -84,6 +85,10 @@ void GameListSearchField::setFilterResult(int visible, int total) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible));
 | 
					 | 
					 | 
					 | 
					    label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					bool GameListSearchField::isEmpty() const {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    return edit_filter->text().isEmpty();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					QString GameList::GetLastFilterResultItem() const {
 | 
					 | 
					 | 
					 | 
					QString GameList::GetLastFilterResultItem() const {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    QString file_path;
 | 
					 | 
					 | 
					 | 
					    QString file_path;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    const int folder_count = item_model->rowCount();
 | 
					 | 
					 | 
					 | 
					    const int folder_count = item_model->rowCount();
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -187,7 +192,9 @@ void GameList::OnTextChanged(const QString& new_text) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // If the searchfield is empty every item is visible
 | 
					 | 
					 | 
					 | 
					    // If the searchfield is empty every item is visible
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // Otherwise the filter gets applied
 | 
					 | 
					 | 
					 | 
					    // Otherwise the filter gets applied
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    if (edit_filter_text.isEmpty()) {
 | 
					 | 
					 | 
					 | 
					    if (edit_filter_text.isEmpty()) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for (int i = 0; i < folder_count; ++i) {
 | 
					 | 
					 | 
					 | 
					        tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(),
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                UISettings::values.favorited_ids.size() == 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        for (int i = 1; i < folder_count; ++i) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            folder = item_model->item(i, 0);
 | 
					 | 
					 | 
					 | 
					            folder = item_model->item(i, 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            const QModelIndex folder_index = folder->index();
 | 
					 | 
					 | 
					 | 
					            const QModelIndex folder_index = folder->index();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            const int children_count = folder->rowCount();
 | 
					 | 
					 | 
					 | 
					            const int children_count = folder->rowCount();
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -198,8 +205,9 @@ void GameList::OnTextChanged(const QString& new_text) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        search_field->setFilterResult(children_total, children_total);
 | 
					 | 
					 | 
					 | 
					        search_field->setFilterResult(children_total, children_total);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    } else {
 | 
					 | 
					 | 
					 | 
					    } else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        int result_count = 0;
 | 
					 | 
					 | 
					 | 
					        int result_count = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        for (int i = 0; i < folder_count; ++i) {
 | 
					 | 
					 | 
					 | 
					        for (int i = 1; i < folder_count; ++i) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            folder = item_model->item(i, 0);
 | 
					 | 
					 | 
					 | 
					            folder = item_model->item(i, 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            const QModelIndex folder_index = folder->index();
 | 
					 | 
					 | 
					 | 
					            const QModelIndex folder_index = folder->index();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            const int children_count = folder->rowCount();
 | 
					 | 
					 | 
					 | 
					            const int children_count = folder->rowCount();
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -280,6 +288,13 @@ void GameList::OnUpdateThemedIcons() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                    .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
 | 
					 | 
					 | 
					 | 
					                    .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					                Qt::DecorationRole);
 | 
					 | 
					 | 
					 | 
					                Qt::DecorationRole);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            break;
 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        case GameListItemType::Favorites:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            child->setData(
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                QIcon::fromTheme(QStringLiteral("star"))
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    .pixmap(icon_size)
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    .scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                Qt::DecorationRole);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        default:
 | 
					 | 
					 | 
					 | 
					        default:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            break;
 | 
					 | 
					 | 
					 | 
					            break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        }
 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -427,6 +442,13 @@ void GameList::DonePopulating(const QStringList& watch_list) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    emit ShowList(!IsEmpty());
 | 
					 | 
					 | 
					 | 
					    emit ShowList(!IsEmpty());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    item_model->invisibleRootItem()->appendRow(new GameListAddDir());
 | 
					 | 
					 | 
					 | 
					    item_model->invisibleRootItem()->appendRow(new GameListAddDir());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    item_model->invisibleRootItem()->insertRow(0, new GameListFavorites());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                            UISettings::values.favorited_ids.size() == 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    tree_view->expand(item_model->invisibleRootItem()->child(0)->index());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (const auto id : UISettings::values.favorited_ids) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        AddFavorite(id);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    // Clear out the old directories to watch for changes and add the new ones
 | 
					 | 
					 | 
					 | 
					    // Clear out the old directories to watch for changes and add the new ones
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    auto watch_dirs = watcher->directories();
 | 
					 | 
					 | 
					 | 
					    auto watch_dirs = watcher->directories();
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -446,7 +468,7 @@ void GameList::DonePopulating(const QStringList& watch_list) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    tree_view->setEnabled(true);
 | 
					 | 
					 | 
					 | 
					    tree_view->setEnabled(true);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    const int folder_count = tree_view->model()->rowCount();
 | 
					 | 
					 | 
					 | 
					    const int folder_count = tree_view->model()->rowCount();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    int children_total = 0;
 | 
					 | 
					 | 
					 | 
					    int children_total = 0;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    for (int i = 0; i < folder_count; ++i) {
 | 
					 | 
					 | 
					 | 
					    for (int i = 1; i < folder_count; ++i) {
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        children_total += item_model->item(i, 0)->rowCount();
 | 
					 | 
					 | 
					 | 
					        children_total += item_model->item(i, 0)->rowCount();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    search_field->setFilterResult(children_total, children_total);
 | 
					 | 
					 | 
					 | 
					    search_field->setFilterResult(children_total, children_total);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -478,6 +500,9 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    case GameListItemType::SysNandDir:
 | 
					 | 
					 | 
					 | 
					    case GameListItemType::SysNandDir:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        AddPermDirPopup(context_menu, selected);
 | 
					 | 
					 | 
					 | 
					        AddPermDirPopup(context_menu, selected);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break;
 | 
					 | 
					 | 
					 | 
					        break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    case GameListItemType::Favorites:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        AddFavoritesPopup(context_menu);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    default:
 | 
					 | 
					 | 
					 | 
					    default:
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        break;
 | 
					 | 
					 | 
					 | 
					        break;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -485,6 +510,8 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path) {
 | 
					 | 
					 | 
					 | 
					void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    QAction* favorite = context_menu.addAction(tr("Favorite"));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    context_menu.addSeparator();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
 | 
					 | 
					 | 
					 | 
					    QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location"));
 | 
					 | 
					 | 
					 | 
					    QAction* open_mod_location = context_menu.addAction(tr("Open Mod Data Location"));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    QAction* open_transferable_shader_cache =
 | 
					 | 
					 | 
					 | 
					    QAction* open_transferable_shader_cache =
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -503,6 +530,9 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    context_menu.addSeparator();
 | 
					 | 
					 | 
					 | 
					    context_menu.addSeparator();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    QAction* properties = context_menu.addAction(tr("Properties"));
 | 
					 | 
					 | 
					 | 
					    QAction* properties = context_menu.addAction(tr("Properties"));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    favorite->setVisible(program_id != 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    favorite->setCheckable(true);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    favorite->setChecked(UISettings::values.favorited_ids.contains(program_id));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    open_save_location->setVisible(program_id != 0);
 | 
					 | 
					 | 
					 | 
					    open_save_location->setVisible(program_id != 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    open_mod_location->setVisible(program_id != 0);
 | 
					 | 
					 | 
					 | 
					    open_mod_location->setVisible(program_id != 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    open_transferable_shader_cache->setVisible(program_id != 0);
 | 
					 | 
					 | 
					 | 
					    open_transferable_shader_cache->setVisible(program_id != 0);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -513,6 +543,7 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
 | 
					 | 
					 | 
					 | 
					    auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0);
 | 
					 | 
					 | 
					 | 
					    navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    connect(favorite, &QAction::triggered, [this, program_id]() { ToggleFavorite(program_id); });
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    connect(open_save_location, &QAction::triggered, [this, program_id, path]() {
 | 
					 | 
					 | 
					 | 
					    connect(open_save_location, &QAction::triggered, [this, program_id, path]() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					        emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
 | 
					 | 
					 | 
					 | 
					        emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    });
 | 
					 | 
					 | 
					 | 
					    });
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -576,7 +607,7 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    const int row = selected.row();
 | 
					 | 
					 | 
					 | 
					    const int row = selected.row();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    move_up->setEnabled(row > 0);
 | 
					 | 
					 | 
					 | 
					    move_up->setEnabled(row > 1);
 | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    move_down->setEnabled(row < item_model->rowCount() - 2);
 | 
					 | 
					 | 
					 | 
					    move_down->setEnabled(row < item_model->rowCount() - 2);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    connect(move_up, &QAction::triggered, [this, selected, row, game_dir_index] {
 | 
					 | 
					 | 
					 | 
					    connect(move_up, &QAction::triggered, [this, selected, row, game_dir_index] {
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -614,6 +645,18 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    });
 | 
					 | 
					 | 
					 | 
					    });
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void GameList::AddFavoritesPopup(QMenu& context_menu) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    QAction* clear_all = context_menu.addAction(tr("Clear"));
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    connect(clear_all, &QAction::triggered, [this] {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        for (const auto id : UISettings::values.favorited_ids) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            RemoveFavorite(id);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        UISettings::values.favorited_ids.clear();
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    });
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					void GameList::LoadCompatibilityList() {
 | 
					 | 
					 | 
					 | 
					void GameList::LoadCompatibilityList() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    QFile compat_list{QStringLiteral(":compatibility_list/compatibility_list.json")};
 | 
					 | 
					 | 
					 | 
					    QFile compat_list{QStringLiteral(":compatibility_list/compatibility_list.json")};
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -728,6 +771,58 @@ void GameList::RefreshGameDirectory() {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    }
 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}
 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void GameList::ToggleFavorite(u64 program_id) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (!UISettings::values.favorited_ids.contains(program_id)) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                !search_field->isEmpty());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        UISettings::values.favorited_ids.append(program_id);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        AddFavorite(program_id);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        item_model->sort(tree_view->header()->sortIndicatorSection(),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                         tree_view->header()->sortIndicatorOrder());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    } else {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        UISettings::values.favorited_ids.removeOne(program_id);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        RemoveFavorite(program_id);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (UISettings::values.favorited_ids.size() == 0) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            tree_view->setRowHidden(0, item_model->invisibleRootItem()->index(), true);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void GameList::AddFavorite(u64 program_id) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    auto* favorites_row = item_model->item(0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (int i = 1; i < item_model->rowCount() - 1; i++) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        const auto* folder = item_model->item(i);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        for (int j = 0; j < folder->rowCount(); j++) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            if (folder->child(j)->data(GameListItemPath::ProgramIdRole).toULongLong() ==
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                program_id) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                QList<QStandardItem*> list;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                for (int k = 0; k < item_model->columnCount(); k++) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                    list.append(folder->child(j, k)->clone());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                list[0]->setData(folder->child(j)->data(GameListItem::SortRole),
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                                 GameListItem::SortRole);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                list[0]->setText(folder->child(j)->data(Qt::DisplayRole).toString());
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                favorites_row->appendRow(list);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					                return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					void GameList::RemoveFavorite(u64 program_id) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    auto* favorites_row = item_model->item(0);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    for (int i = 0; i < favorites_row->rowCount(); i++) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        const auto* game = favorites_row->child(i);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        if (game->data(GameListItemPath::ProgramIdRole).toULongLong() == program_id) {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            favorites_row->removeRow(i);
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					            return;
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					        }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					    }
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} {
 | 
					 | 
					 | 
					 | 
					GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} {
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					    connect(parent, &GMainWindow::UpdateThemedIcons, this,
 | 
					 | 
					 | 
					 | 
					    connect(parent, &GMainWindow::UpdateThemedIcons, this,
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					            &GameListPlaceholder::onUpdateThemedIcons);
 | 
					 | 
					 | 
					 | 
					            &GameListPlaceholder::onUpdateThemedIcons);
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
 
 |