Add ahndling for overwrite / skip all existing

This commit is contained in:
d0k3 2016-07-27 00:19:12 +02:00
parent b46f5ab2ac
commit fe14f071d0
3 changed files with 65 additions and 26 deletions

View File

@ -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;
} }
} }

View File

@ -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);

View File

@ -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);