mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
- updated build instructions - added user-agent header to webdav calls - Generalized popDriveNotActive to popRemoteNotActive - Updated version identifier presented in app - Removed some commented code
391 lines
12 KiB
C++
391 lines
12 KiB
C++
#include <switch.h>
|
|
|
|
#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<rfs::RfsItem> 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);
|
|
} |