diff options
Diffstat (limited to 'src/yuzu/game_list.cpp')
| -rw-r--r-- | src/yuzu/game_list.cpp | 124 |
1 files changed, 83 insertions, 41 deletions
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index bfb600df0..a9738e298 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -56,7 +56,7 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve case Qt::Key_Return: case Qt::Key_Enter: { if (gamelist->search_field->visible == 1) { - QString file_path = gamelist->getLastFilterResultItem(); + const QString file_path = gamelist->GetLastFilterResultItem(); // To avoid loading error dialog loops while confirming them using enter // Also users usually want to run a different game after closing one @@ -83,22 +83,25 @@ void GameListSearchField::setFilterResult(int visible, int total) { label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); } -QString GameList::getLastFilterResultItem() const { - QStandardItem* folder; - QStandardItem* child; +QString GameList::GetLastFilterResultItem() const { QString file_path; const int folder_count = item_model->rowCount(); + for (int i = 0; i < folder_count; ++i) { - folder = item_model->item(i, 0); + const QStandardItem* folder = item_model->item(i, 0); const QModelIndex folder_index = folder->index(); const int children_count = folder->rowCount(); + for (int j = 0; j < children_count; ++j) { - if (!tree_view->isRowHidden(j, folder_index)) { - child = folder->child(j, 0); - file_path = child->data(GameListItemPath::FullPathRole).toString(); + if (tree_view->isRowHidden(j, folder_index)) { + continue; } + + const QStandardItem* child = folder->child(j, 0); + file_path = child->data(GameListItemPath::FullPathRole).toString(); } } + return file_path; } @@ -123,7 +126,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { edit_filter->setPlaceholderText(tr("Enter pattern to filter")); edit_filter->installEventFilter(key_release_eater); edit_filter->setClearButtonEnabled(true); - connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged); + connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::OnTextChanged); label_filter_result = new QLabel; button_filter_close = new QToolButton(this); button_filter_close->setText(QStringLiteral("X")); @@ -133,7 +136,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { "#000000; font-weight: bold; background: #F0F0F0; }" "QToolButton:hover{ border: none; padding: 0px; color: " "#EEEEEE; font-weight: bold; background: #E81123}")); - connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked); + connect(button_filter_close, &QToolButton::clicked, parent, &GameList::OnFilterCloseClicked); layout_filter->setSpacing(10); layout_filter->addWidget(label_filter); layout_filter->addWidget(edit_filter); @@ -159,16 +162,22 @@ static bool ContainsAllWords(const QString& haystack, const QString& userinput) } // Syncs the expanded state of Game Directories with settings to persist across sessions -void GameList::onItemExpanded(const QModelIndex& item) { +void GameList::OnItemExpanded(const QModelIndex& item) { const auto type = item.data(GameListItem::TypeRole).value<GameListItemType>(); - if (type == GameListItemType::CustomDir || type == GameListItemType::SdmcDir || - type == GameListItemType::UserNandDir || type == GameListItemType::SysNandDir) - item.data(GameListDir::GameDirRole).value<UISettings::GameDir*>()->expanded = - tree_view->isExpanded(item); + const bool is_dir = type == GameListItemType::CustomDir || type == GameListItemType::SdmcDir || + type == GameListItemType::UserNandDir || + type == GameListItemType::SysNandDir; + + if (!is_dir) { + return; + } + + auto* game_dir = item.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); + game_dir->expanded = tree_view->isExpanded(item); } // Event in order to filter the gamelist after editing the searchfield -void GameList::onTextChanged(const QString& new_text) { +void GameList::OnTextChanged(const QString& new_text) { const int folder_count = tree_view->model()->rowCount(); QString edit_filter_text = new_text.toLower(); QStandardItem* folder; @@ -224,7 +233,7 @@ void GameList::onTextChanged(const QString& new_text) { } } -void GameList::onUpdateThemedIcons() { +void GameList::OnUpdateThemedIcons() { for (int i = 0; i < item_model->invisibleRootItem()->rowCount(); i++) { QStandardItem* child = item_model->invisibleRootItem()->child(i); @@ -276,7 +285,7 @@ void GameList::onUpdateThemedIcons() { } } -void GameList::onFilterCloseClicked() { +void GameList::OnFilterCloseClicked() { main_window->filterBarSetChecked(false); } @@ -317,11 +326,11 @@ GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvide } item_model->setSortRole(GameListItemPath::SortRole); - connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::onUpdateThemedIcons); + connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons); connect(tree_view, &QTreeView::activated, this, &GameList::ValidateEntry); connect(tree_view, &QTreeView::customContextMenuRequested, this, &GameList::PopupContextMenu); - connect(tree_view, &QTreeView::expanded, this, &GameList::onItemExpanded); - connect(tree_view, &QTreeView::collapsed, this, &GameList::onItemExpanded); + connect(tree_view, &QTreeView::expanded, this, &GameList::OnItemExpanded); + connect(tree_view, &QTreeView::collapsed, this, &GameList::OnItemExpanded); // We must register all custom types with the Qt Automoc system so that we are able to use // it with signals/slots. In this case, QList falls under the umbrells of custom types. @@ -338,17 +347,17 @@ GameList::~GameList() { emit ShouldCancelWorker(); } -void GameList::setFilterFocus() { +void GameList::SetFilterFocus() { if (tree_view->model()->rowCount() > 0) { search_field->setFocus(); } } -void GameList::setFilterVisible(bool visibility) { +void GameList::SetFilterVisible(bool visibility) { search_field->setVisible(visibility); } -void GameList::clearFilter() { +void GameList::ClearFilter() { search_field->clear(); } @@ -397,22 +406,24 @@ void GameList::ValidateEntry(const QModelIndex& item) { } } -bool GameList::isEmpty() const { +bool GameList::IsEmpty() const { for (int i = 0; i < item_model->rowCount(); i++) { const QStandardItem* child = item_model->invisibleRootItem()->child(i); const auto type = static_cast<GameListItemType>(child->type()); + if (!child->hasChildren() && (type == GameListItemType::SdmcDir || type == GameListItemType::UserNandDir || type == GameListItemType::SysNandDir)) { item_model->invisibleRootItem()->removeRow(child->row()); i--; - }; + } } + return !item_model->invisibleRootItem()->hasChildren(); } -void GameList::DonePopulating(QStringList watch_list) { - emit ShowList(!isEmpty()); +void GameList::DonePopulating(const QStringList& watch_list) { + emit ShowList(!IsEmpty()); item_model->invisibleRootItem()->appendRow(new GameListAddDir()); @@ -472,30 +483,58 @@ void GameList::PopupContextMenu(const QPoint& menu_location) { context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location)); } -void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, std::string path) { +void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::string& path) { QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location")); - QAction* open_lfs_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 = context_menu.addAction(tr("Open Transferable Shader Cache")); context_menu.addSeparator(); + QMenu* remove_menu = context_menu.addMenu(tr("Remove")); + QAction* remove_update = remove_menu->addAction(tr("Remove Installed Update")); + QAction* remove_dlc = remove_menu->addAction(tr("Remove All Installed DLC")); + QAction* remove_shader_cache = remove_menu->addAction(tr("Remove Shader Cache")); + QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration")); + remove_menu->addSeparator(); + QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents")); QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS")); QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard")); QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry")); context_menu.addSeparator(); QAction* properties = context_menu.addAction(tr("Properties")); - open_save_location->setEnabled(program_id != 0); + open_save_location->setVisible(program_id != 0); + open_mod_location->setVisible(program_id != 0); + open_transferable_shader_cache->setVisible(program_id != 0); + remove_update->setVisible(program_id != 0); + remove_dlc->setVisible(program_id != 0); + remove_shader_cache->setVisible(program_id != 0); + remove_all_content->setVisible(program_id != 0); auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0); connect(open_save_location, &QAction::triggered, [this, program_id, path]() { - emit OpenFolderRequested(GameListOpenTarget::SaveData, path); + emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path); }); - connect(open_lfs_location, &QAction::triggered, [this, program_id, path]() { - emit OpenFolderRequested(GameListOpenTarget::ModData, path); + connect(open_mod_location, &QAction::triggered, [this, program_id, path]() { + emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path); }); connect(open_transferable_shader_cache, &QAction::triggered, [this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); }); + connect(remove_all_content, &QAction::triggered, [this, program_id]() { + emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::Game); + }); + connect(remove_update, &QAction::triggered, [this, program_id]() { + emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::Update); + }); + connect(remove_dlc, &QAction::triggered, [this, program_id]() { + emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::AddOnContent); + }); + connect(remove_shader_cache, &QAction::triggered, [this, program_id]() { + emit RemoveFileRequested(program_id, GameListRemoveTarget::ShaderCache); + }); + connect(remove_custom_config, &QAction::triggered, [this, program_id]() { + emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration); + }); connect(dump_romfs, &QAction::triggered, [this, program_id, path]() { emit DumpRomFSRequested(program_id, path); }); connect(copy_tid, &QAction::triggered, @@ -531,8 +570,8 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) { UISettings::GameDir& game_dir = *selected.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); - QAction* move_up = context_menu.addAction(tr(u8"\U000025b2 Move Up")); - QAction* move_down = context_menu.addAction(tr(u8"\U000025bc Move Down ")); + QAction* move_up = context_menu.addAction(tr("\u25B2 Move Up")); + QAction* move_down = context_menu.addAction(tr("\u25bc Move Down")); QAction* open_directory_location = context_menu.addAction(tr("Open Directory Location")); const int row = selected.row(); @@ -662,12 +701,15 @@ void GameList::SaveInterfaceLayout() { } void GameList::LoadInterfaceLayout() { - auto header = tree_view->header(); - if (!header->restoreState(UISettings::values.gamelist_header_state)) { - // We are using the name column to display icons and titles - // so make it as large as possible as default. - header->resizeSection(COLUMN_NAME, header->width()); + auto* header = tree_view->header(); + + if (header->restoreState(UISettings::values.gamelist_header_state)) { + return; } + + // We are using the name column to display icons and titles + // so make it as large as possible as default. + header->resizeSection(COLUMN_NAME, header->width()); } const QStringList GameList::supported_file_extensions = { |
