initial work on support custom fs mount points
This commit is contained in:
@@ -83,6 +83,7 @@ struct FileAssocEntry {
|
|||||||
std::vector<std::string> ext; // list of ext
|
std::vector<std::string> ext; // list of ext
|
||||||
std::vector<std::string> database; // list of systems
|
std::vector<std::string> database; // list of systems
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LastFile {
|
struct LastFile {
|
||||||
fs::FsPath name;
|
fs::FsPath name;
|
||||||
u64 index;
|
u64 index;
|
||||||
@@ -90,6 +91,15 @@ struct LastFile {
|
|||||||
u64 entries_count;
|
u64 entries_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FsDirCollection {
|
||||||
|
fs::FsPath path;
|
||||||
|
fs::FsPath parent_name;
|
||||||
|
std::vector<FsDirectoryEntry> files;
|
||||||
|
std::vector<FsDirectoryEntry> dirs;
|
||||||
|
};
|
||||||
|
|
||||||
|
using FsDirCollections = std::vector<FsDirCollection>;
|
||||||
|
|
||||||
struct Menu final : MenuBase {
|
struct Menu final : MenuBase {
|
||||||
Menu(const std::vector<NroEntry>& nro_entries);
|
Menu(const std::vector<NroEntry>& nro_entries);
|
||||||
~Menu();
|
~Menu();
|
||||||
@@ -205,10 +215,14 @@ private:
|
|||||||
void OnRenameCallback();
|
void OnRenameCallback();
|
||||||
auto CheckIfUpdateFolder() -> Result;
|
auto CheckIfUpdateFolder() -> Result;
|
||||||
|
|
||||||
|
auto get_collection(const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollection& out, bool inc_file, bool inc_dir, bool inc_size) -> Result;
|
||||||
|
auto get_collections(const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollections& out) -> Result;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr inline const char* INI_SECTION = "filebrowser";
|
static constexpr inline const char* INI_SECTION = "filebrowser";
|
||||||
|
|
||||||
const std::vector<NroEntry>& m_nro_entries;
|
const std::vector<NroEntry>& m_nro_entries;
|
||||||
|
std::unique_ptr<fs::FsNative> m_fs;
|
||||||
fs::FsPath m_path;
|
fs::FsPath m_path;
|
||||||
std::vector<FileEntry> m_entries;
|
std::vector<FileEntry> m_entries;
|
||||||
std::vector<u32> m_entries_index; // files not including hidden
|
std::vector<u32> m_entries_index; // files not including hidden
|
||||||
|
|||||||
@@ -36,20 +36,11 @@
|
|||||||
namespace sphaira::ui::menu::filebrowser {
|
namespace sphaira::ui::menu::filebrowser {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct FsDirCollection {
|
|
||||||
fs::FsPath path;
|
|
||||||
fs::FsPath parent_name;
|
|
||||||
std::vector<FsDirectoryEntry> files;
|
|
||||||
std::vector<FsDirectoryEntry> dirs;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ExtDbEntry {
|
struct ExtDbEntry {
|
||||||
std::string_view db_name;
|
std::string_view db_name;
|
||||||
std::span<const std::string_view> ext;
|
std::span<const std::string_view> ext;
|
||||||
};
|
};
|
||||||
|
|
||||||
using FsDirCollections = std::vector<FsDirCollection>;
|
|
||||||
|
|
||||||
constexpr std::string_view AUDIO_EXTENSIONS[] = {
|
constexpr std::string_view AUDIO_EXTENSIONS[] = {
|
||||||
"mp3", "ogg", "flac", "wav", "aac" "ac3", "aif", "asf", "bfwav",
|
"mp3", "ogg", "flac", "wav", "aac" "ac3", "aif", "asf", "bfwav",
|
||||||
"bfsar", "bfstm",
|
"bfsar", "bfstm",
|
||||||
@@ -173,7 +164,7 @@ auto GetRomDatabaseFromPath(std::string_view path) -> int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension, int db_idx, const NroEntry& nro) {
|
auto GetRomIcon(fs::FsNative* fs, ProgressBox* pbox, std::string filename, std::string extension, int db_idx, const NroEntry& nro) {
|
||||||
// if no db entries, use nro icon
|
// if no db entries, use nro icon
|
||||||
if (db_idx < 0) {
|
if (db_idx < 0) {
|
||||||
log_write("using nro image\n");
|
log_write("using nro image\n");
|
||||||
@@ -225,7 +216,7 @@ auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension,
|
|||||||
if (!pbox->ShouldExit()) {
|
if (!pbox->ShouldExit()) {
|
||||||
pbox->NewTransfer("Trying to load "_i18n + ra_thumbnail_path);
|
pbox->NewTransfer("Trying to load "_i18n + ra_thumbnail_path);
|
||||||
std::vector<u8> image_file;
|
std::vector<u8> image_file;
|
||||||
if (R_SUCCEEDED(fs::FsNativeSd().read_entire_file(ra_thumbnail_path.c_str(), image_file))) {
|
if (R_SUCCEEDED(fs->read_entire_file(ra_thumbnail_path.c_str(), image_file))) {
|
||||||
return image_file;
|
return image_file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -248,63 +239,6 @@ auto GetRomIcon(ProgressBox* pbox, std::string filename, std::string extension,
|
|||||||
return nro_get_icon(nro.path, nro.icon_size, nro.icon_offset);
|
return nro_get_icon(nro.path, nro.icon_size, nro.icon_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_collection(fs::FsNative& fs, const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollection& out, bool inc_file, bool inc_dir, bool inc_size) -> Result {
|
|
||||||
out.path = path;
|
|
||||||
out.parent_name = parent_name;
|
|
||||||
|
|
||||||
const auto fetch = [&path, &fs](std::vector<FsDirectoryEntry>& out, u32 flags) -> Result {
|
|
||||||
FsDir d;
|
|
||||||
R_TRY(fs.OpenDirectory(path, flags, &d));
|
|
||||||
ON_SCOPE_EXIT(fs.DirClose(&d));
|
|
||||||
|
|
||||||
s64 count;
|
|
||||||
R_TRY(fs.DirGetEntryCount(&d, &count));
|
|
||||||
|
|
||||||
out.resize(count);
|
|
||||||
return fs.DirRead(&d, &count, out.size(), out.data());
|
|
||||||
};
|
|
||||||
|
|
||||||
if (inc_file) {
|
|
||||||
u32 flags = FsDirOpenMode_ReadFiles;
|
|
||||||
if (!inc_size) {
|
|
||||||
flags |= FsDirOpenMode_NoFileSize;
|
|
||||||
}
|
|
||||||
R_TRY(fetch(out.files, flags));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inc_dir) {
|
|
||||||
R_TRY(fetch(out.dirs, FsDirOpenMode_ReadDirs));
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto get_collections(fs::FsNative& fs, const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollections& out) -> Result {
|
|
||||||
// get a list of all the files / dirs
|
|
||||||
FsDirCollection collection;
|
|
||||||
R_TRY(get_collection(fs, path, parent_name, collection, true, true, false));
|
|
||||||
log_write("got collection: %s parent_name: %s files: %zu dirs: %zu\n", path, parent_name, collection.files.size(), collection.dirs.size());
|
|
||||||
out.emplace_back(collection);
|
|
||||||
|
|
||||||
// for (size_t i = 0; i < collection.dirs.size(); i++) {
|
|
||||||
for (const auto&p : collection.dirs) {
|
|
||||||
// use heap as to not explode the stack
|
|
||||||
const auto new_path = std::make_unique<fs::FsPath>(Menu::GetNewPath(path, p.name));
|
|
||||||
const auto new_parent_name = std::make_unique<fs::FsPath>(Menu::GetNewPath(parent_name, p.name));
|
|
||||||
log_write("trying to get nested collection: %s parent_name: %s\n", *new_path, *new_parent_name);
|
|
||||||
R_TRY(get_collections(fs, *new_path, *new_parent_name, out));
|
|
||||||
}
|
|
||||||
|
|
||||||
R_SUCCEED();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto get_collections(const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollections& out) -> Result {
|
|
||||||
fs::FsNativeSd fs;
|
|
||||||
R_TRY(fs.GetFsOpenResult());
|
|
||||||
|
|
||||||
return get_collections(fs, path, parent_name, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i18n}, m_nro_entries{nro_entries} {
|
Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i18n}, m_nro_entries{nro_entries} {
|
||||||
@@ -516,9 +450,9 @@ Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i1
|
|||||||
|
|
||||||
Result rc;
|
Result rc;
|
||||||
if (entry.IsFile()) {
|
if (entry.IsFile()) {
|
||||||
rc = fs::FsNativeSd().RenameFile(src_path, dst_path);
|
rc = m_fs->RenameFile(src_path, dst_path);
|
||||||
} else {
|
} else {
|
||||||
rc = fs::FsNativeSd().RenameDirectory(src_path, dst_path);
|
rc = m_fs->RenameDirectory(src_path, dst_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
@@ -546,9 +480,8 @@ Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i1
|
|||||||
full_path = fs::AppendPath(m_path, out);
|
full_path = fs::AppendPath(m_path, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::FsNativeSd fs;
|
m_fs->CreateDirectoryRecursivelyWithPath(full_path);
|
||||||
fs.CreateDirectoryRecursivelyWithPath(full_path);
|
if (R_SUCCEEDED(m_fs->CreateFile(full_path, 0, 0))) {
|
||||||
if (R_SUCCEEDED(fs.CreateFile(full_path, 0, 0))) {
|
|
||||||
log_write("created file: %s\n", full_path);
|
log_write("created file: %s\n", full_path);
|
||||||
Scan(m_path);
|
Scan(m_path);
|
||||||
} else {
|
} else {
|
||||||
@@ -567,7 +500,7 @@ Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i1
|
|||||||
full_path = fs::AppendPath(m_path, out);
|
full_path = fs::AppendPath(m_path, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_SUCCEEDED(fs::FsNativeSd().CreateDirectoryRecursively(full_path))) {
|
if (R_SUCCEEDED(m_fs->CreateDirectoryRecursively(full_path))) {
|
||||||
log_write("created dir: %s\n", full_path);
|
log_write("created dir: %s\n", full_path);
|
||||||
Scan(m_path);
|
Scan(m_path);
|
||||||
} else {
|
} else {
|
||||||
@@ -604,6 +537,7 @@ Menu::Menu(const std::vector<NroEntry>& nro_entries) : MenuBase{"FileBrowser"_i1
|
|||||||
}})
|
}})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
m_fs = std::make_unique<fs::FsNativeSd>();
|
||||||
fs::FsPath buf;
|
fs::FsPath buf;
|
||||||
ini_gets("paths", "last_path", "/", buf, sizeof(buf), App::CONFIG_PATH);
|
ini_gets("paths", "last_path", "/", buf, sizeof(buf), App::CONFIG_PATH);
|
||||||
m_path = buf;
|
m_path = buf;
|
||||||
@@ -661,9 +595,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
if (e.IsDir()) {
|
if (e.IsDir()) {
|
||||||
if (e.file_count == -1 && e.dir_count == -1) {
|
if (e.file_count == -1 && e.dir_count == -1) {
|
||||||
const auto full_path = GetNewPath(e);
|
const auto full_path = GetNewPath(e);
|
||||||
fs::FsNativeSd fs;
|
m_fs->DirGetEntryCount(full_path, FsDirOpenMode_ReadFiles | FsDirOpenMode_NoFileSize, &e.file_count);
|
||||||
fs.DirGetEntryCount(full_path, FsDirOpenMode_ReadFiles | FsDirOpenMode_NoFileSize, &e.file_count);
|
m_fs->DirGetEntryCount(full_path, FsDirOpenMode_ReadDirs | FsDirOpenMode_NoFileSize, &e.dir_count);
|
||||||
fs.DirGetEntryCount(full_path, FsDirOpenMode_ReadDirs | FsDirOpenMode_NoFileSize, &e.dir_count);
|
|
||||||
}
|
}
|
||||||
} else if (!e.checked_extension) {
|
} else if (!e.checked_extension) {
|
||||||
e.checked_extension = true;
|
e.checked_extension = true;
|
||||||
@@ -719,12 +652,8 @@ void Menu::Draw(NVGcontext* vg, Theme* theme) {
|
|||||||
gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) + 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP, theme->elements[text_id].colour, "%zd dirs"_i18n.c_str(), e.dir_count);
|
gfx::drawTextArgs(vg, x + w - text_xoffset, y + (h / 2.f) + 3, 16.f, NVG_ALIGN_RIGHT | NVG_ALIGN_TOP, theme->elements[text_id].colour, "%zd dirs"_i18n.c_str(), e.dir_count);
|
||||||
} else {
|
} else {
|
||||||
if (!e.time_stamp.is_valid) {
|
if (!e.time_stamp.is_valid) {
|
||||||
fs::FsNativeSd fs;
|
|
||||||
const auto path = GetNewPath(e);
|
const auto path = GetNewPath(e);
|
||||||
|
m_fs->GetFileTimeStampRaw(path, &e.time_stamp);
|
||||||
if (R_SUCCEEDED(fs.GetFsOpenResult())) {
|
|
||||||
fs.GetFileTimeStampRaw(path, &e.time_stamp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const auto t = (time_t)(e.time_stamp.modified);
|
const auto t = (time_t)(e.time_stamp.modified);
|
||||||
struct tm tm{};
|
struct tm tm{};
|
||||||
@@ -847,7 +776,7 @@ void Menu::InstallForwarder() {
|
|||||||
config.name = nro.nacp.lang[0].name + std::string{" | "} + file_name;
|
config.name = nro.nacp.lang[0].name + std::string{" | "} + file_name;
|
||||||
// config.name = file_name;
|
// config.name = file_name;
|
||||||
config.nacp = nro.nacp;
|
config.nacp = nro.nacp;
|
||||||
config.icon = GetRomIcon(pbox, file_name, extension, db_idx, nro);
|
config.icon = GetRomIcon(m_fs.get(), pbox, file_name, extension, db_idx, nro);
|
||||||
|
|
||||||
return R_SUCCEEDED(App::Install(pbox, config));
|
return R_SUCCEEDED(App::Install(pbox, config));
|
||||||
}));
|
}));
|
||||||
@@ -877,26 +806,17 @@ auto Menu::Scan(const fs::FsPath& new_path, bool is_walk_up) -> Result {
|
|||||||
ResetSelection();
|
ResetSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fs::FsNativeSd fs;
|
|
||||||
// R_TRY(fs.GetFsOpenResult());
|
|
||||||
|
|
||||||
// FsDirCollection collection;
|
|
||||||
// R_TRY(get_collection(fs, new_path, "", collection, true, true, false));
|
|
||||||
|
|
||||||
fs::FsNativeSd fs;
|
|
||||||
R_TRY(fs.GetFsOpenResult());
|
|
||||||
|
|
||||||
FsDir d;
|
FsDir d;
|
||||||
R_TRY(fsFsOpenDirectory(&fs.m_fs, new_path, FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles | FsDirOpenMode_NoFileSize, &d));
|
R_TRY(m_fs->OpenDirectory(new_path, FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles | FsDirOpenMode_NoFileSize, &d));
|
||||||
ON_SCOPE_EXIT(fsDirClose(&d));
|
ON_SCOPE_EXIT(fsDirClose(&d));
|
||||||
|
|
||||||
s64 count;
|
s64 count;
|
||||||
R_TRY(fs.DirGetEntryCount(&d, &count));
|
R_TRY(m_fs->DirGetEntryCount(&d, &count));
|
||||||
|
|
||||||
// we won't run out of memory here (tm)
|
// we won't run out of memory here (tm)
|
||||||
std::vector<FsDirectoryEntry> dir_entries(count);
|
std::vector<FsDirectoryEntry> dir_entries(count);
|
||||||
|
|
||||||
R_TRY(fs.DirRead(&d, &count, dir_entries.size(), dir_entries.data()));
|
R_TRY(m_fs->DirRead(&d, &count, dir_entries.size(), dir_entries.data()));
|
||||||
|
|
||||||
// size may of changed
|
// size may of changed
|
||||||
dir_entries.resize(count);
|
dir_entries.resize(count);
|
||||||
@@ -996,7 +916,6 @@ void Menu::LoadAssocEntriesPath(const fs::FsPath& path) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ON_SCOPE_EXIT(closedir(dir));
|
ON_SCOPE_EXIT(closedir(dir));
|
||||||
fs::FsNativeSd fs;
|
|
||||||
|
|
||||||
while (auto d = readdir(dir)) {
|
while (auto d = readdir(dir)) {
|
||||||
if (d->d_name[0] == '.') {
|
if (d->d_name[0] == '.') {
|
||||||
@@ -1052,7 +971,7 @@ void Menu::LoadAssocEntriesPath(const fs::FsPath& path) {
|
|||||||
// if path isn't empty, check if the file exists
|
// if path isn't empty, check if the file exists
|
||||||
bool file_exists{};
|
bool file_exists{};
|
||||||
if (!assoc.path.empty()) {
|
if (!assoc.path.empty()) {
|
||||||
file_exists = fs.FileExists(assoc.path);
|
file_exists = m_fs->FileExists(assoc.path);
|
||||||
} else {
|
} else {
|
||||||
const auto nro_name = assoc.name + ".nro";
|
const auto nro_name = assoc.name + ".nro";
|
||||||
for (const auto& nro : m_nro_entries) {
|
for (const auto& nro : m_nro_entries) {
|
||||||
@@ -1207,19 +1126,18 @@ void Menu::OnDeleteCallback() {
|
|||||||
|
|
||||||
// check if we only have 1 file / folder
|
// check if we only have 1 file / folder
|
||||||
if (m_selected_files.size() == 1) {
|
if (m_selected_files.size() == 1) {
|
||||||
fs::FsNativeSd fs;
|
|
||||||
const auto& entry = m_selected_files[0];
|
const auto& entry = m_selected_files[0];
|
||||||
const auto full_path = GetNewPath(m_selected_path, entry.name);
|
const auto full_path = GetNewPath(m_selected_path, entry.name);
|
||||||
|
|
||||||
if (entry.IsDir()) {
|
if (entry.IsDir()) {
|
||||||
s64 count{};
|
s64 count{};
|
||||||
fs.DirGetEntryCount(full_path, FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles | FsDirOpenMode_NoFileSize, &count);
|
m_fs->DirGetEntryCount(full_path, FsDirOpenMode_ReadDirs | FsDirOpenMode_ReadFiles | FsDirOpenMode_NoFileSize, &count);
|
||||||
if (!count) {
|
if (!count) {
|
||||||
fs.DeleteDirectory(full_path);
|
m_fs->DeleteDirectory(full_path);
|
||||||
use_progress_box = false;
|
use_progress_box = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fs.DeleteFile(full_path);
|
m_fs->DeleteFile(full_path);
|
||||||
use_progress_box = false;
|
use_progress_box = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1230,7 +1148,6 @@ void Menu::OnDeleteCallback() {
|
|||||||
log_write("did delete\n");
|
log_write("did delete\n");
|
||||||
} else {
|
} else {
|
||||||
App::Push(std::make_shared<ProgressBox>("Deleting"_i18n, [this](auto pbox){
|
App::Push(std::make_shared<ProgressBox>("Deleting"_i18n, [this](auto pbox){
|
||||||
fs::FsNativeSd fs;
|
|
||||||
FsDirCollections collections;
|
FsDirCollections collections;
|
||||||
|
|
||||||
// build list of dirs / files
|
// build list of dirs / files
|
||||||
@@ -1263,10 +1180,10 @@ void Menu::OnDeleteCallback() {
|
|||||||
pbox->NewTransfer("Deleting "_i18n + full_path);
|
pbox->NewTransfer("Deleting "_i18n + full_path);
|
||||||
if (p.type == FsDirEntryType_Dir) {
|
if (p.type == FsDirEntryType_Dir) {
|
||||||
log_write("deleting dir: %s\n", full_path);
|
log_write("deleting dir: %s\n", full_path);
|
||||||
fs.DeleteDirectory(full_path);
|
m_fs->DeleteDirectory(full_path);
|
||||||
} else {
|
} else {
|
||||||
log_write("deleting file: %s\n", full_path);
|
log_write("deleting file: %s\n", full_path);
|
||||||
fs.DeleteFile(full_path);
|
m_fs->DeleteFile(full_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -1291,10 +1208,10 @@ void Menu::OnDeleteCallback() {
|
|||||||
|
|
||||||
if (p.IsDir()) {
|
if (p.IsDir()) {
|
||||||
log_write("deleting dir: %s\n", full_path);
|
log_write("deleting dir: %s\n", full_path);
|
||||||
fs.DeleteDirectory(full_path);
|
m_fs->DeleteDirectory(full_path);
|
||||||
} else {
|
} else {
|
||||||
log_write("deleting file: %s\n", full_path);
|
log_write("deleting file: %s\n", full_path);
|
||||||
fs.DeleteFile(full_path);
|
m_fs->DeleteFile(full_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1312,14 +1229,13 @@ void Menu::OnPasteCallback() {
|
|||||||
|
|
||||||
// check if we only have 1 file / folder and is cut (rename)
|
// check if we only have 1 file / folder and is cut (rename)
|
||||||
if (m_selected_files.size() == 1 && m_selected_type == SelectedType::Cut) {
|
if (m_selected_files.size() == 1 && m_selected_type == SelectedType::Cut) {
|
||||||
fs::FsNativeSd fs;
|
|
||||||
const auto& entry = m_selected_files[0];
|
const auto& entry = m_selected_files[0];
|
||||||
const auto full_path = GetNewPath(m_selected_path, entry.name);
|
const auto full_path = GetNewPath(m_selected_path, entry.name);
|
||||||
|
|
||||||
if (entry.IsDir()) {
|
if (entry.IsDir()) {
|
||||||
fs.RenameDirectory(full_path, GetNewPath(entry));
|
m_fs->RenameDirectory(full_path, GetNewPath(entry));
|
||||||
} else {
|
} else {
|
||||||
fs.RenameFile(full_path, GetNewPath(entry));
|
m_fs->RenameFile(full_path, GetNewPath(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
ResetSelection();
|
ResetSelection();
|
||||||
@@ -1327,7 +1243,6 @@ void Menu::OnPasteCallback() {
|
|||||||
log_write("did paste\n");
|
log_write("did paste\n");
|
||||||
} else {
|
} else {
|
||||||
App::Push(std::make_shared<ProgressBox>("Pasting"_i18n, [this](auto pbox){
|
App::Push(std::make_shared<ProgressBox>("Pasting"_i18n, [this](auto pbox){
|
||||||
fs::FsNativeSd fs;
|
|
||||||
|
|
||||||
if (m_selected_type == SelectedType::Cut) {
|
if (m_selected_type == SelectedType::Cut) {
|
||||||
for (const auto& p : m_selected_files) {
|
for (const auto& p : m_selected_files) {
|
||||||
@@ -1342,9 +1257,9 @@ void Menu::OnPasteCallback() {
|
|||||||
pbox->NewTransfer("Pasting "_i18n + src_path);
|
pbox->NewTransfer("Pasting "_i18n + src_path);
|
||||||
|
|
||||||
if (p.IsDir()) {
|
if (p.IsDir()) {
|
||||||
fs.RenameDirectory(src_path, dst_path);
|
m_fs->RenameDirectory(src_path, dst_path);
|
||||||
} else {
|
} else {
|
||||||
fs.RenameFile(src_path, dst_path);
|
m_fs->RenameFile(src_path, dst_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1378,7 +1293,7 @@ void Menu::OnPasteCallback() {
|
|||||||
|
|
||||||
if (p.IsDir()) {
|
if (p.IsDir()) {
|
||||||
pbox->NewTransfer("Creating "_i18n + dst_path);
|
pbox->NewTransfer("Creating "_i18n + dst_path);
|
||||||
fs.CreateDirectory(dst_path);
|
m_fs->CreateDirectory(dst_path);
|
||||||
} else {
|
} else {
|
||||||
pbox->NewTransfer("Copying "_i18n + src_path);
|
pbox->NewTransfer("Copying "_i18n + src_path);
|
||||||
R_TRY_RESULT(pbox->CopyFile(src_path, dst_path), false);
|
R_TRY_RESULT(pbox->CopyFile(src_path, dst_path), false);
|
||||||
@@ -1400,7 +1315,7 @@ void Menu::OnPasteCallback() {
|
|||||||
|
|
||||||
log_write("creating: %s to %s\n", src_path, dst_path);
|
log_write("creating: %s to %s\n", src_path, dst_path);
|
||||||
pbox->NewTransfer("Creating "_i18n + dst_path);
|
pbox->NewTransfer("Creating "_i18n + dst_path);
|
||||||
fs.CreateDirectory(dst_path);
|
m_fs->CreateDirectory(dst_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& p : c.files) {
|
for (const auto& p : c.files) {
|
||||||
@@ -1438,13 +1353,10 @@ auto Menu::CheckIfUpdateFolder() -> Result {
|
|||||||
return FsError_FileNotFound;
|
return FsError_FileNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::FsNativeSd fs;
|
|
||||||
R_TRY(fs.GetFsOpenResult());
|
|
||||||
|
|
||||||
// check that we have daybreak installed
|
// check that we have daybreak installed
|
||||||
if (!m_daybreak_path.has_value()) {
|
if (!m_daybreak_path.has_value()) {
|
||||||
auto daybreak_path = DAYBREAK_PATH;
|
auto daybreak_path = DAYBREAK_PATH;
|
||||||
if (!fs.FileExists(DAYBREAK_PATH)) {
|
if (!m_fs->FileExists(DAYBREAK_PATH)) {
|
||||||
if (auto e = nro_find(m_nro_entries, "Daybreak", "Atmosphere-NX", {}); e.has_value()) {
|
if (auto e = nro_find(m_nro_entries, "Daybreak", "Atmosphere-NX", {}); e.has_value()) {
|
||||||
daybreak_path = e.value().path;
|
daybreak_path = e.value().path;
|
||||||
} else {
|
} else {
|
||||||
@@ -1458,11 +1370,11 @@ auto Menu::CheckIfUpdateFolder() -> Result {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FsDir d;
|
FsDir d;
|
||||||
R_TRY(fs.OpenDirectory(m_path, FsDirOpenMode_ReadDirs, &d));
|
R_TRY(m_fs->OpenDirectory(m_path, FsDirOpenMode_ReadDirs, &d));
|
||||||
ON_SCOPE_EXIT(fs.DirClose(&d));
|
ON_SCOPE_EXIT(m_fs->DirClose(&d));
|
||||||
|
|
||||||
s64 count;
|
s64 count;
|
||||||
R_TRY(fs.DirGetEntryCount(&d, &count));
|
R_TRY(m_fs->DirGetEntryCount(&d, &count));
|
||||||
|
|
||||||
// check that we are at the bottom level
|
// check that we are at the bottom level
|
||||||
R_UNLESS(count == 0, 0x1);
|
R_UNLESS(count == 0, 0x1);
|
||||||
@@ -1479,6 +1391,56 @@ auto Menu::CheckIfUpdateFolder() -> Result {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Menu::get_collection(const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollection& out, bool inc_file, bool inc_dir, bool inc_size) -> Result {
|
||||||
|
out.path = path;
|
||||||
|
out.parent_name = parent_name;
|
||||||
|
|
||||||
|
const auto fetch = [this, &path](std::vector<FsDirectoryEntry>& out, u32 flags) -> Result {
|
||||||
|
FsDir d;
|
||||||
|
R_TRY(m_fs->OpenDirectory(path, flags, &d));
|
||||||
|
ON_SCOPE_EXIT(m_fs->DirClose(&d));
|
||||||
|
|
||||||
|
s64 count;
|
||||||
|
R_TRY(m_fs->DirGetEntryCount(&d, &count));
|
||||||
|
|
||||||
|
out.resize(count);
|
||||||
|
return m_fs->DirRead(&d, &count, out.size(), out.data());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (inc_file) {
|
||||||
|
u32 flags = FsDirOpenMode_ReadFiles;
|
||||||
|
if (!inc_size) {
|
||||||
|
flags |= FsDirOpenMode_NoFileSize;
|
||||||
|
}
|
||||||
|
R_TRY(fetch(out.files, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inc_dir) {
|
||||||
|
R_TRY(fetch(out.dirs, FsDirOpenMode_ReadDirs));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Menu::get_collections(const fs::FsPath& path, const fs::FsPath& parent_name, FsDirCollections& out) -> Result {
|
||||||
|
// get a list of all the files / dirs
|
||||||
|
FsDirCollection collection;
|
||||||
|
R_TRY(get_collection(path, parent_name, collection, true, true, false));
|
||||||
|
log_write("got collection: %s parent_name: %s files: %zu dirs: %zu\n", path, parent_name, collection.files.size(), collection.dirs.size());
|
||||||
|
out.emplace_back(collection);
|
||||||
|
|
||||||
|
// for (size_t i = 0; i < collection.dirs.size(); i++) {
|
||||||
|
for (const auto&p : collection.dirs) {
|
||||||
|
// use heap as to not explode the stack
|
||||||
|
const auto new_path = std::make_unique<fs::FsPath>(Menu::GetNewPath(path, p.name));
|
||||||
|
const auto new_parent_name = std::make_unique<fs::FsPath>(Menu::GetNewPath(parent_name, p.name));
|
||||||
|
log_write("trying to get nested collection: %s parent_name: %s\n", *new_path, *new_parent_name);
|
||||||
|
R_TRY(get_collections(*new_path, *new_parent_name, out));
|
||||||
|
}
|
||||||
|
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sphaira::ui::menu::filebrowser
|
} // namespace sphaira::ui::menu::filebrowser
|
||||||
|
|
||||||
// options
|
// options
|
||||||
|
|||||||
Reference in New Issue
Block a user