diff --git a/inc/file.h b/inc/file.h index 5f04491..8840938 100644 --- a/inc/file.h +++ b/inc/file.h @@ -61,11 +61,8 @@ namespace fs //Dumps all titles for current user void dumpAllUserSaves(); - //returns file properties as C++ string - std::string getFileProps(const std::string& _path); - - //Recursively retrieves info about dir _path - void getDirProps(const std::string& _path, uint32_t& dirCount, uint32_t& fileCount, uint64_t& totalSize); + void getShowFileProps(const std::string& _path); + void getShowDirProps(const std::string& _path); bool fileExists(const std::string& _path); //Returns file size @@ -164,6 +161,15 @@ namespace fs uint16_t index; } svCreateArgs; + typedef struct + { + std::string path; + bool origin = false; + unsigned dirCount = 0; + unsigned fileCount = 0; + uint64_t totalSize = 0; + } dirCountArgs; + copyArgs *copyArgsCreate(const std::string& from, const std::string& to, const std::string& dev, zipFile z, unzFile unz, bool _cleanup); void copyArgsDestroy(copyArgs *c); diff --git a/inc/fsthrd.h b/inc/fsthrd.h index fd0fd6e..fd13a20 100644 --- a/inc/fsthrd.h +++ b/inc/fsthrd.h @@ -17,4 +17,5 @@ namespace fs void closeZip_t(void *a); void backupUserSaves_t(void *a); + void getShowDirProps_t(void *a); } diff --git a/inc/ui/miscui.h b/inc/ui/miscui.h index c85be79..a2ee990 100644 --- a/inc/ui/miscui.h +++ b/inc/ui/miscui.h @@ -162,6 +162,7 @@ namespace ui //General use ui::confirmArgs *confirmArgsCreate(bool _hold, funcPtr _func, void *_funcArgs, bool _cleanup, const char *fmt, ...); void confirm(void *a); + void showMessage(const char *fmt, ...); bool confirmTransfer(const std::string& f, const std::string& t); bool confirmDelete(const std::string& p); void drawBoundBox(SDL_Texture *target, int x, int y, int w, int h, uint8_t clrSh); diff --git a/inc/util.h b/inc/util.h index bdf38b8..6dadf86 100644 --- a/inc/util.h +++ b/inc/util.h @@ -19,22 +19,22 @@ namespace util typedef enum { - cpu204MHz = 204000000, - cpu306MHz = 306000000, - cpu408MHz = 408000000, - cpu510MHz = 510000000, - cpu612MHz = 612000000, - cpu714MHz = 714000000, - cpu816MHz = 816000000, - cpu918MHz = 918000000, - cpu1020MHz = 1020000000, //Default - cpu1122MHz = 1122000000, - cpu1224MHz = 1224000000, - cpu1326MHz = 1326000000, - cpu1428MHz = 1428000000, - cpu1581MHz = 1581000000, - cpu1683MHz = 1683000000, - cpu1785MHz = 1785000000 + CPU_SPEED_204MHz = 204000000, + CPU_SPEED_306MHz = 306000000, + CPU_SPEED_408MHz = 408000000, + CPU_SPEED_510MHz = 510000000, + CPU_SPEED_612MHz = 612000000, + CPU_SPEED_714MHz = 714000000, + CPU_SPEED_816MHz = 816000000, + CPU_SPEED_918MHz = 918000000, + CPU_SPEED_1020MHz = 1020000000, //Default + CPU_SPEED_1122MHz = 1122000000, + CPU_SPEED_1224MHz = 1224000000, + CPU_SPEED_1326MHz = 1326000000, + CPU_SPEED_1428MHz = 1428000000, + CPU_SPEED_1581MHz = 1581000000, + CPU_SPEED_1683MHz = 1683000000, + CPU_SPEED_1785MHz = 1785000000 } cpuSpds; //Returns string with date S+ time @@ -106,6 +106,8 @@ namespace util return fs::getWorkDir() + data::getTitleSafeNameByTID(tid) + "/"; } + std::string getSizeString(const uint64_t& _size); + inline void createTitleDirectoryByTID(const uint64_t& tid) { std::string makePath = fs::getWorkDir() + data::getTitleSafeNameByTID(tid); diff --git a/src/data.cpp b/src/data.cpp index c4cc9af..238761e 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -307,7 +307,7 @@ void data::sortUserTitles() void data::init() { if(cfg::config["ovrClk"]) - util::setCPU(util::cpu1224MHz); + util::setCPU(util::CPU_SPEED_1224MHz); uint64_t lang; setGetSystemLanguage(&lang); @@ -325,7 +325,7 @@ void data::exit() SDL_DestroyTexture(iconMask); if(cfg::config["ovrClk"]) - util::setCPU(util::cpu1020MHz); + util::setCPU(util::CPU_SPEED_1020MHz); } void data::setUserIndex(unsigned _sUser) diff --git a/src/file.cpp b/src/file.cpp index 269ac2c..fff200b 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -359,7 +359,7 @@ void fs::copyDirToZip(const std::string& from, zipFile to) { if(cfg::config["ovrClk"]) { - util::setCPU(util::cpu1785MHz); + util::setCPU(util::CPU_SPEED_1785MHz); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0)); } copyArgs *send = copyArgsCreate(from, "", "", to, NULL, true); @@ -370,7 +370,7 @@ void fs::copyZipToDir(unzFile unz, const std::string& to, const std::string& dev { if(cfg::config["ovrClk"]) { - util::setCPU(util::cpu1785MHz); + util::setCPU(util::CPU_SPEED_1785MHz); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0)); } copyArgs *send = copyArgsCreate("", to, dev, NULL, unz, true); @@ -470,61 +470,18 @@ void fs::dumpAllUserSaves() ui::newThread(fs::backupUserSaves_t, send, _fileDrawFunc); } -std::string fs::getFileProps(const std::string& _path) +void fs::getShowFileProps(const std::string& _path) { - std::string ret = ""; - - FILE *get = fopen(_path.c_str(), "rb"); - if(get != NULL) - { - //Size - fseek(get, 0, SEEK_END); - unsigned fileSize = ftell(get); - fseek(get, 0, SEEK_SET); - - fclose(get); - - //Probably add more later - - char tmp[256]; - std::sprintf(tmp, "Path: #%s#\nSize: %u", _path.c_str(), fileSize); - - ret = tmp; - } - return ret; + size_t size = fs::fsize(_path); + ui::showMessage(ui::getUICString("fileModeFileProperties", 0), _path.c_str(), util::getSizeString(size).c_str()); } -void fs::getDirProps(const std::string& _path, uint32_t& dirCount, uint32_t& fileCount, uint64_t& totalSize) +void fs::getShowDirProps(const std::string& _path) { - fs::dirList list(_path); - - for(unsigned i = 0; i < list.getCount(); i++) - { - if(list.isDir(i)) - { - ++dirCount; - std::string newPath = _path + list.getItem(i) + "/"; - uint32_t dirAdd = 0, fileAdd = 0; - uint64_t sizeAdd = 0; - - getDirProps(newPath, dirAdd, fileAdd, sizeAdd); - dirCount += dirAdd; - fileCount += fileAdd; - totalSize += sizeAdd; - } - else - { - ++fileCount; - std::string filePath = _path + list.getItem(i); - - FILE *gSize = fopen(filePath.c_str(), "rb"); - fseek(gSize, 0, SEEK_END); - size_t fSize = ftell(gSize); - fclose(gSize); - - totalSize += fSize; - } - } + fs::dirCountArgs *send = new fs::dirCountArgs; + send->path = _path; + send->origin = true; + ui::newThread(fs::getShowDirProps_t, send, NULL); } bool fs::fileExists(const std::string& path) @@ -562,6 +519,12 @@ bool fs::isDir(const std::string& _path) void fs::createNewBackup(void *a) { + if(!fs::dirNotEmpty("sv:/")) + { + ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popSaveIsEmpty", 0)); + return; + } + uint64_t held = ui::padKeysHeld(); data::user *u = data::getCurrentUser(); @@ -609,7 +572,7 @@ void fs::createNewBackup(void *a) } else { - mkdir(path.c_str(), 777); + fs::mkDir(path); path += "/"; fs::copyDirToDir("sv:/", path); } @@ -629,15 +592,16 @@ void fs::overwriteBackup(void *a) unsigned ind = m->getSelected() - 1;;//Skip new std::string itemName = d->getItem(ind); - if(d->isDir(ind)) + bool saveHasFiles = fs::dirNotEmpty("sv:/"); + if(d->isDir(ind) && saveHasFiles) { std::string toPath = util::generatePathByTID(cd->tid) + itemName + "/"; //Delete and recreate fs::delDir(toPath); - mkdir(toPath.c_str(), 777); + fs::mkDir(toPath); fs::copyDirToDir("sv:/", toPath); } - else if(!d->isDir(ind) && d->getItemExt(ind) == "zip") + else if(!d->isDir(ind) && d->getItemExt(ind) == "zip" && saveHasFiles) { std::string toPath = util::generatePathByTID(cd->tid) + itemName; fs::delfile(toPath); @@ -661,16 +625,17 @@ void fs::restoreBackup(void *a) std::string itemName = d->getItem(ind); if((cd->saveInfo.save_data_type != FsSaveDataType_System || cfg::config["sysSaveWrite"]) && m->getSelected() > 0) { - if(cfg::config["autoBack"] && cfg::config["zip"]) + bool saveHasFiles = fs::dirNotEmpty("sv:/"); + if(cfg::config["autoBack"] && cfg::config["zip"] && saveHasFiles) { std::string autoZip = util::generatePathByTID(cd->tid) + "/AUTO " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip"; zipFile zip = zipOpen64(autoZip.c_str(), 0); fs::copyDirToZip("sv:/", zip); } - else if(cfg::config["autoBack"]) + else if(cfg::config["autoBack"] && saveHasFiles) { std::string autoFolder = util::generatePathByTID(cd->tid) + "/AUTO - " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/"; - mkdir(autoFolder.substr(0, autoFolder.length() - 1).c_str(), 777); + fs::mkDir(autoFolder.substr(0, autoFolder.length() - 1)); fs::copyDirToDir("sv:/", autoFolder); } @@ -683,7 +648,7 @@ void fs::restoreBackup(void *a) fs::copyDirToDirCommit(fromPath, "sv:/", "sv"); } else - ui::showPopMessage(POP_FRAME_DEFAULT, "Folder is empty!"); + ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popFolderIsEmpty", 0)); } else if(!d->isDir(ind) && d->getItemExt(ind) == "zip") { @@ -695,7 +660,7 @@ void fs::restoreBackup(void *a) fs::copyZipToDir(unz, "sv:/", "sv"); } else - ui::showPopMessage(POP_FRAME_DEFAULT, "ZIP is empty!"); + ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popZipIsEmpty", 0)); } else { diff --git a/src/fsthrd.cpp b/src/fsthrd.cpp index bd04232..b0a9ba2 100644 --- a/src/fsthrd.cpp +++ b/src/fsthrd.cpp @@ -460,7 +460,7 @@ void fs::copyDirToZip_t(void *a) if(args->cleanup) { if(cfg::config["ovrClk"]) - util::setCPU(util::cpu1224MHz); + util::setCPU(util::CPU_SPEED_1224MHz); ui::newThread(closeZip_t, args->z, NULL); delete args->prog; delete args; @@ -549,7 +549,7 @@ void fs::copyZipToDir_t(void *a) unzClose(args->unz); copyArgsDestroy(args); if(cfg::config["ovrClk"]) - util::setCPU(util::cpu1224MHz); + util::setCPU(util::CPU_SPEED_1224MHz); } delete[] buff; t->finished = true; @@ -580,7 +580,7 @@ void fs::backupUserSaves_t(void *a) if(cfg::config["ovrClk"] && cfg::config["zip"]) { - util::setCPU(util::cpu1785MHz); + util::setCPU(util::CPU_SPEED_1785MHz); ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popCPUBoostEnabled", 0)); } @@ -634,7 +634,48 @@ void fs::backupUserSaves_t(void *a) } delete c; if(cfg::config["ovrClk"] && cfg::config["zip"]) - util::setCPU(util::cpu1224MHz); + util::setCPU(util::CPU_SPEED_1224MHz); t->finished = true; } + +void fs::getShowDirProps_t(void *a) +{ + threadInfo *t = (threadInfo *)a; + fs::dirCountArgs *d = (fs::dirCountArgs *)t->argPtr; + + t->status->setStatus(ui::getUICString("threadStatusGetDirProps", 0)); + + fs::dirList *dir = new fs::dirList(d->path); + for(unsigned i = 0; i < dir->getCount(); i++) + { + if(dir->isDir(i)) + { + d->dirCount++; + threadInfo *fakeThread = new threadInfo; + dirCountArgs *tmpArgs = new dirCountArgs; + tmpArgs->path = d->path + dir->getItem(i) + "/"; + tmpArgs->origin = false; + fakeThread->status = t->status; + fakeThread->argPtr = tmpArgs; + getShowDirProps_t(fakeThread); + d->dirCount += tmpArgs->dirCount; + d->fileCount += tmpArgs->fileCount; + d->totalSize += tmpArgs->totalSize; + delete fakeThread; + delete tmpArgs; + } + else + { + std::string filePath = d->path + dir->getItem(i); + d->fileCount++; + d->totalSize += fs::fsize(filePath); + } + } + if(d->origin) + { + ui::showMessage(ui::getUICString("fileModeFolderProperties", 0), d->path.c_str(), d->dirCount, d->fileCount, util::getSizeString(d->totalSize).c_str()); + delete d; + } + t->finished = true; +} diff --git a/src/ui.cpp b/src/ui.cpp index b7cd7cb..1088d37 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -140,6 +140,7 @@ void ui::init() util::replaceButtonsInString(ui::strings[std::make_pair("helpSettings", 0)]); util::replaceButtonsInString(ui::strings[std::make_pair("dialogYes", 0)]); util::replaceButtonsInString(ui::strings[std::make_pair("dialogNo", 0)]); + util::replaceButtonsInString(ui::strings[std::make_pair("dialogOK", 0)]); //setup pad padConfigureInput(1, HidNpadStyleSet_NpadStandard); diff --git a/src/ui/fm.cpp b/src/ui/fm.cpp index 369b729..19770e6 100644 --- a/src/ui/fm.cpp +++ b/src/ui/fm.cpp @@ -365,6 +365,26 @@ static void _copyMenuMkDir(void *a) refreshMenu(&fake); } +static void _copyMenuGetProps(void *a) +{ + menuFuncArgs *ma = (menuFuncArgs *)a; + fs::backupArgs *b = (fs::backupArgs *)ma->b; + + int sel = b->m->getSelected(); + if(sel == 0) + fs::getShowDirProps(*ma->path); + else if(sel > 1 && b->d->isDir(sel - 2)) + { + std::string folderPath = *ma->path + b->d->getItem(sel - 2) + "/"; + fs::getShowDirProps(folderPath); + } + else if(sel > 1) + { + std::string filePath = *ma->path + b->d->getItem(sel - 2); + fs::getShowFileProps(filePath); + } +} + static void _copyMenuClose(void *a) { menuFuncArgs *ma = (menuFuncArgs *)a; @@ -430,6 +450,7 @@ void ui::fmInit() devCopyMenu->optAddButtonEvent(2, HidNpadButton_A, _copyMenuRename, devArgs); devCopyMenu->optAddButtonEvent(3, HidNpadButton_A, _copyMenuMkDir, devArgs); devCopyMenu->optAddButtonEvent(4, HidNpadButton_A, _devMenuAddToPathFilter, devArgs); + devCopyMenu->optAddButtonEvent(5, HidNpadButton_A, _copyMenuGetProps, devArgs); devCopyMenu->optAddButtonEvent(6, HidNpadButton_A, _copyMenuClose, devArgs); ui::registerPanel(devPanel); @@ -448,6 +469,7 @@ void ui::fmInit() sdCopyMenu->optAddButtonEvent(1, HidNpadButton_A, _copyMenuDelete, sdmcArgs); sdCopyMenu->optAddButtonEvent(2, HidNpadButton_A, _copyMenuRename, sdmcArgs); sdCopyMenu->optAddButtonEvent(3, HidNpadButton_A, _copyMenuMkDir, sdmcArgs); + sdCopyMenu->optAddButtonEvent(4, HidNpadButton_A, _copyMenuGetProps, sdmcArgs); sdCopyMenu->optAddButtonEvent(5, HidNpadButton_A, _copyMenuClose, sdmcArgs); ui::registerPanel(sdPanel); diff --git a/src/ui/miscui.cpp b/src/ui/miscui.cpp index 1470f62..8f6c6c2 100644 --- a/src/ui/miscui.cpp +++ b/src/ui/miscui.cpp @@ -476,6 +476,47 @@ void ui::confirm(void *a) ui::newThread(confirm_t, a, confirmDrawFunc); } +static void showMessage_t(void *a) +{ + threadInfo *t = (threadInfo *)a; + std::string *text = (std::string *)t->argPtr; + while(true) + { + if(ui::padKeysDown() & HidNpadButton_A) + break; + + svcSleepThread(10000000); + } + delete text; + t->finished = true; +} + +static void showMessageDrawFunc(void *a) +{ + threadInfo *t = (threadInfo *)a; + std::string *text = (std::string *)t->argPtr; + if(!t->finished) + { + unsigned okX = 640 - (gfx::getTextWidth(ui::getUICString("dialogOK", 0), 18) / 2); + ui::drawTextbox(NULL, 280, 262, 720, 256); + gfx::drawLine(NULL, &ui::rectSh, 280, 454, 999, 454); + gfx::drawTextfWrap(NULL, 16, 312, 288, 656, &ui::txtCont, text->c_str()); + gfx::drawTextf(NULL, 18, okX, 478, &ui::txtCont, ui::getUICString("dialogOK", 0)); + } +} + +void ui::showMessage(const char *fmt, ...) +{ + char tmp[1024]; + va_list args; + va_start(args, fmt); + vsprintf(tmp, fmt, args); + va_end(args); + + std::string *send = new std::string(tmp); + ui::newThread(showMessage_t, send, showMessageDrawFunc); +} + void ui::drawTextbox(SDL_Texture *target, int x, int y, int w, int h) { //Top diff --git a/src/ui/uistr.cpp b/src/ui/uistr.cpp index a2a3179..a37e2b6 100644 --- a/src/ui/uistr.cpp +++ b/src/ui/uistr.cpp @@ -24,6 +24,7 @@ void ui::initStrings() //Y/N On/Off addUIString("dialogYes", 0, "Yes [A]"); addUIString("dialogNo", 0, "No [B]"); + addUIString("dialogOK", 0, "OK [A]"); addUIString("settingsOn", 0, ">On>"); addUIString("settingsOff", 0, "Off"); addUIString("holdingText", 0, "(Hold) "); @@ -65,6 +66,10 @@ void ui::initStrings() addUIString("fileModeMenu", 5, "Close"); addUIString("fileModeMenu", 6, "Add to Path Filters"); + //File mode properties string + addUIString("fileModeFileProperties", 0, "Path: %s\nSize: %s"); + addUIString("fileModeFolderProperties", 0, "Path: %s\nSub Folders: %u\nFile Count: %u\nTotal Size: %s"); + //Settings menu addUIString("settingsMenu", 0, "Empty Trash Bin"); addUIString("settingsMenu", 1, "Check for Updates"); @@ -134,10 +139,14 @@ void ui::initStrings() addUIString("threadStatusDeletingUpdate", 0, "Deleting pending update..."); addUIString("threadStatusCheckingForUpdate", 0, "Checking for updates..."); addUIString("threadStatusDownloadingUpdate", 0, "Downloading update..."); + addUIString("threadStatusGetDirProps", 0, "Getting Folder Properties..."); //Random leftover pop-ups addUIString("popCPUBoostEnabled", 0, "CPU Boost Enabled for ZIP."); addUIString("popErrorCommittingFile", 0, "Error committing file to save!"); + addUIString("popZipIsEmpty", 0, "ZIP file is empty!"); + addUIString("popFolderIsEmpty", 0, "Folder is empty!"); + addUIString("popSaveIsEmpty", 0, "Save data is empty!"); addUIString("popProcessShutdown", 0, "#%s# successfully shutdown."); addUIString("popAddedToPathFilter", 0, "'#%s#' added to path filters."); diff --git a/src/util.cpp b/src/util.cpp index fabbfb7..26d2863 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -389,6 +389,20 @@ void util::checkForUpdate(void *a) t->finished = true; } +std::string util::getSizeString(const uint64_t& _size) +{ + char sizeStr[32]; + if(_size >= 0x40000000) + sprintf(sizeStr, "%.2fGB", (float)_size / 1024.0f / 1024.0f / 1024.0f); + else if(_size >= 0x100000) + sprintf(sizeStr, "%.2fMB", (float)_size / 1024.0f / 1024.0f); + else if(_size >= 0x400) + sprintf(sizeStr, "%.2fKB", (float)_size / 1024.0f); + else + sprintf(sizeStr, "%lu Bytes", _size); + return std::string(sizeStr); +} + Result util::accountDeleteUser(AccountUid *uid) { Service *account = accountGetServiceSession();