diff --git a/Source/Core/DolphinWX/CMakeLists.txt b/Source/Core/DolphinWX/CMakeLists.txt
index 31927c0422..7b00f96329 100644
--- a/Source/Core/DolphinWX/CMakeLists.txt
+++ b/Source/Core/DolphinWX/CMakeLists.txt
@@ -34,6 +34,7 @@ set(GUI_SRCS
Debugger/RegisterWindow.cpp
Debugger/WatchView.cpp
Debugger/WatchWindow.cpp
+ ISOProperties/FilesystemPanel.cpp
ISOProperties/InfoPanel.cpp
ISOProperties/ISOProperties.cpp
NetPlay/ChangeGameDialog.cpp
diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj b/Source/Core/DolphinWX/DolphinWX.vcxproj
index a4738e1af5..d88b6f06e0 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcxproj
+++ b/Source/Core/DolphinWX/DolphinWX.vcxproj
@@ -90,6 +90,7 @@
+
@@ -146,6 +147,7 @@
+
diff --git a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
index eb099a84b3..8ce65746ae 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
+++ b/Source/Core/DolphinWX/DolphinWX.vcxproj.filters
@@ -224,6 +224,9 @@
GUI\Config
+
+ GUI\ISOProperties
+
GUI\ISOProperties
@@ -437,6 +440,9 @@
GUI\Config
+
+ GUI\ISOProperties
+
GUI\ISOProperties
diff --git a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp
new file mode 100644
index 0000000000..bd1fc44f3b
--- /dev/null
+++ b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.cpp
@@ -0,0 +1,641 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DolphinWX/ISOProperties/FilesystemPanel.h"
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "Common/CommonPaths.h"
+#include "Common/FileUtil.h"
+#include "Common/Logging/Log.h"
+#include "DiscIO/Enums.h"
+#include "DiscIO/Filesystem.h"
+#include "DiscIO/Volume.h"
+#include "DiscIO/VolumeCreator.h"
+#include "DolphinWX/ISOFile.h"
+#include "DolphinWX/WxUtils.h"
+
+namespace
+{
+class WiiPartition final : public wxTreeItemData
+{
+public:
+ WiiPartition(std::unique_ptr volume_,
+ std::unique_ptr filesystem_)
+ : volume{std::move(volume_)}, filesystem{std::move(filesystem_)}
+ {
+ }
+
+ std::unique_ptr volume;
+ std::unique_ptr filesystem;
+};
+
+class IntegrityCheckThread final : public wxThread
+{
+public:
+ explicit IntegrityCheckThread(const WiiPartition& partition)
+ : wxThread{wxTHREAD_JOINABLE}, m_partition{partition}
+ {
+ Create();
+ }
+
+ ExitCode Entry() override
+ {
+ return reinterpret_cast(m_partition.volume->CheckIntegrity());
+ }
+
+private:
+ const WiiPartition& m_partition;
+};
+
+enum : int
+{
+ ICON_DISC,
+ ICON_FOLDER,
+ ICON_FILE
+};
+
+wxImageList* LoadIconBitmaps(const wxWindow* context)
+{
+ static constexpr std::array icon_names{
+ {"isoproperties_disc", "isoproperties_folder", "isoproperties_file"}};
+
+ const wxSize icon_size = context->FromDIP(wxSize(16, 16));
+ auto* const icon_list = new wxImageList(icon_size.GetWidth(), icon_size.GetHeight());
+
+ for (const auto& name : icon_names)
+ {
+ icon_list->Add(
+ WxUtils::LoadScaledResourceBitmap(name, context, icon_size, wxDefaultSize,
+ WxUtils::LSI_SCALE_DOWN | WxUtils::LSI_ALIGN_CENTER));
+ }
+
+ return icon_list;
+}
+
+size_t CreateDirectoryTree(wxTreeCtrl* tree_ctrl, wxTreeItemId parent,
+ const std::vector& file_infos,
+ const size_t first_index, const size_t last_index)
+{
+ size_t current_index = first_index;
+
+ while (current_index < last_index)
+ {
+ const DiscIO::SFileInfo& file_info = file_infos[current_index];
+ std::string file_path = file_info.m_FullPath;
+
+ // Trim the trailing '/' if it exists.
+ if (file_path.back() == DIR_SEP_CHR)
+ {
+ file_path.pop_back();
+ }
+
+ // Cut off the path up to the actual filename or folder.
+ // Say we have "/music/stream/stream1.strm", the result will be "stream1.strm".
+ const size_t dir_sep_index = file_path.rfind(DIR_SEP_CHR);
+ if (dir_sep_index != std::string::npos)
+ {
+ file_path = file_path.substr(dir_sep_index + 1);
+ }
+
+ // check next index
+ if (file_info.IsDirectory())
+ {
+ const wxTreeItemId item = tree_ctrl->AppendItem(parent, StrToWxStr(file_path), ICON_FOLDER);
+ current_index = CreateDirectoryTree(tree_ctrl, item, file_infos, current_index + 1,
+ static_cast(file_info.m_FileSize));
+ }
+ else
+ {
+ tree_ctrl->AppendItem(parent, StrToWxStr(file_path), ICON_FILE);
+ current_index++;
+ }
+ }
+
+ return current_index;
+}
+
+size_t CreateDirectoryTree(wxTreeCtrl* tree_ctrl, wxTreeItemId parent,
+ const std::vector& file_infos)
+{
+ if (file_infos.empty())
+ return 0;
+
+ return CreateDirectoryTree(tree_ctrl, parent, file_infos, 1, file_infos.at(0).m_FileSize);
+}
+
+WiiPartition* FindWiiPartition(wxTreeCtrl* tree_ctrl, const wxString& label)
+{
+ wxTreeItemIdValue cookie;
+ auto partition = tree_ctrl->GetFirstChild(tree_ctrl->GetRootItem(), cookie);
+
+ while (partition.IsOk())
+ {
+ const wxString partition_label = tree_ctrl->GetItemText(partition);
+
+ if (partition_label == label)
+ return static_cast(tree_ctrl->GetItemData(partition));
+
+ partition = tree_ctrl->GetNextSibling(partition);
+ }
+
+ return nullptr;
+}
+} // Anonymous namespace
+
+FilesystemPanel::FilesystemPanel(wxWindow* parent, wxWindowID id, const GameListItem& item,
+ const std::unique_ptr& opened_iso)
+ : wxPanel{parent, id}, m_game_list_item{item}, m_opened_iso{opened_iso}
+{
+ CreateGUI();
+ BindEvents();
+ PopulateFileSystemTree();
+
+ m_tree_ctrl->Expand(m_tree_ctrl->GetRootItem());
+}
+
+FilesystemPanel::~FilesystemPanel() = default;
+
+void FilesystemPanel::BindEvents()
+{
+ m_tree_ctrl->Bind(wxEVT_TREE_ITEM_RIGHT_CLICK, &FilesystemPanel::OnRightClickTree, this);
+
+ Bind(wxEVT_MENU, &FilesystemPanel::OnExtractFile, this, ID_EXTRACT_FILE);
+ Bind(wxEVT_MENU, &FilesystemPanel::OnExtractDirectories, this, ID_EXTRACT_ALL);
+ Bind(wxEVT_MENU, &FilesystemPanel::OnExtractDirectories, this, ID_EXTRACT_DIR);
+ Bind(wxEVT_MENU, &FilesystemPanel::OnExtractHeaderData, this, ID_EXTRACT_APPLOADER);
+ Bind(wxEVT_MENU, &FilesystemPanel::OnExtractHeaderData, this, ID_EXTRACT_DOL);
+ Bind(wxEVT_MENU, &FilesystemPanel::OnCheckPartitionIntegrity, this, ID_CHECK_INTEGRITY);
+}
+
+void FilesystemPanel::CreateGUI()
+{
+ m_tree_ctrl = new wxTreeCtrl(this);
+ m_tree_ctrl->AssignImageList(LoadIconBitmaps(this));
+ m_tree_ctrl->AddRoot(_("Disc"), ICON_DISC);
+
+ const auto space_5 = FromDIP(5);
+ auto* const main_sizer = new wxBoxSizer(wxVERTICAL);
+ main_sizer->AddSpacer(space_5);
+ main_sizer->Add(m_tree_ctrl, 1, wxEXPAND | wxLEFT | wxRIGHT, space_5);
+ main_sizer->AddSpacer(space_5);
+
+ SetSizer(main_sizer);
+}
+
+void FilesystemPanel::PopulateFileSystemTree()
+{
+ switch (m_opened_iso->GetVolumeType())
+ {
+ case DiscIO::Platform::GAMECUBE_DISC:
+ PopulateFileSystemTreeGC();
+ break;
+
+ case DiscIO::Platform::WII_DISC:
+ PopulateFileSystemTreeWii();
+ break;
+
+ case DiscIO::Platform::ELF_DOL:
+ case DiscIO::Platform::NUMBER_OF_PLATFORMS:
+ case DiscIO::Platform::WII_WAD:
+ break;
+ }
+}
+
+void FilesystemPanel::PopulateFileSystemTreeGC()
+{
+ m_filesystem = DiscIO::CreateFileSystem(m_opened_iso.get());
+ if (!m_filesystem)
+ return;
+
+ CreateDirectoryTree(m_tree_ctrl, m_tree_ctrl->GetRootItem(), m_filesystem->GetFileList());
+}
+
+void FilesystemPanel::PopulateFileSystemTreeWii() const
+{
+ u32 partition_count = 0;
+
+ for (u32 group = 0; group < 4; group++)
+ {
+ // yes, technically there can be OVER NINE THOUSAND partitions...
+ for (u32 i = 0; i < 0xFFFFFFFF; i++)
+ {
+ auto volume = DiscIO::CreateVolumeFromFilename(m_game_list_item.GetFileName(), group, i);
+ if (volume == nullptr)
+ break;
+
+ auto file_system = DiscIO::CreateFileSystem(volume.get());
+ if (file_system != nullptr)
+ {
+ auto* const partition = new WiiPartition(std::move(volume), std::move(file_system));
+
+ const wxTreeItemId partition_root = m_tree_ctrl->AppendItem(
+ m_tree_ctrl->GetRootItem(), wxString::Format(_("Partition %u"), partition_count),
+ ICON_DISC);
+
+ m_tree_ctrl->SetItemData(partition_root, partition);
+ CreateDirectoryTree(m_tree_ctrl, partition_root, partition->filesystem->GetFileList());
+
+ if (partition_count == 1)
+ m_tree_ctrl->Expand(partition_root);
+
+ partition_count++;
+ }
+ }
+ }
+}
+
+void FilesystemPanel::OnRightClickTree(wxTreeEvent& event)
+{
+ m_tree_ctrl->SelectItem(event.GetItem());
+
+ wxMenu menu;
+
+ const auto selection = m_tree_ctrl->GetSelection();
+ const auto first_visible_item = m_tree_ctrl->GetFirstVisibleItem();
+ const int image_type = m_tree_ctrl->GetItemImage(selection);
+
+ if (image_type == ICON_DISC && first_visible_item != selection)
+ {
+ menu.Append(ID_EXTRACT_DIR, _("Extract Partition..."));
+ }
+ else if (image_type == ICON_FOLDER)
+ {
+ menu.Append(ID_EXTRACT_DIR, _("Extract Directory..."));
+ }
+ else if (image_type == ICON_FILE)
+ {
+ menu.Append(ID_EXTRACT_FILE, _("Extract File..."));
+ }
+
+ menu.Append(ID_EXTRACT_ALL, _("Extract All Files..."));
+
+ if (m_opened_iso->GetVolumeType() != DiscIO::Platform::WII_DISC ||
+ (image_type == ICON_DISC && first_visible_item != selection))
+ {
+ menu.AppendSeparator();
+ menu.Append(ID_EXTRACT_APPLOADER, _("Extract Apploader..."));
+ menu.Append(ID_EXTRACT_DOL, _("Extract DOL..."));
+ }
+
+ if (image_type == ICON_DISC && first_visible_item != selection)
+ {
+ menu.AppendSeparator();
+ menu.Append(ID_CHECK_INTEGRITY, _("Check Partition Integrity"));
+ }
+
+ PopupMenu(&menu);
+ event.Skip();
+}
+
+void FilesystemPanel::OnExtractFile(wxCommandEvent& WXUNUSED(event))
+{
+ const wxString selection_label = m_tree_ctrl->GetItemText(m_tree_ctrl->GetSelection());
+
+ const wxString output_file_path =
+ wxFileSelector(_("Extract File"), wxEmptyString, selection_label, wxEmptyString,
+ wxGetTranslation(wxALL_FILES), wxFD_SAVE, this);
+
+ if (output_file_path.empty() || selection_label.empty())
+ return;
+
+ ExtractSingleFile(output_file_path);
+}
+
+void FilesystemPanel::OnExtractDirectories(wxCommandEvent& event)
+{
+ const wxString selected_directory_label = m_tree_ctrl->GetItemText(m_tree_ctrl->GetSelection());
+ const wxString extract_path = wxDirSelector(_("Choose the folder to extract to"));
+
+ if (extract_path.empty() || selected_directory_label.empty())
+ return;
+
+ switch (event.GetId())
+ {
+ case ID_EXTRACT_ALL:
+ ExtractAllFiles(extract_path);
+ break;
+ case ID_EXTRACT_DIR:
+ ExtractSingleDirectory(extract_path);
+ break;
+ }
+}
+
+void FilesystemPanel::OnExtractHeaderData(wxCommandEvent& event)
+{
+ DiscIO::IFileSystem* file_system = nullptr;
+ const wxString path = wxDirSelector(_("Choose the folder to extract to"));
+
+ if (path.empty())
+ return;
+
+ if (m_opened_iso->GetVolumeType() == DiscIO::Platform::WII_DISC)
+ {
+ const auto* const selection_data = m_tree_ctrl->GetItemData(m_tree_ctrl->GetSelection());
+ const auto* const partition = static_cast(selection_data);
+
+ file_system = partition->filesystem.get();
+ }
+ else
+ {
+ file_system = m_filesystem.get();
+ }
+
+ bool ret = false;
+ if (event.GetId() == ID_EXTRACT_APPLOADER)
+ {
+ ret = file_system->ExportApploader(WxStrToStr(path));
+ }
+ else if (event.GetId() == ID_EXTRACT_DOL)
+ {
+ ret = file_system->ExportDOL(WxStrToStr(path));
+ }
+
+ if (!ret)
+ {
+ WxUtils::ShowErrorDialog(
+ wxString::Format(_("Failed to extract to %s!"), WxStrToStr(path).c_str()));
+ }
+}
+
+void FilesystemPanel::OnCheckPartitionIntegrity(wxCommandEvent& WXUNUSED(event))
+{
+ // Normally we can't enter this function if we aren't analyzing a Wii disc
+ // anyway, but let's still check to be sure.
+ if (m_opened_iso->GetVolumeType() != DiscIO::Platform::WII_DISC)
+ return;
+
+ wxProgressDialog dialog(_("Checking integrity..."), _("Working..."), 1000, this,
+ wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH);
+
+ const auto selection = m_tree_ctrl->GetSelection();
+
+ IntegrityCheckThread thread(*static_cast(m_tree_ctrl->GetItemData(selection)));
+ thread.Run();
+
+ while (thread.IsAlive())
+ {
+ dialog.Pulse();
+ wxThread::Sleep(50);
+ }
+
+ dialog.Destroy();
+
+ if (thread.Wait())
+ {
+ wxMessageBox(_("Integrity check completed. No errors have been found."),
+ _("Integrity check completed"), wxOK | wxICON_INFORMATION, this);
+ }
+ else
+ {
+ wxMessageBox(wxString::Format(_("Integrity check for %s failed. The disc image is most "
+ "likely corrupted or has been patched incorrectly."),
+ m_tree_ctrl->GetItemText(selection)),
+ _("Integrity Check Error"), wxOK | wxICON_ERROR, this);
+ }
+}
+
+void FilesystemPanel::ExtractAllFiles(const wxString& output_folder)
+{
+ switch (m_opened_iso->GetVolumeType())
+ {
+ case DiscIO::Platform::GAMECUBE_DISC:
+ ExtractAllFilesGC(output_folder);
+ break;
+
+ case DiscIO::Platform::WII_DISC:
+ ExtractAllFilesWii(output_folder);
+ break;
+
+ case DiscIO::Platform::ELF_DOL:
+ case DiscIO::Platform::NUMBER_OF_PLATFORMS:
+ case DiscIO::Platform::WII_WAD:
+ break;
+ }
+}
+
+void FilesystemPanel::ExtractAllFilesGC(const wxString& output_folder)
+{
+ ExtractDirectories("", WxStrToStr(output_folder), m_filesystem.get());
+}
+
+void FilesystemPanel::ExtractAllFilesWii(const wxString& output_folder)
+{
+ const wxTreeItemId root = m_tree_ctrl->GetRootItem();
+
+ wxTreeItemIdValue cookie;
+ wxTreeItemId item = m_tree_ctrl->GetFirstChild(root, cookie);
+
+ while (item.IsOk())
+ {
+ const auto* const partition = static_cast(m_tree_ctrl->GetItemData(item));
+ ExtractDirectories("", WxStrToStr(output_folder), partition->filesystem.get());
+ item = m_tree_ctrl->GetNextChild(root, cookie);
+ }
+}
+
+void FilesystemPanel::ExtractSingleFile(const wxString& output_file_path) const
+{
+ const auto selection_file_path = BuildFilePathFromSelection();
+
+ switch (m_opened_iso->GetVolumeType())
+ {
+ case DiscIO::Platform::GAMECUBE_DISC:
+ ExtractSingleFileGC(selection_file_path, output_file_path);
+ break;
+
+ case DiscIO::Platform::WII_DISC:
+ ExtractSingleFileWii(selection_file_path, output_file_path);
+ break;
+
+ case DiscIO::Platform::ELF_DOL:
+ case DiscIO::Platform::NUMBER_OF_PLATFORMS:
+ case DiscIO::Platform::WII_WAD:
+ break;
+ }
+}
+
+void FilesystemPanel::ExtractSingleFileGC(const wxString& file_path,
+ const wxString& output_file_path) const
+{
+ m_filesystem->ExportFile(WxStrToStr(file_path), WxStrToStr(output_file_path));
+}
+
+void FilesystemPanel::ExtractSingleFileWii(wxString file_path,
+ const wxString& output_file_path) const
+{
+ const size_t slash_index = file_path.find('/');
+ const wxString partition_label = file_path.substr(0, slash_index);
+ const auto* const partition = FindWiiPartition(m_tree_ctrl, partition_label);
+
+ // Remove "Partition x/"
+ file_path.erase(0, slash_index + 1);
+
+ partition->filesystem->ExportFile(WxStrToStr(file_path), WxStrToStr(output_file_path));
+}
+
+void FilesystemPanel::ExtractSingleDirectory(const wxString& output_folder)
+{
+ const wxString directory_path = BuildDirectoryPathFromSelection();
+
+ switch (m_opened_iso->GetVolumeType())
+ {
+ case DiscIO::Platform::GAMECUBE_DISC:
+ ExtractSingleDirectoryGC(directory_path, output_folder);
+ break;
+
+ case DiscIO::Platform::WII_DISC:
+ ExtractSingleDirectoryWii(directory_path, output_folder);
+ break;
+
+ case DiscIO::Platform::ELF_DOL:
+ case DiscIO::Platform::NUMBER_OF_PLATFORMS:
+ case DiscIO::Platform::WII_WAD:
+ break;
+ }
+}
+
+void FilesystemPanel::ExtractSingleDirectoryGC(const wxString& directory_path,
+ const wxString& output_folder)
+{
+ ExtractDirectories(WxStrToStr(directory_path), WxStrToStr(output_folder), m_filesystem.get());
+}
+
+void FilesystemPanel::ExtractSingleDirectoryWii(wxString directory_path,
+ const wxString& output_folder)
+{
+ const size_t slash_index = directory_path.find('/');
+ const wxString partition_label = directory_path.substr(0, slash_index);
+ const auto* const partition = FindWiiPartition(m_tree_ctrl, partition_label);
+
+ // Remove "Partition x/"
+ directory_path.erase(0, slash_index + 1);
+
+ ExtractDirectories(WxStrToStr(directory_path), WxStrToStr(output_folder),
+ partition->filesystem.get());
+}
+
+void FilesystemPanel::ExtractDirectories(const std::string& full_path,
+ const std::string& output_folder,
+ DiscIO::IFileSystem* filesystem)
+{
+ const std::vector& fst = filesystem->GetFileList();
+
+ u32 index = 0;
+ u32 size = 0;
+
+ // Extract all
+ if (full_path.empty())
+ {
+ size = static_cast(fst.size());
+
+ filesystem->ExportApploader(output_folder);
+ if (m_opened_iso->GetVolumeType() == DiscIO::Platform::GAMECUBE_DISC)
+ filesystem->ExportDOL(output_folder);
+ }
+ else
+ {
+ // Look for the dir we are going to extract
+ for (index = 0; index < fst.size(); ++index)
+ {
+ if (fst[index].m_FullPath == full_path)
+ {
+ INFO_LOG(DISCIO, "Found the directory at %u", index);
+ size = static_cast(fst[index].m_FileSize);
+ break;
+ }
+ }
+
+ INFO_LOG(DISCIO, "Directory found from %u to %u\nextracting to: %s", index, size,
+ output_folder.c_str());
+ }
+
+ const auto dialog_title = (index != 0) ? _("Extracting Directory") : _("Extracting All Files");
+ wxProgressDialog dialog(dialog_title, _("Extracting..."), static_cast(size - 1), this,
+ wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME |
+ wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH);
+
+ // Extraction
+ for (u32 i = index; i < size; i++)
+ {
+ dialog.SetTitle(wxString::Format(
+ "%s : %u%%", dialog_title.c_str(),
+ static_cast((static_cast(i - index) / static_cast(size - index)) *
+ 100)));
+
+ dialog.Update(i, wxString::Format(_("Extracting %s"), StrToWxStr(fst[i].m_FullPath)));
+
+ if (dialog.WasCancelled())
+ break;
+
+ if (fst[i].IsDirectory())
+ {
+ const std::string export_name =
+ StringFromFormat("%s/%s/", output_folder.c_str(), fst[i].m_FullPath.c_str());
+ INFO_LOG(DISCIO, "%s", export_name.c_str());
+
+ if (!File::Exists(export_name) && !File::CreateFullPath(export_name))
+ {
+ ERROR_LOG(DISCIO, "Could not create the path %s", export_name.c_str());
+ }
+ else
+ {
+ if (!File::IsDirectory(export_name))
+ ERROR_LOG(DISCIO, "%s already exists and is not a directory", export_name.c_str());
+
+ ERROR_LOG(DISCIO, "Folder %s already exists", export_name.c_str());
+ }
+ }
+ else
+ {
+ const std::string export_name =
+ StringFromFormat("%s/%s", output_folder.c_str(), fst[i].m_FullPath.c_str());
+ INFO_LOG(DISCIO, "%s", export_name.c_str());
+
+ if (!File::Exists(export_name) && !filesystem->ExportFile(fst[i].m_FullPath, export_name))
+ {
+ ERROR_LOG(DISCIO, "Could not export %s", export_name.c_str());
+ }
+ else
+ {
+ ERROR_LOG(DISCIO, "%s already exists", export_name.c_str());
+ }
+ }
+ }
+}
+
+wxString FilesystemPanel::BuildFilePathFromSelection() const
+{
+ wxString file_path = m_tree_ctrl->GetItemText(m_tree_ctrl->GetSelection());
+
+ const auto root_node = m_tree_ctrl->GetRootItem();
+ auto node = m_tree_ctrl->GetItemParent(m_tree_ctrl->GetSelection());
+
+ while (node != root_node)
+ {
+ file_path = m_tree_ctrl->GetItemText(node) + DIR_SEP_CHR + file_path;
+ node = m_tree_ctrl->GetItemParent(node);
+ }
+
+ return file_path;
+}
+
+wxString FilesystemPanel::BuildDirectoryPathFromSelection() const
+{
+ wxString directory_path = BuildFilePathFromSelection();
+ directory_path += DIR_SEP_CHR;
+ return directory_path;
+}
diff --git a/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.h b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.h
new file mode 100644
index 0000000000..7b40fb36c9
--- /dev/null
+++ b/Source/Core/DolphinWX/ISOProperties/FilesystemPanel.h
@@ -0,0 +1,76 @@
+// Copyright 2016 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+#include
+#include
+
+class GameListItem;
+class wxTreeCtrl;
+class wxTreeEvent;
+
+namespace DiscIO
+{
+class IFileSystem;
+class IVolume;
+}
+
+class FilesystemPanel final : public wxPanel
+{
+public:
+ explicit FilesystemPanel(wxWindow* parent, wxWindowID id, const GameListItem& item,
+ const std::unique_ptr& opened_iso);
+ ~FilesystemPanel();
+
+private:
+ enum
+ {
+ ID_EXTRACT_DIR = 20000,
+ ID_EXTRACT_ALL,
+ ID_EXTRACT_FILE,
+ ID_EXTRACT_APPLOADER,
+ ID_EXTRACT_DOL,
+ ID_CHECK_INTEGRITY,
+ };
+
+ void CreateGUI();
+ void BindEvents();
+
+ void PopulateFileSystemTree();
+ void PopulateFileSystemTreeGC();
+ void PopulateFileSystemTreeWii() const;
+
+ void OnRightClickTree(wxTreeEvent&);
+ void OnExtractFile(wxCommandEvent&);
+ void OnExtractDirectories(wxCommandEvent&);
+ void OnExtractHeaderData(wxCommandEvent&);
+ void OnCheckPartitionIntegrity(wxCommandEvent&);
+
+ void ExtractAllFiles(const wxString& output_folder);
+ void ExtractAllFilesGC(const wxString& output_folder);
+ void ExtractAllFilesWii(const wxString& output_folder);
+
+ void ExtractSingleFile(const wxString& output_file_path) const;
+ void ExtractSingleFileGC(const wxString& file_path, const wxString& output_file_path) const;
+ void ExtractSingleFileWii(wxString file_path, const wxString& output_file_path) const;
+
+ void ExtractSingleDirectory(const wxString& output_folder);
+ void ExtractSingleDirectoryGC(const wxString& directory_path, const wxString& output_folder);
+ void ExtractSingleDirectoryWii(wxString directory_path, const wxString& output_folder);
+
+ void ExtractDirectories(const std::string& full_path, const std::string& output_folder,
+ DiscIO::IFileSystem* filesystem);
+
+ wxString BuildFilePathFromSelection() const;
+ wxString BuildDirectoryPathFromSelection() const;
+
+ wxTreeCtrl* m_tree_ctrl;
+
+ const GameListItem& m_game_list_item;
+ const std::unique_ptr& m_opened_iso;
+
+ std::unique_ptr m_filesystem;
+};
diff --git a/Source/Core/DolphinWX/ISOProperties/ISOProperties.cpp b/Source/Core/DolphinWX/ISOProperties/ISOProperties.cpp
index 0b8c00e1b6..fbff389704 100644
--- a/Source/Core/DolphinWX/ISOProperties/ISOProperties.cpp
+++ b/Source/Core/DolphinWX/ISOProperties/ISOProperties.cpp
@@ -4,13 +4,11 @@
#include "DolphinWX/ISOProperties/ISOProperties.h"
-#include
#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -22,25 +20,18 @@
#include
#include
#include
-#include
#include
#include
-#include
-#include
#include
#include
-#include
#include
#include
-#include
#include
#include
#include
#include
#include
#include
-#include
-#include
#include
#include "Common/CommonPaths.h"
@@ -48,14 +39,12 @@
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Common/StringUtil.h"
-#include "Common/SysConf.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/GeckoCodeConfig.h"
#include "Core/PatchEngine.h"
#include "DiscIO/Blob.h"
#include "DiscIO/Enums.h"
-#include "DiscIO/Filesystem.h"
#include "DiscIO/Volume.h"
#include "DiscIO/VolumeCreator.h"
#include "DolphinWX/Cheats/ActionReplayCodesPanel.h"
@@ -65,6 +54,7 @@
#include "DolphinWX/Frame.h"
#include "DolphinWX/Globals.h"
#include "DolphinWX/ISOFile.h"
+#include "DolphinWX/ISOProperties/FilesystemPanel.h"
#include "DolphinWX/ISOProperties/InfoPanel.h"
#include "DolphinWX/Main.h"
#include "DolphinWX/PatchAddEdit.h"
@@ -197,13 +187,6 @@ EVT_LISTBOX(ID_PATCHES_LIST, CISOProperties::PatchListSelectionChanged)
EVT_BUTTON(ID_EDITPATCH, CISOProperties::PatchButtonClicked)
EVT_BUTTON(ID_ADDPATCH, CISOProperties::PatchButtonClicked)
EVT_BUTTON(ID_REMOVEPATCH, CISOProperties::PatchButtonClicked)
-EVT_TREE_ITEM_RIGHT_CLICK(ID_TREECTRL, CISOProperties::OnRightClickOnTree)
-EVT_MENU(IDM_EXTRACTFILE, CISOProperties::OnExtractFile)
-EVT_MENU(IDM_EXTRACTDIR, CISOProperties::OnExtractDir)
-EVT_MENU(IDM_EXTRACTALL, CISOProperties::OnExtractDir)
-EVT_MENU(IDM_EXTRACTAPPLOADER, CISOProperties::OnExtractDataFromHeader)
-EVT_MENU(IDM_EXTRACTDOL, CISOProperties::OnExtractDataFromHeader)
-EVT_MENU(IDM_CHECKINTEGRITY, CISOProperties::CheckPartitionIntegrity)
END_EVENT_TABLE()
CISOProperties::CISOProperties(const GameListItem& game_list_item, wxWindow* parent, wxWindowID id,
@@ -227,58 +210,6 @@ CISOProperties::CISOProperties(const GameListItem& game_list_item, wxWindow* par
CreateGUIControls();
LoadGameConfig();
- // Filesystem browser/dumper
- // TODO : Should we add a way to browse the wad file ?
- if (m_open_iso->GetVolumeType() != DiscIO::Platform::WII_WAD)
- {
- if (m_open_iso->GetVolumeType() == DiscIO::Platform::WII_DISC)
- {
- int partition_count = 0;
- for (int group = 0; group < 4; group++)
- {
- for (u32 i = 0; i < 0xFFFFFFFF;
- i++) // yes, technically there can be OVER NINE THOUSAND partitions...
- {
- std::unique_ptr volume(
- DiscIO::CreateVolumeFromFilename(OpenGameListItem.GetFileName(), group, i));
- if (volume != nullptr)
- {
- std::unique_ptr file_system(
- DiscIO::CreateFileSystem(volume.get()));
- if (file_system != nullptr)
- {
- WiiPartition* const partition =
- new WiiPartition(std::move(volume), std::move(file_system));
-
- wxTreeItemId PartitionRoot = m_Treectrl->AppendItem(
- RootId, wxString::Format(_("Partition %i"), partition_count), 0, 0);
-
- m_Treectrl->SetItemData(PartitionRoot, partition);
- CreateDirectoryTree(PartitionRoot, partition->FileSystem->GetFileList());
-
- if (partition_count == 1)
- m_Treectrl->Expand(PartitionRoot);
-
- partition_count++;
- }
- }
- else
- {
- break;
- }
- }
- }
- }
- else
- {
- m_filesystem = DiscIO::CreateFileSystem(m_open_iso.get());
- if (m_filesystem)
- CreateDirectoryTree(RootId, m_filesystem->GetFileList());
- }
-
- m_Treectrl->Expand(RootId);
- }
-
wxTheApp->Bind(DOLPHIN_EVT_LOCAL_INI_CHANGED, &CISOProperties::OnLocalIniModified, this);
}
@@ -286,57 +217,6 @@ CISOProperties::~CISOProperties()
{
}
-size_t CISOProperties::CreateDirectoryTree(wxTreeItemId& parent,
- const std::vector& fileInfos)
-{
- if (fileInfos.empty())
- return 0;
- else
- return CreateDirectoryTree(parent, fileInfos, 1, fileInfos.at(0).m_FileSize);
-}
-
-size_t CISOProperties::CreateDirectoryTree(wxTreeItemId& parent,
- const std::vector& fileInfos,
- const size_t _FirstIndex, const size_t _LastIndex)
-{
- size_t CurrentIndex = _FirstIndex;
-
- while (CurrentIndex < _LastIndex)
- {
- const DiscIO::SFileInfo rFileInfo = fileInfos[CurrentIndex];
- std::string filePath = rFileInfo.m_FullPath;
-
- // Trim the trailing '/' if it exists.
- if (filePath[filePath.length() - 1] == DIR_SEP_CHR)
- {
- filePath.pop_back();
- }
-
- // Cut off the path up to the actual filename or folder.
- // Say we have "/music/stream/stream1.strm", the result will be "stream1.strm".
- size_t dirSepIndex = filePath.find_last_of(DIR_SEP_CHR);
- if (dirSepIndex != std::string::npos)
- {
- filePath = filePath.substr(dirSepIndex + 1);
- }
-
- // check next index
- if (rFileInfo.IsDirectory())
- {
- wxTreeItemId item = m_Treectrl->AppendItem(parent, StrToWxStr(filePath), 1, 1);
- CurrentIndex =
- CreateDirectoryTree(item, fileInfos, CurrentIndex + 1, (size_t)rFileInfo.m_FileSize);
- }
- else
- {
- m_Treectrl->AppendItem(parent, StrToWxStr(filePath), 2, 2);
- CurrentIndex++;
- }
- }
-
- return CurrentIndex;
-}
-
long CISOProperties::GetElementStyle(const char* section, const char* key)
{
// Disable 3rd state if default gameini overrides the setting
@@ -554,29 +434,9 @@ void CISOProperties::CreateGUIControls()
if (m_open_iso->GetVolumeType() != DiscIO::Platform::WII_WAD)
{
- wxPanel* const filesystem_panel = new wxPanel(m_Notebook, ID_FILESYSTEM);
- m_Notebook->AddPage(filesystem_panel, _("Filesystem"));
-
- // Filesystem icons
- wxSize icon_size = FromDIP(wxSize(16, 16));
- wxImageList* const m_iconList = new wxImageList(icon_size.GetWidth(), icon_size.GetHeight());
- static const std::array s_icon_names{
- {"isoproperties_disc", "isoproperties_folder", "isoproperties_file"}};
- for (const auto& name : s_icon_names)
- m_iconList->Add(
- WxUtils::LoadScaledResourceBitmap(name, this, icon_size, wxDefaultSize,
- WxUtils::LSI_SCALE_DOWN | WxUtils::LSI_ALIGN_CENTER));
-
- // Filesystem tree
- m_Treectrl = new wxTreeCtrl(filesystem_panel, ID_TREECTRL);
- m_Treectrl->AssignImageList(m_iconList);
- RootId = m_Treectrl->AddRoot(_("Disc"), 0, 0, nullptr);
-
- wxBoxSizer* sTreePage = new wxBoxSizer(wxVERTICAL);
- sTreePage->AddSpacer(space5);
- sTreePage->Add(m_Treectrl, 1, wxEXPAND | wxLEFT | wxRIGHT, space5);
- sTreePage->AddSpacer(space5);
- filesystem_panel->SetSizer(sTreePage);
+ m_Notebook->AddPage(
+ new FilesystemPanel(m_Notebook, ID_FILESYSTEM, OpenGameListItem, m_open_iso),
+ _("Filesystem"));
}
wxStdDialogButtonSizer* sButtons = CreateStdDialogButtonSizer(wxOK | wxNO_DEFAULT);
@@ -626,313 +486,6 @@ void CISOProperties::OnCloseClick(wxCommandEvent& WXUNUSED(event))
Close();
}
-void CISOProperties::OnRightClickOnTree(wxTreeEvent& event)
-{
- m_Treectrl->SelectItem(event.GetItem());
-
- wxMenu popupMenu;
-
- if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 0 &&
- m_Treectrl->GetFirstVisibleItem() != m_Treectrl->GetSelection())
- {
- popupMenu.Append(IDM_EXTRACTDIR, _("Extract Partition..."));
- }
- else if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 1)
- {
- popupMenu.Append(IDM_EXTRACTDIR, _("Extract Directory..."));
- }
- else if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 2)
- {
- popupMenu.Append(IDM_EXTRACTFILE, _("Extract File..."));
- }
-
- popupMenu.Append(IDM_EXTRACTALL, _("Extract All Files..."));
-
- if (m_open_iso->GetVolumeType() != DiscIO::Platform::WII_DISC ||
- (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 0 &&
- m_Treectrl->GetFirstVisibleItem() != m_Treectrl->GetSelection()))
- {
- popupMenu.AppendSeparator();
- popupMenu.Append(IDM_EXTRACTAPPLOADER, _("Extract Apploader..."));
- popupMenu.Append(IDM_EXTRACTDOL, _("Extract DOL..."));
- }
-
- if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 0 &&
- m_Treectrl->GetFirstVisibleItem() != m_Treectrl->GetSelection())
- {
- popupMenu.AppendSeparator();
- popupMenu.Append(IDM_CHECKINTEGRITY, _("Check Partition Integrity"));
- }
-
- PopupMenu(&popupMenu);
-
- event.Skip();
-}
-
-void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED(event))
-{
- wxString File = m_Treectrl->GetItemText(m_Treectrl->GetSelection());
-
- wxString Path = wxFileSelector(_("Export File"), wxEmptyString, File, wxEmptyString,
- wxGetTranslation(wxALL_FILES), wxFD_SAVE, this);
-
- if (!Path || !File)
- return;
-
- while (m_Treectrl->GetItemParent(m_Treectrl->GetSelection()) != m_Treectrl->GetRootItem())
- {
- wxString temp = m_Treectrl->GetItemText(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
- File = temp + DIR_SEP_CHR + File;
-
- m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
- }
-
- if (m_open_iso->GetVolumeType() == DiscIO::Platform::WII_DISC)
- {
- const wxTreeItemId tree_selection = m_Treectrl->GetSelection();
- WiiPartition* partition =
- reinterpret_cast(m_Treectrl->GetItemData(tree_selection));
- File.erase(0, m_Treectrl->GetItemText(tree_selection).length() + 1); // Remove "Partition x/"
-
- partition->FileSystem->ExportFile(WxStrToStr(File), WxStrToStr(Path));
- }
- else
- {
- m_filesystem->ExportFile(WxStrToStr(File), WxStrToStr(Path));
- }
-}
-
-void CISOProperties::ExportDir(const std::string& _rFullPath, const std::string& _rExportFolder,
- const WiiPartition* partition)
-{
- bool is_wii = m_open_iso->GetVolumeType() == DiscIO::Platform::WII_DISC;
- DiscIO::IFileSystem* const fs = is_wii ? partition->FileSystem.get() : m_filesystem.get();
-
- const std::vector& fst = fs->GetFileList();
-
- u32 index = 0;
- u32 size = 0;
-
- // Extract all
- if (_rFullPath.empty())
- {
- index = 0;
- size = (u32)fst.size();
-
- fs->ExportApploader(_rExportFolder);
- if (m_open_iso->GetVolumeType() != DiscIO::Platform::WII_DISC)
- fs->ExportDOL(_rExportFolder);
- }
- else
- {
- // Look for the dir we are going to extract
- for (index = 0; index != fst.size(); ++index)
- {
- if (fst[index].m_FullPath == _rFullPath)
- {
- INFO_LOG(DISCIO, "Found the directory at %u", index);
- size = (u32)fst[index].m_FileSize;
- break;
- }
- }
-
- INFO_LOG(DISCIO, "Directory found from %u to %u\nextracting to: %s", index, size,
- _rExportFolder.c_str());
- }
-
- wxString dialogTitle = (index != 0) ? _("Extracting Directory") : _("Extracting All Files");
- wxProgressDialog dialog(dialogTitle, _("Extracting..."), size - 1, this,
- wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT | wxPD_ELAPSED_TIME |
- wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | wxPD_SMOOTH);
-
- // Extraction
- for (u32 i = index; i < size; i++)
- {
- dialog.SetTitle(wxString::Format("%s : %d%%", dialogTitle.c_str(),
- (u32)(((float)(i - index) / (float)(size - index)) * 100)));
-
- dialog.Update(i, wxString::Format(_("Extracting %s"), StrToWxStr(fst[i].m_FullPath)));
-
- if (dialog.WasCancelled())
- break;
-
- if (fst[i].IsDirectory())
- {
- const std::string exportName =
- StringFromFormat("%s/%s/", _rExportFolder.c_str(), fst[i].m_FullPath.c_str());
- INFO_LOG(DISCIO, "%s", exportName.c_str());
-
- if (!File::Exists(exportName) && !File::CreateFullPath(exportName))
- {
- ERROR_LOG(DISCIO, "Could not create the path %s", exportName.c_str());
- }
- else
- {
- if (!File::IsDirectory(exportName))
- ERROR_LOG(DISCIO, "%s already exists and is not a directory", exportName.c_str());
-
- ERROR_LOG(DISCIO, "Folder %s already exists", exportName.c_str());
- }
- }
- else
- {
- const std::string exportName =
- StringFromFormat("%s/%s", _rExportFolder.c_str(), fst[i].m_FullPath.c_str());
- INFO_LOG(DISCIO, "%s", exportName.c_str());
-
- if (!File::Exists(exportName) && !fs->ExportFile(fst[i].m_FullPath, exportName))
- {
- ERROR_LOG(DISCIO, "Could not export %s", exportName.c_str());
- }
- else
- {
- ERROR_LOG(DISCIO, "%s already exists", exportName.c_str());
- }
- }
- }
-}
-
-void CISOProperties::OnExtractDir(wxCommandEvent& event)
-{
- wxString Directory = m_Treectrl->GetItemText(m_Treectrl->GetSelection());
- wxString Path = wxDirSelector(_("Choose the folder to extract to"));
-
- if (!Path || !Directory)
- return;
-
- if (event.GetId() == IDM_EXTRACTALL)
- {
- if (m_open_iso->GetVolumeType() == DiscIO::Platform::WII_DISC)
- {
- wxTreeItemIdValue cookie;
- wxTreeItemId root = m_Treectrl->GetRootItem();
- wxTreeItemId item = m_Treectrl->GetFirstChild(root, cookie);
- while (item.IsOk())
- {
- ExportDir("", WxStrToStr(Path),
- reinterpret_cast(m_Treectrl->GetItemData(item)));
- item = m_Treectrl->GetNextChild(root, cookie);
- }
- }
- else
- {
- ExportDir("", WxStrToStr(Path));
- }
-
- return;
- }
-
- while (m_Treectrl->GetItemParent(m_Treectrl->GetSelection()) != m_Treectrl->GetRootItem())
- {
- wxString temp = m_Treectrl->GetItemText(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
- Directory = temp + DIR_SEP_CHR + Directory;
-
- m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
- }
-
- Directory += DIR_SEP_CHR;
-
- if (m_open_iso->GetVolumeType() == DiscIO::Platform::WII_DISC)
- {
- const wxTreeItemId tree_selection = m_Treectrl->GetSelection();
- WiiPartition* partition =
- reinterpret_cast(m_Treectrl->GetItemData(tree_selection));
- Directory.erase(0,
- m_Treectrl->GetItemText(tree_selection).length() + 1); // Remove "Partition x/"
-
- ExportDir(WxStrToStr(Directory), WxStrToStr(Path), partition);
- }
- else
- {
- ExportDir(WxStrToStr(Directory), WxStrToStr(Path));
- }
-}
-
-void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event)
-{
- DiscIO::IFileSystem* FS = nullptr;
- wxString Path = wxDirSelector(_("Choose the folder to extract to"));
-
- if (Path.empty())
- return;
-
- if (m_open_iso->GetVolumeType() == DiscIO::Platform::WII_DISC)
- {
- WiiPartition* partition =
- reinterpret_cast(m_Treectrl->GetItemData(m_Treectrl->GetSelection()));
- FS = partition->FileSystem.get();
- }
- else
- {
- FS = m_filesystem.get();
- }
-
- bool ret = false;
- if (event.GetId() == IDM_EXTRACTAPPLOADER)
- {
- ret = FS->ExportApploader(WxStrToStr(Path));
- }
- else if (event.GetId() == IDM_EXTRACTDOL)
- {
- ret = FS->ExportDOL(WxStrToStr(Path));
- }
-
- if (!ret)
- WxUtils::ShowErrorDialog(
- wxString::Format(_("Failed to extract to %s!"), WxStrToStr(Path).c_str()));
-}
-
-class IntegrityCheckThread : public wxThread
-{
-public:
- IntegrityCheckThread(const WiiPartition& Partition)
- : wxThread(wxTHREAD_JOINABLE), m_Partition(Partition)
- {
- Create();
- }
-
- ExitCode Entry() override { return (ExitCode)m_Partition.Partition->CheckIntegrity(); }
-private:
- const WiiPartition& m_Partition;
-};
-
-void CISOProperties::CheckPartitionIntegrity(wxCommandEvent& event)
-{
- // Normally we can't enter this function if we aren't analyzing a Wii disc
- // anyway, but let's still check to be sure.
- if (m_open_iso->GetVolumeType() != DiscIO::Platform::WII_DISC)
- return;
-
- wxProgressDialog dialog(_("Checking integrity..."), _("Working..."), 1000, this,
- wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH);
-
- WiiPartition* partition =
- reinterpret_cast(m_Treectrl->GetItemData(m_Treectrl->GetSelection()));
- IntegrityCheckThread thread(*partition);
- thread.Run();
-
- while (thread.IsAlive())
- {
- dialog.Pulse();
- wxThread::Sleep(50);
- }
-
- dialog.Destroy();
-
- if (!thread.Wait())
- {
- wxMessageBox(wxString::Format(_("Integrity check for %s failed. The disc image is most "
- "likely corrupted or has been patched incorrectly."),
- m_Treectrl->GetItemText(m_Treectrl->GetSelection())),
- _("Integrity Check Error"), wxOK | wxICON_ERROR, this);
- }
- else
- {
- wxMessageBox(_("Integrity check completed. No errors have been found."),
- _("Integrity check completed"), wxOK | wxICON_INFORMATION, this);
- }
-}
-
void CISOProperties::OnEmustateChanged(wxCommandEvent& event)
{
EmuIssues->Enable(event.GetSelection() != 0);
diff --git a/Source/Core/DolphinWX/ISOProperties/ISOProperties.h b/Source/Core/DolphinWX/ISOProperties/ISOProperties.h
index 10f1cab115..0d244cea88 100644
--- a/Source/Core/DolphinWX/ISOProperties/ISOProperties.h
+++ b/Source/Core/DolphinWX/ISOProperties/ISOProperties.h
@@ -14,11 +14,11 @@
#include
#include "Common/IniFile.h"
-#include "DiscIO/Filesystem.h"
-#include "DiscIO/Volume.h"
#include "DolphinWX/ISOFile.h"
#include "DolphinWX/PatchAddEdit.h"
+class ActionReplayCodesPanel;
+class CheatWarningMessage;
class DolphinSlider;
class wxButton;
class wxCheckBox;
@@ -27,32 +27,16 @@ class wxChoice;
class wxSpinCtrl;
class wxStaticBitmap;
class wxTextCtrl;
-class wxTreeCtrl;
namespace DiscIO
{
-enum class Language;
+class IVolume;
}
+
namespace Gecko
{
class CodeConfigPanel;
}
-class ActionReplayCodesPanel;
-class CheatWarningMessage;
-class GameListItem;
-
-class WiiPartition final : public wxTreeItemData
-{
-public:
- WiiPartition(std::unique_ptr partition,
- std::unique_ptr file_system)
- : Partition(std::move(partition)), FileSystem(std::move(file_system))
- {
- }
-
- std::unique_ptr Partition;
- std::unique_ptr FileSystem;
-};
struct PHackData
{
@@ -77,7 +61,6 @@ private:
DECLARE_EVENT_TABLE();
std::unique_ptr m_open_iso;
- std::unique_ptr m_filesystem;
std::vector onFrame;
PHackData m_PHack_Data;
@@ -104,9 +87,6 @@ private:
wxButton* EditPatch;
wxButton* RemovePatch;
- wxTreeCtrl* m_Treectrl;
- wxTreeItemId RootId;
-
ActionReplayCodesPanel* m_ar_code_panel;
Gecko::CodeConfigPanel* m_geckocode_panel;
@@ -115,9 +95,7 @@ private:
enum
{
- ID_TREECTRL = 1000,
-
- ID_NOTEBOOK,
+ ID_NOTEBOOK = 1000,
ID_GAMECONFIG,
ID_PATCH_PAGE,
ID_ARCODE_PAGE,
@@ -147,13 +125,6 @@ private:
ID_DEPTHPERCENTAGE,
ID_CONVERGENCE,
ID_MONODEPTH,
-
- IDM_EXTRACTDIR,
- IDM_EXTRACTALL,
- IDM_EXTRACTFILE,
- IDM_EXTRACTAPPLOADER,
- IDM_EXTRACTDOL,
- IDM_CHECKINTEGRITY,
};
void LaunchExternalEditor(const std::string& filename, bool wait_until_closed);
@@ -165,23 +136,12 @@ private:
void OnShowDefaultConfig(wxCommandEvent& event);
void PatchListSelectionChanged(wxCommandEvent& event);
void PatchButtonClicked(wxCommandEvent& event);
- void OnRightClickOnTree(wxTreeEvent& event);
- void OnExtractFile(wxCommandEvent& event);
- void OnExtractDir(wxCommandEvent& event);
- void OnExtractDataFromHeader(wxCommandEvent& event);
- void CheckPartitionIntegrity(wxCommandEvent& event);
void OnEmustateChanged(wxCommandEvent& event);
void OnCheatCodeToggled(wxCommandEvent& event);
void OnChangeTitle(wxCommandEvent& event);
const GameListItem OpenGameListItem;
- size_t CreateDirectoryTree(wxTreeItemId& parent, const std::vector& fileInfos);
- size_t CreateDirectoryTree(wxTreeItemId& parent, const std::vector& fileInfos,
- const size_t _FirstIndex, const size_t _LastIndex);
- void ExportDir(const std::string& _rFullPath, const std::string& _rExportFilename,
- const WiiPartition* partition = nullptr);
-
IniFile GameIniDefault;
IniFile GameIniLocal;
std::string GameIniFileLocal;