diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 864b62cc92..2333c1a860 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -102,6 +102,7 @@ enum MenuIdentifiers MenuId_RecentIsos_reservedStart, MenuId_IsoBrowse = MenuId_RecentIsos_reservedStart + 100, // Open dialog, runs selected iso. MenuId_IsoClear, + MenuId_IsoClearMissing, MenuId_DriveSelector, MenuId_DriveListRefresh, MenuId_Ask_On_Booting, diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index 5a788aacf2..fea7390583 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -275,6 +275,7 @@ void MainEmuFrame::ConnectMenus() // CDVD Bind(wxEVT_MENU, &MainEmuFrame::Menu_IsoBrowse_Click, this, MenuId_IsoBrowse); Bind(wxEVT_MENU, &MainEmuFrame::Menu_IsoClear_Click, this, MenuId_IsoClear); + Bind(wxEVT_MENU, &MainEmuFrame::Menu_IsoClearMissing_Click, this, MenuId_IsoClearMissing); Bind(wxEVT_MENU, &MainEmuFrame::Menu_CdvdSource_Click, this, MenuId_Src_Iso); Bind(wxEVT_MENU, &MainEmuFrame::Menu_CdvdSource_Click, this, MenuId_Src_Disc); Bind(wxEVT_MENU, &MainEmuFrame::Menu_CdvdSource_Click, this, MenuId_Src_NoDisc); diff --git a/pcsx2/gui/MainFrame.h b/pcsx2/gui/MainFrame.h index 27e5dd0df3..f8fb480a95 100644 --- a/pcsx2/gui/MainFrame.h +++ b/pcsx2/gui/MainFrame.h @@ -162,6 +162,7 @@ protected: void Menu_IsoBrowse_Click(wxCommandEvent& event); void Menu_IsoClear_Click(wxCommandEvent& event); + void Menu_IsoClearMissing_Click(wxCommandEvent& event); void Menu_EnableBackupStates_Click(wxCommandEvent& event); void Menu_EnablePatches_Click(wxCommandEvent& event); void Menu_EnableCheats_Click(wxCommandEvent& event); diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index 7d90ab2348..33a19f1656 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -579,6 +579,46 @@ void MainEmuFrame::Menu_IsoClear_Click(wxCommandEvent& event) } } +void MainEmuFrame::Menu_IsoClearMissing_Click(wxCommandEvent& event) +{ + auto& iso_manager = wxGetApp().GetRecentIsoManager(); + const auto& missing_files = iso_manager.GetMissingFiles(); + + if (missing_files.empty()) + { + wxDialogWithHelpers dialog(this, _("Information")); + dialog += dialog.Heading(_("No files to remove.")); + pxIssueConfirmation(dialog, MsgButtons().OK()); + } + else + { + wxDialogWithHelpers dialog(this, _("Confirm clearing ISO list")); + dialog += dialog.Heading(_("The following entries will be removed from the ISO list. Continue?")); + + wxString missing_files_list; + + for (const auto& file : missing_files) + { + missing_files_list += "* "; + missing_files_list += file.Filename; + missing_files_list += "\n"; + } + + dialog += dialog.Text(missing_files_list); + + const bool confirmed = pxIssueConfirmation(dialog, MsgButtons().YesNo()) == wxID_YES; + + if (confirmed) + { + // If the CDVD mode is not ISO, or the system isn't running, wipe the CurrentIso field in INI file + if (g_Conf->CdvdSource != CDVD_SourceType::Iso || !SysHasValidState()) + SysUpdateIsoSrcFile(""); + iso_manager.ClearMissing(); + AppSaveSettings(); + } + } +} + void MainEmuFrame::Menu_Ask_On_Boot_Click(wxCommandEvent& event) { g_Conf->AskOnBoot = event.IsChecked(); diff --git a/pcsx2/gui/RecentIsoList.cpp b/pcsx2/gui/RecentIsoList.cpp index 24670932a4..a17bdde600 100644 --- a/pcsx2/gui/RecentIsoList.cpp +++ b/pcsx2/gui/RecentIsoList.cpp @@ -38,6 +38,7 @@ RecentIsoManager::RecentIsoManager( wxMenu* menu, int firstIdForMenuItems_or_wxI m_Separator = nullptr; m_ClearSeparator = nullptr; m_Clear = nullptr; + m_ClearMissing = nullptr; IniLoader loader; LoadListFrom(loader); @@ -116,6 +117,12 @@ void RecentIsoManager::RemoveAllFromMenu() m_Menu->Destroy( m_Clear ); m_Clear = nullptr; } + + if (m_ClearMissing != nullptr) + { + m_Menu->Destroy(m_ClearMissing); + m_ClearMissing = nullptr; + } } void RecentIsoManager::Clear() @@ -125,6 +132,40 @@ void RecentIsoManager::Clear() Repopulate(); } +RecentIsoManager::VectorType RecentIsoManager::GetMissingFiles() const +{ + VectorType missing_files; + + std::copy_if( + m_Items.begin(), + m_Items.end(), + std::back_inserter(missing_files), + [](const RecentItem& item) { + return !wxFileExists(item.Filename); + }); + + return missing_files; +} + +void RecentIsoManager::ClearMissing() +{ + RemoveAllFromMenu(); + + VectorType existing_files; + + std::copy_if( + m_Items.begin(), + m_Items.end(), + std::back_inserter(existing_files), + [](const RecentItem& item) { + return wxFileExists(item.Filename); + }); + + m_Items = existing_files; + + Repopulate(); +} + void RecentIsoManager::Repopulate() { int cnt = m_Items.size(); @@ -138,6 +179,7 @@ void RecentIsoManager::Repopulate() InsertIntoMenu( i ); m_ClearSeparator = m_Menu->AppendSeparator(); + m_ClearMissing = m_Menu->Append(MenuIdentifiers::MenuId_IsoClearMissing, _("Clear missing files")); m_Clear = m_Menu->Append(MenuIdentifiers::MenuId_IsoClear, _("Clear ISO list")); } diff --git a/pcsx2/gui/RecentIsoList.h b/pcsx2/gui/RecentIsoList.h index 480645f276..32e6897d5e 100644 --- a/pcsx2/gui/RecentIsoList.h +++ b/pcsx2/gui/RecentIsoList.h @@ -38,7 +38,11 @@ protected: } }; - std::vector m_Items; +public: + using VectorType = std::vector; + +protected: + VectorType m_Items; wxMenu* m_Menu; uint m_MaxLength; @@ -49,15 +53,19 @@ protected: wxMenuItem* m_Separator; wxMenuItem* m_ClearSeparator; wxMenuItem* m_Clear; + wxMenuItem* m_ClearMissing; public: RecentIsoManager( wxMenu* menu , int firstIdForMenuItems_or_wxID_ANY ); virtual ~RecentIsoManager(); + VectorType GetMissingFiles() const; + void RemoveAllFromMenu(); void EnableItems(bool display); void Repopulate(); void Clear(); + void ClearMissing(); void Add( const wxString& src ); protected: