Allow moving files & folders

This commit is contained in:
d0k3 2016-04-29 02:21:36 +02:00
parent ed77cde373
commit bc102c3645
4 changed files with 59 additions and 21 deletions

View File

@ -403,7 +403,7 @@ bool PathCopyVirtual(const char* destdir, const char* orig) {
return ret; return ret;
} }
bool PathCopyWorker(char* dest, char* orig, bool overwrite) { bool PathCopyWorker(char* dest, char* orig, bool overwrite, bool move) {
FILINFO fno = {.lfname = NULL}; FILINFO fno = {.lfname = NULL};
bool ret = false; bool ret = false;
@ -442,13 +442,15 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite) {
// the copy process takes place here // the copy process takes place here
if (!ShowProgress(0, 0, orig)) return false; if (!ShowProgress(0, 0, orig)) return false;
if (fno.fattrib & AM_DIR) { // processing folders... if (move && f_stat(dest, NULL) != FR_OK) { // moving if dest not existing
ret = (f_rename(orig, dest) == FR_OK);
} else if (fno.fattrib & AM_DIR) { // processing folders (same for move & copy)
DIR pdir; DIR pdir;
char* fname = orig + strnlen(orig, 256); char* fname = orig + strnlen(orig, 256);
// create the destination folder if it does not already exist // create the destination folder if it does not already exist
if ((f_opendir(&pdir, dest) != FR_OK) && (f_mkdir(dest) != FR_OK)) { if ((f_opendir(&pdir, dest) != FR_OK) && (f_mkdir(dest) != FR_OK)) {
ShowPrompt(false, "Error: Cannot create output dir"); ShowPrompt(false, "Error: Overwriting file with dir");
return false; return false;
} else f_closedir(&pdir); } else f_closedir(&pdir);
@ -466,12 +468,22 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite) {
if (fno.fname[0] == 0) { if (fno.fname[0] == 0) {
ret = true; ret = true;
break; break;
} else if (!PathCopyWorker(dest, orig, overwrite)) { } else if (!PathCopyWorker(dest, orig, overwrite, move)) {
break; break;
} }
} }
f_closedir(&pdir); f_closedir(&pdir);
} else { // processing files... } else if (move) { // moving if destination exists
if (f_stat(dest, &fno) != FR_OK)
return false;
if (fno.fattrib & AM_DIR) {
ShowPrompt(false, "Error: Overwriting dir with file");
return false;
}
if (f_unlink(dest) != FR_OK)
return false;
ret = (f_rename(orig, dest) == FR_OK);
} else { // copying files
FIL ofile; FIL ofile;
FIL dfile; FIL dfile;
size_t fsize; size_t fsize;
@ -486,7 +498,7 @@ bool PathCopyWorker(char* dest, char* orig, bool overwrite) {
} }
if (f_open(&dfile, dest, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK) { if (f_open(&dfile, dest, FA_WRITE | FA_CREATE_ALWAYS) != FR_OK) {
ShowPrompt(false, "Error: Cannot create output file"); ShowPrompt(false, "Error: Cannot create destination file");
f_close(&ofile); f_close(&ofile);
return false; return false;
} }
@ -533,7 +545,24 @@ bool PathCopy(const char* destdir, const char* orig) {
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); return PathCopyWorker(fdpath, fopath, false, false);
}
}
bool PathMove(const char* destdir, const char* orig) {
if (!CheckWritePermissions(destdir)) return false;
if (GetVirtualSource(destdir) || GetVirtualSource(orig)) {
ShowPrompt(false, "Error: Moving virtual files not possible");
return false;
} else {
char fdpath[256]; // 256 is the maximum length of a full path
char fopath[256];
strncpy(fdpath, destdir, 255);
strncpy(fopath, orig, 255);
bool same_drv = (PathToNumFS(orig) == PathToNumFS(destdir));
bool res = PathCopyWorker(fdpath, fopath, false, same_drv);
if (res) PathDelete(orig);
return res;
} }
} }

View File

@ -53,6 +53,9 @@ bool FileGetSha256(const char* path, u8* sha256);
/** 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);
/** Recursively move a file or directory **/
bool PathMove(const char* destdir, const char* orig);
/** Recursively delete a file or directory **/ /** Recursively delete a file or directory **/
bool PathDelete(const char* path); bool PathDelete(const char* path);

View File

@ -7,7 +7,7 @@
#include "virtual.h" #include "virtual.h"
#include "image.h" #include "image.h"
#define VERSION "0.3.7" #define VERSION "0.3.9"
#define N_PANES 2 #define N_PANES 2
#define IMG_DRV "789I" #define IMG_DRV "789I"
@ -337,18 +337,18 @@ u32 GodMode() {
} else if ((pad_state & BUTTON_A) && (curr_entry->type == T_FILE)) { // process a file } else if ((pad_state & BUTTON_A) && (curr_entry->type == T_FILE)) { // process a file
u32 file_type = IdentifyImage(curr_entry->path); u32 file_type = IdentifyImage(curr_entry->path);
char pathstr[32 + 1]; char pathstr[32 + 1];
const char* options[4]; const char* optionstr[4];
u32 n_opt = 2; u32 n_opt = 2;
TruncateString(pathstr, curr_entry->path, 32, 8); TruncateString(pathstr, curr_entry->path, 32, 8);
options[0] = "Show in Hexviewer"; optionstr[0] = "Show in Hexviewer";
options[1] = "Calculate SHA-256"; optionstr[1] = "Calculate SHA-256";
if (file_type && (PathToNumFS(curr_entry->path) == 0)) { if (file_type && (PathToNumFS(curr_entry->path) == 0)) {
options[2] = (file_type == IMG_NAND) ? "Mount as NAND image" : "Mount as FAT image"; optionstr[2] = (file_type == IMG_NAND) ? "Mount as NAND image" : "Mount as FAT image";
n_opt = 3; n_opt = 3;
} }
u32 user_select = ShowSelectPrompt(n_opt, options, pathstr); u32 user_select = ShowSelectPrompt(n_opt, optionstr, pathstr);
if (user_select == 1) { // -> show in hex viewer if (user_select == 1) { // -> show in hex viewer
static bool show_instr = true; static bool show_instr = true;
if (show_instr) { if (show_instr) {
@ -510,20 +510,26 @@ u32 GodMode() {
if (clipboard->n_entries) if (clipboard->n_entries)
last_clipboard_size = clipboard->n_entries; last_clipboard_size = clipboard->n_entries;
} 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)" };
char promptstr[64]; char promptstr[64];
u32 user_select;
if (clipboard->n_entries == 1) { if (clipboard->n_entries == 1) {
char namestr[20+1]; char namestr[20+1];
TruncateString(namestr, clipboard->entry[0].name, 20, 12); TruncateString(namestr, clipboard->entry[0].name, 20, 12);
snprintf(promptstr, 64, "Copy \"%s\" here?", namestr); snprintf(promptstr, 64, "Copy / Move \"%s\" here?", namestr);
} else snprintf(promptstr, 64, "Copy %lu path(s) here?", clipboard->n_entries); } else snprintf(promptstr, 64, "Copy / Move %lu paths here?", clipboard->n_entries);
if (ShowPrompt(true, promptstr)) { if ((user_select = ShowSelectPrompt(2, optionstr, promptstr))) {
for (u32 c = 0; c < clipboard->n_entries; c++) { for (u32 c = 0; c < clipboard->n_entries; c++) {
if (!PathCopy(current_path, clipboard->entry[c].path)) {
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)) {
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)) {
if (c + 1 < clipboard->n_entries) {
if (!ShowPrompt(true, "Failed moving path:\n%s\nProcess remaining?", namestr)) break;
} else ShowPrompt(false, "Failed moving path:\n%s", namestr);
} }
} }
} }

View File

@ -291,7 +291,7 @@ u32 ShowSelectPrompt(u32 n, const char** options, const char *format, ...) {
str_width = GetDrawStringWidth(str); str_width = GetDrawStringWidth(str);
str_height = GetDrawStringHeight(str) + (n * 12) + (3 * 10); str_height = GetDrawStringHeight(str) + (n * 12) + (3 * 10);
if (str_width < 18*8) str_width = 18 * 8; if (str_width < 24*8) str_width = 24 * 8;
x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2; x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2; y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2;
yopt = y + GetDrawStringHeight(str) + 8; yopt = y + GetDrawStringHeight(str) + 8;
@ -341,7 +341,7 @@ bool ShowInputPrompt(char* inputstr, u32 max_size, const char *format, ...) {
str_width = GetDrawStringWidth(str); str_width = GetDrawStringWidth(str);
str_height = GetDrawStringHeight(str) + (8*10); str_height = GetDrawStringHeight(str) + (8*10);
if (str_width < 24) str_width = 24; if (str_width < (24*8)) str_width = 24 * 8;
x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2; x = (str_width >= SCREEN_WIDTH_TOP) ? 0 : (SCREEN_WIDTH_TOP - str_width) / 2;
y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2; y = (str_height >= SCREEN_HEIGHT) ? 0 : (SCREEN_HEIGHT - str_height) / 2;