diff --git a/source/fs/fsutil.c b/source/fs/fsutil.c index 717405d..f498c32 100644 --- a/source/fs/fsutil.c +++ b/source/fs/fsutil.c @@ -782,6 +782,60 @@ bool DirCreate(const char* cpath, const char* dirname) { return (fa_mkdir(npath) == FR_OK); } +bool DirInfoWorker(char* fpath, bool virtual, u64* tsize, u32* tdirs, u32* tfiles) { + char* fname = fpath + strnlen(fpath, 256 - 1); + bool ret = true; + if (virtual) { + VirtualDir vdir; + VirtualFile vfile; + if (!GetVirtualDir(&vdir, fpath)) return false; // get dir reader object + while (ReadVirtualDir(&vfile, &vdir)) { + if (vfile.flags & VFLAG_DIR) { + (*tdirs)++; + *(fname++) = '/'; + GetVirtualFilename(fname, &vfile, (256 - 1) - (fname - fpath)); + if (!DirInfoWorker(fpath, virtual, tsize, tdirs, tfiles)) ret = false; + *(--fname) = '\0'; + } else { + *tsize += vfile.size; + (*tfiles)++; + } + } + } else { + DIR pdir; + FILINFO fno; + if (fa_opendir(&pdir, fpath) != FR_OK) return false; // get dir reader object + while (f_readdir(&pdir, &fno) == FR_OK) { + if ((strncmp(fno.fname, ".", 2) == 0) || (strncmp(fno.fname, "..", 3) == 0)) + continue; // filter out virtual entries + if (fno.fname[0] == 0) break; // end of dir + if (fno.fattrib & AM_DIR) { + (*tdirs)++; + *(fname++) = '/'; + strncpy(fname, fno.fname, (256 - 1) - (fname - fpath)); + if (!DirInfoWorker(fpath, virtual, tsize, tdirs, tfiles)) ret = false; + *(--fname) = '\0'; + } else { + *tsize += fno.fsize; + (*tfiles)++; + } + } + f_closedir(&pdir); + } + + return ret; +} + +bool DirInfo(const char* path, u64* tsize, u32* tdirs, u32* tfiles) { + bool virtual = (DriveType(path) & DRV_VIRTUAL); + char fpath[256]; + strncpy(fpath, path, 255); + *tsize = *tdirs = *tfiles = 0; + ShowString("Analyzing dir, please wait..."); + bool res = DirInfoWorker(fpath, virtual, tsize, tdirs, tfiles); + return res; +} + void CreateScreenshot() { const u8 bmp_header[54] = { 0x42, 0x4D, 0x36, 0xCA, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, diff --git a/source/fs/fsutil.h b/source/fs/fsutil.h index c4393eb..7c94b60 100644 --- a/source/fs/fsutil.h +++ b/source/fs/fsutil.h @@ -57,5 +57,8 @@ bool PathRename(const char* path, const char* newname); /** Create a new directory in cpath **/ bool DirCreate(const char* cpath, const char* dirname); +/** Get # of files, subdirs and total size for directory **/ +bool DirInfo(const char* path, u64* tsize, u32* tdirs, u32* tfiles); + /** Create a screenshot of the current framebuffer **/ void CreateScreenshot(); diff --git a/source/godmode.c b/source/godmode.c index 147769c..5b19272 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -1110,17 +1110,31 @@ u32 GodMode() { // basic navigation commands if ((pad_state & BUTTON_A) && (curr_entry->type != T_FILE) && (curr_entry->type != T_DOTDOT)) { // for dirs if (switched && !(DriveType(curr_entry->path) & DRV_SEARCH)) { // search directory - char searchstr[256]; - char namestr[20+1]; - snprintf(searchstr, 256, "*"); - TruncateString(namestr, curr_entry->name, 20, 8); - if (ShowStringPrompt(searchstr, 256, "Search %s?\nEnter search below.", namestr)) { - SetFSSearch(searchstr, curr_entry->path); - snprintf(current_path, 256, "Z:"); - GetDirContents(current_dir, current_path); - if (current_dir->n_entries) ShowPrompt(false, "Found %lu results.", current_dir->n_entries - 1); - cursor = 1; - scroll = 0; + const char* optionstr[2] = { "Search files & subdirs", "Directory info" }; // search files only? + char namestr[32+1]; + TruncateString(namestr, (*current_path) ? curr_entry->path : curr_entry->name, 32, 8); + u32 user_select = ShowSelectPrompt(2, optionstr, "%s", namestr); + if (user_select == 1) { + char searchstr[256]; + snprintf(searchstr, 256, "*"); + TruncateString(namestr, curr_entry->name, 20, 8); + if (ShowStringPrompt(searchstr, 256, "Search %s?\nEnter search below.", namestr)) { + SetFSSearch(searchstr, curr_entry->path); + snprintf(current_path, 256, "Z:"); + GetDirContents(current_dir, current_path); + if (current_dir->n_entries) ShowPrompt(false, "Found %lu results.", current_dir->n_entries - 1); + cursor = 1; + scroll = 0; + } + } else if (user_select == 2) { + u64 tsize = 0; + u32 tdirs = 0; + u32 tfiles = 0; + if (DirInfo(curr_entry->path, &tsize, &tdirs, &tfiles)) { + char bytestr[32]; + FormatBytes(bytestr, tsize); + ShowPrompt(false, "%s\n%lu files & %lu subdirs\n%s total", namestr, tfiles, tdirs, bytestr); + } else ShowPrompt(false, "Analyze dir: failed!"); } } else { // one level up u32 user_select = 1;