forked from Mirror/GodMode9
Add ahndling for overwrite / skip all existing
This commit is contained in:
parent
b46f5ab2ac
commit
fe14f071d0
72
source/fs.c
72
source/fs.c
@ -12,6 +12,9 @@
|
|||||||
#define NORM_FS 10
|
#define NORM_FS 10
|
||||||
#define VIRT_FS 5
|
#define VIRT_FS 5
|
||||||
|
|
||||||
|
#define SKIP_CUR (1<<3)
|
||||||
|
#define OVERWRITE_CUR (1<<4)
|
||||||
|
|
||||||
// Volume2Partition resolution table
|
// Volume2Partition resolution table
|
||||||
PARTITION VolToPart[] = {
|
PARTITION VolToPart[] = {
|
||||||
{0, 1}, {1, 0}, {2, 0}, {3, 0}, {4, 0},
|
{0, 1}, {1, 0}, {2, 0}, {3, 0}, {4, 0},
|
||||||
@ -508,7 +511,7 @@ bool FileInjectFile(const char* dest, const char* orig, u32 offset) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathCopyVirtual(const char* destdir, const char* orig) {
|
bool PathCopyVirtual(const char* destdir, const char* orig, u32* flags) {
|
||||||
char dest[256]; // maximum path name length in FAT
|
char dest[256]; // maximum path name length in FAT
|
||||||
char* oname = strrchr(orig, '/');
|
char* oname = strrchr(orig, '/');
|
||||||
char deststr[36 + 1];
|
char deststr[36 + 1];
|
||||||
@ -618,9 +621,12 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check if destination exists
|
// check if destination exists
|
||||||
if (f_stat(dest, NULL) == FR_OK) {
|
if (flags && !(*flags & OVERWRITE_ALL) && f_stat(dest, NULL) == FR_OK) {
|
||||||
const char* optionstr[3] = {"Choose new name", "Overwrite file", "Skip file"};
|
if (*flags & SKIP_ALL) return true;
|
||||||
u32 user_select = ShowSelectPrompt(3, optionstr, "Destination already exists:\n%s", deststr);
|
const char* optionstr[5] =
|
||||||
|
{"Choose new name", "Overwrite file", "Skip file", "Overwrite all", "Skip all"};
|
||||||
|
u32 user_select = ShowSelectPrompt((*flags & ASK_ALL) ? 5 : 3, optionstr,
|
||||||
|
"Destination already exists:\n%s", deststr);
|
||||||
if (user_select == 1) {
|
if (user_select == 1) {
|
||||||
do {
|
do {
|
||||||
char* dname = strrchr(dest, '/');
|
char* dname = strrchr(dest, '/');
|
||||||
@ -629,7 +635,17 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
|
|||||||
if (!ShowStringPrompt(dname, 255 - (dname - dest), "Choose new destination name"))
|
if (!ShowStringPrompt(dname, 255 - (dname - dest), "Choose new destination name"))
|
||||||
return false;
|
return false;
|
||||||
} while (f_stat(dest, NULL) == FR_OK);
|
} while (f_stat(dest, NULL) == FR_OK);
|
||||||
} else if (user_select != 2) return (user_select == 3);
|
} else if (user_select == 3) {
|
||||||
|
*flags |= SKIP_CUR;
|
||||||
|
return true;
|
||||||
|
} else if (user_select == 4) {
|
||||||
|
*flags |= OVERWRITE_ALL;
|
||||||
|
} else if (user_select == 5) {
|
||||||
|
*flags |= SKIP_ALL;
|
||||||
|
return true;
|
||||||
|
} else if (user_select != 2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_open(&dfile, dest, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
|
if (f_open(&dfile, dest, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK)
|
||||||
@ -666,11 +682,10 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathCopyWorker(char* dest, char* orig, bool overwrite, bool move) {
|
bool PathCopyWorker(char* dest, char* orig, u32* flags, bool move) {
|
||||||
FILINFO fno;
|
FILINFO fno;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
|
||||||
if (f_stat(dest, &fno) != FR_OK) { // is root or destination does not exist
|
if (f_stat(dest, &fno) != FR_OK) { // is root or destination does not exist
|
||||||
DIR tmp_dir; // check if root
|
DIR tmp_dir; // check if root
|
||||||
if (f_opendir(&tmp_dir, dest) != FR_OK) return false;
|
if (f_opendir(&tmp_dir, dest) != FR_OK) return false;
|
||||||
@ -699,18 +714,32 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite, bool move) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if destination exists
|
// check if destination exists
|
||||||
if (!overwrite && (f_stat(dest, NULL) == FR_OK)) {
|
if (flags && !(*flags & (OVERWRITE_CUR|OVERWRITE_ALL)) && (f_stat(dest, NULL) == FR_OK)) {
|
||||||
const char* optionstr[3] = {"Choose new name", "Overwrite file(s)", "Skip file(s)"};
|
if (*flags & SKIP_ALL) return true;
|
||||||
|
const char* optionstr[5] =
|
||||||
|
{"Choose new name", "Overwrite file(s)", "Skip file(s)", "Overwrite all", "Skip all"};
|
||||||
char namestr[36 + 1];
|
char namestr[36 + 1];
|
||||||
TruncateString(namestr, dest, 36, 8);
|
TruncateString(namestr, dest, 36, 8);
|
||||||
u32 user_select = ShowSelectPrompt(3, optionstr, "Destination already exists:\n%s", namestr);
|
u32 user_select = ShowSelectPrompt((*flags & ASK_ALL) ? 5 : 3, optionstr,
|
||||||
|
"Destination already exists:\n%s", namestr);
|
||||||
if (user_select == 1) {
|
if (user_select == 1) {
|
||||||
do {
|
do {
|
||||||
if (!ShowStringPrompt(dname, 255 - (dname - dest), "Choose new destination name"))
|
if (!ShowStringPrompt(dname, 255 - (dname - dest), "Choose new destination name"))
|
||||||
return false;
|
return false;
|
||||||
} while (f_stat(dest, NULL) == FR_OK);
|
} while (f_stat(dest, NULL) == FR_OK);
|
||||||
} else if (user_select != 2) return (user_select == 3);
|
} else if (user_select == 2) {
|
||||||
overwrite = true;
|
*flags |= OVERWRITE_CUR;
|
||||||
|
} else if (user_select == 3) {
|
||||||
|
*flags |= SKIP_CUR;
|
||||||
|
return true;
|
||||||
|
} else if (user_select == 4) {
|
||||||
|
*flags |= OVERWRITE_ALL;
|
||||||
|
} else if (user_select == 5) {
|
||||||
|
*flags |= SKIP_ALL;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the copy process takes place here
|
// the copy process takes place here
|
||||||
@ -738,7 +767,7 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite, bool move) {
|
|||||||
if (fno.fname[0] == 0) {
|
if (fno.fname[0] == 0) {
|
||||||
ret = true;
|
ret = true;
|
||||||
break;
|
break;
|
||||||
} else if (!PathCopyWorker(dest, orig, overwrite, move)) {
|
} else if (!PathCopyWorker(dest, orig, flags, move)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -802,27 +831,30 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite, bool move) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathCopy(const char* destdir, const char* orig) {
|
bool PathCopy(const char* destdir, const char* orig, u32* flags) {
|
||||||
if (!CheckWritePermissions(destdir)) return false;
|
if (!CheckWritePermissions(destdir)) return false;
|
||||||
|
if (flags) *flags = *flags & ~(SKIP_CUR|OVERWRITE_CUR); // reset local flags
|
||||||
if (GetVirtualSource(destdir) || GetVirtualSource(orig)) {
|
if (GetVirtualSource(destdir) || GetVirtualSource(orig)) {
|
||||||
// users are inventive...
|
// users are inventive...
|
||||||
if ((PathToNumFS(orig) > 0) && GetVirtualSource(destdir)) {
|
if ((PathToNumFS(orig) > 0) && GetVirtualSource(destdir)) {
|
||||||
ShowPrompt(false, "Only files from SD card are accepted");
|
ShowPrompt(false, "Only files from SD card are accepted");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return PathCopyVirtual(destdir, orig);
|
return PathCopyVirtual(destdir, orig, flags);
|
||||||
} else {
|
} else {
|
||||||
char fdpath[256]; // 256 is the maximum length of a full path
|
char fdpath[256]; // 256 is the maximum length of a full path
|
||||||
char fopath[256];
|
char fopath[256];
|
||||||
strncpy(fdpath, destdir, 255);
|
strncpy(fdpath, destdir, 255);
|
||||||
strncpy(fopath, orig, 255);
|
strncpy(fopath, orig, 255);
|
||||||
return PathCopyWorker(fdpath, fopath, false, false);
|
bool res = PathCopyWorker(fdpath, fopath, flags, false);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathMove(const char* destdir, const char* orig) {
|
bool PathMove(const char* destdir, const char* orig, u32* flags) {
|
||||||
if (!CheckWritePermissions(destdir)) return false;
|
if (!CheckWritePermissions(destdir)) return false;
|
||||||
if (!CheckWritePermissions(orig)) return false;
|
if (!CheckWritePermissions(orig)) return false;
|
||||||
|
if (flags) *flags = *flags & ~(SKIP_CUR|OVERWRITE_CUR); // reset local flags
|
||||||
if (GetVirtualSource(destdir) || GetVirtualSource(orig)) {
|
if (GetVirtualSource(destdir) || GetVirtualSource(orig)) {
|
||||||
ShowPrompt(false, "Error: Moving virtual files not possible");
|
ShowPrompt(false, "Error: Moving virtual files not possible");
|
||||||
return false;
|
return false;
|
||||||
@ -832,8 +864,8 @@ bool PathMove(const char* destdir, const char* orig) {
|
|||||||
strncpy(fdpath, destdir, 255);
|
strncpy(fdpath, destdir, 255);
|
||||||
strncpy(fopath, orig, 255);
|
strncpy(fopath, orig, 255);
|
||||||
bool same_drv = (PathToNumFS(orig) == PathToNumFS(destdir));
|
bool same_drv = (PathToNumFS(orig) == PathToNumFS(destdir));
|
||||||
bool res = PathCopyWorker(fdpath, fopath, false, same_drv);
|
bool res = PathCopyWorker(fdpath, fopath, flags, same_drv);
|
||||||
if (res) PathDelete(orig);
|
if (res && (!flags || !(*flags&(SKIP_CUR|SKIP_ALL)))) PathDelete(orig);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,10 @@ typedef enum {
|
|||||||
#define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE)
|
#define PERM_BASE (PERM_SDCARD | PERM_RAMDRIVE)
|
||||||
#define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY)
|
#define PERM_ALL (PERM_SDCARD | PERM_RAMDRIVE | PERM_EMUNAND | PERM_SYSNAND | PERM_IMAGE | PERM_MEMORY)
|
||||||
|
|
||||||
|
#define ASK_ALL (1<<0)
|
||||||
|
#define SKIP_ALL (1<<1)
|
||||||
|
#define OVERWRITE_ALL (1<<2)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char* name; // should point to the correct portion of the path
|
char* name; // should point to the correct portion of the path
|
||||||
char path[256];
|
char path[256];
|
||||||
@ -76,10 +80,10 @@ u32 FileFindData(const char* path, u8* data, u32 size, u32 offset);
|
|||||||
bool FileInjectFile(const char* dest, const char* orig, u32 offset);
|
bool FileInjectFile(const char* dest, const char* orig, u32 offset);
|
||||||
|
|
||||||
/** Recursively copy a file or directory **/
|
/** Recursively copy a file or directory **/
|
||||||
bool PathCopy(const char* destdir, const char* orig);
|
bool PathCopy(const char* destdir, const char* orig, u32* flags);
|
||||||
|
|
||||||
/** Recursively move a file or directory **/
|
/** Recursively move a file or directory **/
|
||||||
bool PathMove(const char* destdir, const char* orig);
|
bool PathMove(const char* destdir, const char* orig, u32* flags);
|
||||||
|
|
||||||
/** Recursively delete a file or directory **/
|
/** Recursively delete a file or directory **/
|
||||||
bool PathDelete(const char* path);
|
bool PathDelete(const char* path);
|
||||||
|
@ -118,8 +118,8 @@ void DrawUserInterface(const char* curr_path, DirEntry* curr_entry, DirStruct* c
|
|||||||
160 / FONT_WIDTH_EXT, tempstr);
|
160 / FONT_WIDTH_EXT, tempstr);
|
||||||
|
|
||||||
// bottom: inctruction block
|
// bottom: inctruction block
|
||||||
char instr[256];
|
char instr[512];
|
||||||
snprintf(instr, 256, "%s%s\n%s%s%s%s%s%s%s",
|
snprintf(instr, 512, "%s%s\n%s%s%s%s%s%s%s",
|
||||||
#ifndef SAFEMODE
|
#ifndef SAFEMODE
|
||||||
"GodMode9 Explorer v", VERSION, // generic start part
|
"GodMode9 Explorer v", VERSION, // generic start part
|
||||||
#else
|
#else
|
||||||
@ -823,6 +823,7 @@ u32 GodMode() {
|
|||||||
} else if (pad_state & BUTTON_Y) { // paste files
|
} else if (pad_state & BUTTON_Y) { // paste files
|
||||||
const char* optionstr[2] = { "Copy path(s)", "Move path(s)" };
|
const char* optionstr[2] = { "Copy path(s)", "Move path(s)" };
|
||||||
char promptstr[64];
|
char promptstr[64];
|
||||||
|
u32 flags = 0;
|
||||||
u32 user_select;
|
u32 user_select;
|
||||||
if (clipboard->n_entries == 1) {
|
if (clipboard->n_entries == 1) {
|
||||||
char namestr[20+1];
|
char namestr[20+1];
|
||||||
@ -835,11 +836,13 @@ u32 GodMode() {
|
|||||||
for (u32 c = 0; c < clipboard->n_entries; c++) {
|
for (u32 c = 0; c < clipboard->n_entries; c++) {
|
||||||
char namestr[36+1];
|
char namestr[36+1];
|
||||||
TruncateString(namestr, clipboard->entry[c].name, 36, 12);
|
TruncateString(namestr, clipboard->entry[c].name, 36, 12);
|
||||||
if ((user_select == 1) && !PathCopy(current_path, clipboard->entry[c].path)) {
|
flags &= ~ASK_ALL;
|
||||||
|
if (c < clipboard->n_entries - 1) flags |= ASK_ALL;
|
||||||
|
if ((user_select == 1) && !PathCopy(current_path, clipboard->entry[c].path, &flags)) {
|
||||||
if (c + 1 < clipboard->n_entries) {
|
if (c + 1 < clipboard->n_entries) {
|
||||||
if (!ShowPrompt(true, "Failed copying path:\n%s\nProcess remaining?", namestr)) break;
|
if (!ShowPrompt(true, "Failed copying path:\n%s\nProcess remaining?", namestr)) break;
|
||||||
} else ShowPrompt(false, "Failed copying path:\n%s", namestr);
|
} else ShowPrompt(false, "Failed copying path:\n%s", namestr);
|
||||||
} else if ((user_select == 2) && !PathMove(current_path, clipboard->entry[c].path)) {
|
} else if ((user_select == 2) && !PathMove(current_path, clipboard->entry[c].path, &flags)) {
|
||||||
if (c + 1 < clipboard->n_entries) {
|
if (c + 1 < clipboard->n_entries) {
|
||||||
if (!ShowPrompt(true, "Failed moving path:\n%s\nProcess remaining?", namestr)) break;
|
if (!ShowPrompt(true, "Failed moving path:\n%s\nProcess remaining?", namestr)) break;
|
||||||
} else ShowPrompt(false, "Failed moving path:\n%s", namestr);
|
} else ShowPrompt(false, "Failed moving path:\n%s", namestr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user