#include #include "ui.h" #include "fs.h" #include "util.h" #include "cfg.h" static ui::menu *fldMenu = NULL; ui::slideOutPanel *ui::fldPanel = NULL; static fs::dirList *fldList = NULL; static SDL_Texture *fldBuffer; static unsigned int fldGuideWidth = 0; static Mutex fldLock = 0; static std::string driveParent; static std::vector driveFldList; static void fldMenuCallback(void *a) { switch(ui::padKeysDown()) { case HidNpadButton_B: fs::unmountSave(); fs::freePathFilters(); fldMenu->setActive(false); ui::fldPanel->closePanel(); unsigned cusr = data::getCurrentUserIndex(); ui::ttlSetActive(cusr, true, true); ui::updateInput(); break; } } static void fldPanelDraw(void *a) { mutexLock(&fldLock); SDL_Texture *target = (SDL_Texture *)a; gfx::clearTarget(fldBuffer, &ui::slidePanelColor); fldMenu->draw(fldBuffer, &ui::txtCont, true); gfx::texDraw(target, fldBuffer, 0, 0); gfx::drawLine(target, &ui::divClr, 10, 648, fldGuideWidth + 54, 648); gfx::drawTextf(target, 18, 32, 673, &ui::txtCont, ui::getUICString("helpFolder", 0)); mutexUnlock(&fldLock); } static void fldFuncCancel(void *a) { std::string *del = (std::string *)a; delete del; } static void fldFuncOverwrite(void *a) { fs::dirItem *in = (fs::dirItem *)a; data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo(); std::string *send = new std::string; send->assign(util::generatePathByTID(utinfo->tid) + in->getItm()); ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdOver"], fs::overwriteBackup, fldFuncCancel, send, ui::getUICString("confirmOverwrite", 0), in->getItm().c_str()); ui::confirm(conf); } static void fldFuncDelete(void *a) { fs::dirItem *in = (fs::dirItem *)a; data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo(); std::string *send = new std::string; send->assign(util::generatePathByTID(utinfo->tid) + in->getItm()); ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], fs::deleteBackup, fldFuncCancel, send, ui::getUICString("confirmDelete", 0), in->getItm().c_str()); ui::confirm(conf); } static void fldFuncRestore(void *a) { fs::dirItem *in = (fs::dirItem *)a; data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo(); std::string *send = new std::string; send->assign(util::generatePathByTID(utinfo->tid) + in->getItm()); ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdRest"], fs::restoreBackup, fldFuncCancel, send, ui::getUICString("confirmRestore", 0), in->getItm().c_str()); ui::confirm(conf); } static void fldFuncUpload_t(void *a) { threadInfo *t = (threadInfo *)a; fs::dirItem *di = (fs::dirItem *)t->argPtr; fsSetPriority(FsPriority_Realtime); data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo(); std::string path, tmpZip, filename;//Final path to upload from if(cfg::config["ovrClk"]) util::sysBoost(); //Zip first then upload if folder based backup if(di->isDir()) { t->status->setStatus(ui::getUICString("threadStatusCompressingSaveForUpload", 0), di->getItm().c_str()); filename = di->getItm() + ".zip"; tmpZip = util::generatePathByTID(utinfo->tid) + di->getItm() + ".zip"; std::string fldPath = util::generatePathByTID(utinfo->tid) + di->getItm() + "/"; int zipTrim = util::getTotalPlacesInPath(fs::getWorkDir()) + 2;//Trim path down to save root zipFile tmp = zipOpen64(tmpZip.c_str(), 0); fs::copyDirToZip(fldPath, tmp, true, zipTrim, NULL); zipClose(tmp, NULL); path = tmpZip; } else { filename = di->getItm(); path = util::generatePathByTID(utinfo->tid) + di->getItm(); } //Change thread stuff so upload status can be shown t->status->setStatus(ui::getUICString("threadStatusUploadingFile", 0), di->getItm().c_str()); fs::copyArgs *cpyArgs = fs::copyArgsCreate("", "", "", NULL, NULL, false, false, 0); cpyArgs->prog->setMax(fs::fsize(path)); cpyArgs->prog->update(0); t->argPtr = cpyArgs; t->drawFunc = fs::fileDrawFunc; //curlDlArgs curlFuncs::curlUpArgs upload; upload.f = fopen(path.c_str(), "rb"); upload.o = &cpyArgs->offset; if(fs::rfs->fileExists(filename, driveParent)) { std::string id = fs::rfs->getFileID(filename, driveParent); fs::rfs->updateFile(id, &upload); } else fs::rfs->uploadFile(filename, driveParent, &upload); fclose(upload.f); if(!tmpZip.empty()) fs::delfile(tmpZip); fs::copyArgsDestroy(cpyArgs); t->drawFunc = NULL; if(cfg::config["ovrClk"]) util::sysNormal(); ui::fldRefreshMenu(); t->finished = true; } static void fldFuncUpload(void *a) { if(fs::rfs) ui::newThread(fldFuncUpload_t, a, NULL); else ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popRemoteNotActive", 0)); } static void fldFuncDownload_t(void *a) { threadInfo *t = (threadInfo *)a; rfs::RfsItem *in = (rfs::RfsItem *)t->argPtr; data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo(); std::string targetPath = util::generatePathByTID(utinfo->tid) + in->name; t->status->setStatus(ui::getUICString("threadStatusDownloadingFile", 0), in->name.c_str()); if(cfg::config["ovrClk"]) util::sysBoost(); if(fs::fileExists(targetPath)) fs::delfile(targetPath); //Use this for progress bar fs::copyArgs *cpy = fs::copyArgsCreate("", "", "", NULL, NULL, false, false, 0); cpy->prog->setMax(in->size); cpy->prog->update(0); t->argPtr = cpy; t->drawFunc = fs::fileDrawFunc; //DL struct curlFuncs::curlDlArgs dlFile; dlFile.path = targetPath; dlFile.size = in->size; dlFile.o = &cpy->offset; fs::rfs->downloadFile(in->id, &dlFile); //fclose(dlFile.f); fs::copyArgsDestroy(cpy); t->drawFunc = NULL; if(cfg::config["ovrClk"]) util::sysNormal(); ui::fldRefreshMenu(); t->finished = true; } static void fldFuncDownload(void *a) { rfs::RfsItem *in = (rfs::RfsItem *)a; data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo(); std::string testPath = util::generatePathByTID(utinfo->tid) + in->name; if(fs::fileExists(testPath)) { ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdOver"], fldFuncDownload_t, NULL, a, ui::getUICString("confirmDriveOverwrite", 0)); ui::confirm(conf); } else ui::newThread(fldFuncDownload_t, a, NULL); } static void fldFuncDriveDelete_t(void *a) { threadInfo *t = (threadInfo *)a; rfs::RfsItem *gdi = (rfs::RfsItem *)t->argPtr; t->status->setStatus(ui::getUICString("threadStatusDeletingFile", 0)); fs::rfs->deleteFile(gdi->id); ui::fldRefreshMenu(); t->finished = true; } static void fldFuncDriveDelete(void *a) { rfs::RfsItem *in = (rfs::RfsItem *)a; ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], fldFuncDriveDelete_t, NULL, a, ui::getUICString("confirmDelete", 0), in->name.c_str()); ui::confirm(conf); } static void fldFuncDriveRestore_t(void *a) { threadInfo *t = (threadInfo *)a; rfs::RfsItem *gdi = (rfs::RfsItem *)t->argPtr; t->status->setStatus(ui::getUICString("threadStatusDownloadingFile", 0), gdi->name.c_str()); fs::copyArgs *cpy = fs::copyArgsCreate("", "", "", NULL, NULL, false, false, 0); cpy->prog->setMax(gdi->size); cpy->prog->update(0); t->argPtr = cpy; t->drawFunc = fs::fileDrawFunc; curlFuncs::curlDlArgs dlFile; dlFile.path = "sdmc:/tmp.zip"; dlFile.size = gdi->size; dlFile.o = &cpy->offset; fs::rfs->downloadFile(gdi->id, &dlFile); unzFile tmp = unzOpen64("sdmc:/tmp.zip"); fs::copyZipToDir(tmp, "sv:/", "sv", t); unzClose(tmp); fs::delfile("sdmc:/tmp.zip"); fs::copyArgsDestroy(cpy); t->argPtr = NULL; t->drawFunc = NULL; t->finished = true; } static void fldFuncDriveRestore(void *a) { rfs::RfsItem *in = (rfs::RfsItem *)a; ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdOver"], fldFuncDriveRestore_t, NULL, a, ui::getUICString("confirmRestore", 0), in->name.c_str()); ui::confirm(conf); } void ui::fldInit() { fldGuideWidth = gfx::getTextWidth(ui::getUICString("helpFolder", 0), 18); fldMenu = new ui::menu(10, 4, fldGuideWidth + 44, 18, 6); fldMenu->setCallback(fldMenuCallback, NULL); fldMenu->setActive(false); ui::fldPanel = new ui::slideOutPanel(fldGuideWidth + 64, 720, 0, ui::SLD_RIGHT, fldPanelDraw); fldBuffer = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET, fldGuideWidth + 64, 647); ui::registerPanel(fldPanel); fldList = new fs::dirList; } void ui::fldExit() { delete ui::fldPanel; delete fldMenu; delete fldList; } void ui::fldUpdate() { fldMenu->update(); } void ui::fldPopulateMenu() { mutexLock(&fldLock); fldMenu->reset(); data::userTitleInfo *d = data::getCurrentUserTitleInfo(); data::titleInfo *t = data::getTitleInfoByTID(d->tid); util::createTitleDirectoryByTID(d->tid); std::string targetDir = util::generatePathByTID(d->tid); fldList->reassign(targetDir); fs::loadPathFilters(d->tid); fldMenu->addOpt(NULL, ui::getUICString("folderMenuNew", 0)); fldMenu->optAddButtonEvent(0, HidNpadButton_A, fs::createNewBackup, NULL); unsigned fldInd = 1; if(fs::rfs) { if(!fs::rfs->dirExists(t->title, fs::rfsRootID)) fs::rfs->createDir(t->title, fs::rfsRootID); driveParent = fs::rfs->getDirID(t->title, fs::rfsRootID); driveFldList = fs::rfs->getListWithParent(driveParent); for(unsigned i = 0; i < driveFldList.size(); i++, fldInd++) { fldMenu->addOpt(NULL, "[R] " + driveFldList[i].name); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_A, fldFuncDownload, &driveFldList[i]); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_X, fldFuncDriveDelete, &driveFldList[i]); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_Y, fldFuncDriveRestore, &driveFldList[i]); } } for(unsigned i = 0; i < fldList->getCount(); i++, fldInd++) { fs::dirItem *di = fldList->getDirItemAt(i); fldMenu->addOpt(NULL, di->getItm()); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_A, fldFuncOverwrite, di); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_X, fldFuncDelete, di); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_Y, fldFuncRestore, di); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_ZR, fldFuncUpload, di); } fldMenu->setActive(true); ui::fldPanel->openPanel(); mutexUnlock(&fldLock); } void ui::fldRefreshMenu() { mutexLock(&fldLock); fldMenu->reset(); data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo(); std::string targetDir = util::generatePathByTID(utinfo->tid); fldList->reassign(targetDir); fldMenu->addOpt(NULL, ui::getUIString("folderMenuNew", 0)); fldMenu->optAddButtonEvent(0, HidNpadButton_A, fs::createNewBackup, NULL); unsigned fldInd = 1; if(fs::rfs) { driveFldList = fs::rfs->getListWithParent(driveParent); for(unsigned i = 0; i < driveFldList.size(); i++, fldInd++) { fldMenu->addOpt(NULL, "[R] " + driveFldList[i].name); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_A, fldFuncDownload, &driveFldList[i]); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_X, fldFuncDriveDelete, &driveFldList[i]); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_Y, fldFuncDriveRestore, &driveFldList[i]); } } for(unsigned i = 0; i < fldList->getCount(); i++, fldInd++) { fs::dirItem *di = fldList->getDirItemAt(i); fldMenu->addOpt(NULL, di->getItm()); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_A, fldFuncOverwrite, di); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_X, fldFuncDelete, di); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_Y, fldFuncRestore, di); fldMenu->optAddButtonEvent(fldInd, HidNpadButton_ZR, fldFuncUpload, di); } mutexUnlock(&fldLock); }