Multi file copy paste support (#63)

* multi file copy paste support

* fix indentation

* fix overflow
This commit is contained in:
Void 2020-07-30 17:15:55 -05:00 committed by GitHub
parent ddee897052
commit 7e7ae6159a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 112 additions and 78 deletions

View File

@ -16,13 +16,15 @@ u32 copyBuf[copyBufSize];
extern PrintConsole topConsole, bottomConsole; extern PrintConsole topConsole, bottomConsole;
char clipboard[256]; vector<ClipboardFile> clipboard;
char clipboardFilename[256];
bool clipboardFolder = false;
bool clipboardOn = false; bool clipboardOn = false;
bool clipboardUsed = false; bool clipboardUsed = false;
int clipboardDrive = false; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2
bool clipboardInNitro = false; ClipboardFile::ClipboardFile(const char *iPath, const char *iName, bool folder, int drive, bool nitro) : folder(folder), drive(drive), nitro(nitro)
{
strncpy(path, iPath, 256);
strncpy(name, iName, 256);
}
void printBytes(int bytes) void printBytes(int bytes)
{ {
@ -62,11 +64,11 @@ void printBytesAlign(int bytes)
off_t getFileSize(const char *fileName) off_t getFileSize(const char *fileName)
{ {
FILE* fp = fopen(fileName, "rb"); FILE* fp = fopen(fileName, "rb");
off_t fsize = 0; off_t fsize = 0;
if (fp) { if (fp) {
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
fsize = ftell(fp); // Get source file's size fsize = ftell(fp); // Get source file's size
fseek(fp, 0, SEEK_SET); fseek(fp, 0, SEEK_SET);
} }
fclose(fp); fclose(fp);
@ -110,18 +112,18 @@ int fcopy(const char *sourcePath, const char *destinationPath)
closedir(isDir); closedir(isDir);
// Source path is a file // Source path is a file
FILE* sourceFile = fopen(sourcePath, "rb"); FILE* sourceFile = fopen(sourcePath, "rb");
off_t fsize = 0; off_t fsize = 0;
if (sourceFile) { if (sourceFile) {
fseek(sourceFile, 0, SEEK_END); fseek(sourceFile, 0, SEEK_END);
fsize = ftell(sourceFile); // Get source file's size fsize = ftell(sourceFile); // Get source file's size
fseek(sourceFile, 0, SEEK_SET); fseek(sourceFile, 0, SEEK_SET);
} else { } else {
fclose(sourceFile); fclose(sourceFile);
return -1; return -1;
} }
FILE* destinationFile = fopen(destinationPath, "wb"); FILE* destinationFile = fopen(destinationPath, "wb");
//if (destinationFile) { //if (destinationFile) {
fseek(destinationFile, 0, SEEK_SET); fseek(destinationFile, 0, SEEK_SET);
/*} else { /*} else {
@ -153,7 +155,7 @@ int fcopy(const char *sourcePath, const char *destinationPath)
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color
printf ("\x1b[16;0H"); printf ("\x1b[16;0H");
printf ("Progress:\n"); printf ("Progress:\n");
printf ("%i/%i Bytes ", (int)offset, (int)fsize); printf ("%i/%i Bytes ", (int)offset, (int)fsize);
// Copy file to destination path // Copy file to destination path
numr = fread(copyBuf, 1, copyBufSize, sourceFile); numr = fread(copyBuf, 1, copyBufSize, sourceFile);
@ -165,7 +167,7 @@ int fcopy(const char *sourcePath, const char *destinationPath)
fclose(destinationFile); fclose(destinationFile);
printf ("\x1b[17;0H"); printf ("\x1b[17;0H");
printf ("%i/%i Bytes ", (int)fsize, (int)fsize); printf ("%i/%i Bytes ", (int)fsize, (int)fsize);
for (int i = 0; i < 30; i++) swiWaitForVBlank(); for (int i = 0; i < 30; i++) swiWaitForVBlank();
return 1; return 1;
@ -204,7 +206,7 @@ void changeFileAttribs(DirEntry* entry) {
printf ("\x1b[%i;0H", 5+cursorScreenPos); printf ("\x1b[%i;0H", 5+cursorScreenPos);
printf ("[ ] U read-only [ ] D hidden"); printf ("[ ] U read-only [ ] D hidden");
printf ("\x1b[%i;0H", 6+cursorScreenPos); printf ("\x1b[%i;0H", 6+cursorScreenPos);
printf ("[ ] R system [ ] L archive"); printf ("[ ] R system [ ] L archive");
printf ("\x1b[%i;0H", 7+cursorScreenPos); printf ("\x1b[%i;0H", 7+cursorScreenPos);
printf ("[ ] virtual"); printf ("[ ] virtual");
printf ("\x1b[%i;1H", 7+cursorScreenPos); printf ("\x1b[%i;1H", 7+cursorScreenPos);
@ -223,7 +225,7 @@ void changeFileAttribs(DirEntry* entry) {
printf ("\x1b[%i;18H", 6+cursorScreenPos); printf ("\x1b[%i;18H", 6+cursorScreenPos);
printf ((newAttribs & ATTR_ARCHIVE) ? "X" : " "); printf ((newAttribs & ATTR_ARCHIVE) ? "X" : " ");
printf ("\x1b[%i;0H", 11+cursorScreenPos); printf ("\x1b[%i;0H", 11+cursorScreenPos);
printf ((currentAttribs==newAttribs) ? "(<A> to continue) " : "(<A> to apply, <B> to cancel)"); printf ((currentAttribs==newAttribs) ? "(<A> to continue) " : "(<A> to apply, <B> to cancel)");
consoleSelect(&topConsole); consoleSelect(&topConsole);
printf ("\x1B[30m"); // Print black color printf ("\x1B[30m"); // Print black color

View File

@ -5,13 +5,19 @@
#ifndef FILE_COPY #ifndef FILE_COPY
#define FILE_COPY #define FILE_COPY
extern char clipboard[256]; struct ClipboardFile {
extern char clipboardFilename[256]; char path[256];
extern bool clipboardFolder; char name[256];
bool folder;
int drive; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2
bool nitro;
ClipboardFile(const char *path, const char *name, bool folder, int drive, bool nitro);
};
extern vector<ClipboardFile> clipboard;
extern bool clipboardOn; extern bool clipboardOn;
extern bool clipboardUsed; extern bool clipboardUsed;
extern int clipboardDrive; // 0 == SD card, 1 == Flashcard, 2 == RAMdrive 1, 3 == RAMdrive 2
extern bool clipboardInNitro;
extern void printBytes(int bytes); extern void printBytes(int bytes);
extern void printBytesAlign(int bytes); extern void printBytesAlign(int bytes);
@ -20,4 +26,4 @@ extern off_t getFileSize(const char *fileName);
extern int fcopy(const char *sourcePath, const char *destinationPath); extern int fcopy(const char *sourcePath, const char *destinationPath);
void changeFileAttribs(DirEntry* entry); void changeFileAttribs(DirEntry* entry);
#endif // FILE_COPY #endif // FILE_COPY

View File

@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
------------------------------------------------------------------*/ ------------------------------------------------------------------*/
@ -247,7 +247,7 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
} }
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 4; assignedOp[maxCursors] = 4;
printf(entry->isDirectory ? " Show directory info\n" : " Show file info\n"); printf(entry->isDirectory ? " Show directory info\n" : " Show file info\n");
if (sdMounted && (strcmp (path, "sd:/gm9i/out/") != 0)) { if (sdMounted && (strcmp (path, "sd:/gm9i/out/") != 0)) {
maxCursors++; maxCursors++;
assignedOp[maxCursors] = 1; assignedOp[maxCursors] = 1;
@ -288,10 +288,10 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
consoleSelect(&bottomConsole); consoleSelect(&bottomConsole);
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color
if (pressed & KEY_UP) optionOffset -= 1; if (pressed & KEY_UP) optionOffset -= 1;
if (pressed & KEY_DOWN) optionOffset += 1; if (pressed & KEY_DOWN) optionOffset += 1;
if (optionOffset < 0) optionOffset = maxCursors; // Wrap around to bottom of list if (optionOffset < 0) optionOffset = maxCursors; // Wrap around to bottom of list
if (optionOffset > maxCursors) optionOffset = 0; // Wrap around to top of list if (optionOffset > maxCursors) optionOffset = 0; // Wrap around to top of list
if (pressed & KEY_A) { if (pressed & KEY_A) {
@ -313,7 +313,7 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
char destPath[256]; char destPath[256];
snprintf(destPath, sizeof(destPath), "sd:/gm9i/out/%s", entry->name.c_str()); snprintf(destPath, sizeof(destPath), "sd:/gm9i/out/%s", entry->name.c_str());
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Copying... "); printf("Copying... ");
remove(destPath); remove(destPath);
char sourceFolder[PATH_MAX]; char sourceFolder[PATH_MAX];
getcwd(sourceFolder, PATH_MAX); getcwd(sourceFolder, PATH_MAX);
@ -335,7 +335,7 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
char destPath[256]; char destPath[256];
snprintf(destPath, sizeof(destPath), "fat:/gm9i/out/%s", entry->name.c_str()); snprintf(destPath, sizeof(destPath), "fat:/gm9i/out/%s", entry->name.c_str());
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos); iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW+cursorScreenPos);
printf("Copying... "); printf("Copying... ");
remove(destPath); remove(destPath);
char sourceFolder[PATH_MAX]; char sourceFolder[PATH_MAX];
getcwd(sourceFolder, PATH_MAX); getcwd(sourceFolder, PATH_MAX);
@ -368,7 +368,7 @@ int fileBrowse_A(DirEntry* entry, char path[PATH_MAX]) {
} }
} }
bool fileBrowse_paste(char destPath[256]) { bool fileBrowse_paste(char dest[256]) {
int pressed = 0; int pressed = 0;
int optionOffset = 0; int optionOffset = 0;
int maxCursors = -1; int maxCursors = -1;
@ -376,14 +376,17 @@ bool fileBrowse_paste(char destPath[256]) {
consoleSelect(&bottomConsole); consoleSelect(&bottomConsole);
consoleClear(); consoleClear();
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color
printf(clipboardFolder ? "Paste folder here?" : "Paste file here?"); printf("Paste clipboard here?");
printf("\n\n"); printf("\n\n");
iprintf ("\x1b[%d;0H", OPTIONS_ENTRIES_START_ROW); iprintf ("\x1b[%d;0H", OPTIONS_ENTRIES_START_ROW);
maxCursors++; maxCursors++;
printf(" Copy path\n"); printf(" Copy files\n");
if (!clipboardInNitro) { for (auto it = clipboard.begin(); it != clipboard.end(); ++it) {
if (it->nitro)
continue;
maxCursors++; maxCursors++;
printf(" Move path\n"); printf(" Move files\n");
break;
} }
printf("\n"); printf("\n");
printf("(<A> select, <B> cancel)"); printf("(<A> select, <B> cancel)");
@ -415,27 +418,33 @@ bool fileBrowse_paste(char destPath[256]) {
consoleSelect(&bottomConsole); consoleSelect(&bottomConsole);
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color
if (pressed & KEY_UP) optionOffset -= 1; if (pressed & KEY_UP) optionOffset -= 1;
if (pressed & KEY_DOWN) optionOffset += 1; if (pressed & KEY_DOWN) optionOffset += 1;
if (optionOffset < 0) optionOffset = maxCursors; // Wrap around to bottom of list if (optionOffset < 0) optionOffset = maxCursors; // Wrap around to bottom of list
if (optionOffset > maxCursors) optionOffset = 0; // Wrap around to top of list if (optionOffset > maxCursors) optionOffset = 0; // Wrap around to top of list
if (pressed & KEY_A) { if (pressed & KEY_A) {
char destPath[256];
iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW); iprintf ("\x1b[%d;3H", optionOffset + OPTIONS_ENTRIES_START_ROW);
if (optionOffset == 0) { printf(optionOffset ? "Moving..." : "Copying...");
printf("Copying..."); for (auto it = clipboard.begin(); it != clipboard.end(); ++it) {
remove(destPath); snprintf(destPath, sizeof(destPath), "%s%s", dest, it->name);
fcopy(clipboard, destPath); if (!strcmp (it->path, destPath))
} else { continue; // If the source and destination for the clipped file is the same skip it
printf("Moving...");
if (currentDrive == clipboardDrive) { if (optionOffset && !it->nitro ) { // Don't remove if from nitro
rename(clipboard, destPath); if (currentDrive == it->drive) {
rename(it->path, destPath);
} else {
fcopy(it->path, destPath); // Copy file to destination, since renaming won't work
remove(it->path); // Delete source file after copying
}
clipboardUsed = false; // Disable clipboard restore
} else { } else {
fcopy(clipboard, destPath); // Copy file to destination, since renaming won't work remove(destPath);
remove(clipboard); // Delete source file after copying fcopy(it->path, destPath);
} }
clipboardUsed = false; // Disable clipboard restore
} }
clipboardOn = false; // Clear clipboard after copying or moving clipboardOn = false; // Clear clipboard after copying or moving
return true; return true;
@ -467,7 +476,8 @@ void fileBrowse_drawBottomScreen(DirEntry* entry) {
printf ("\x1b[22;0H"); printf ("\x1b[22;0H");
printf ("%s\n", titleName); printf ("%s\n", titleName);
printf ("X - DELETE/[+R] RENAME file\n"); printf ("X - DELETE/[+R] RENAME file\n");
printf ("%s/[+R] CREATE entry%s", clipboardOn ? "Y - PASTE file" : "Y - COPY file", clipboardOn ? "" : "\n"); printf ("L - COPY file\n");
printf ("Y - PASTE file/[+R] CREATE entry");
printf ("R+A - Directory options\n"); printf ("R+A - Directory options\n");
if (sdMounted || flashcardMounted) { if (sdMounted || flashcardMounted) {
printf ("%s\n", SCREENSHOTTEXT); printf ("%s\n", SCREENSHOTTEXT);
@ -497,8 +507,15 @@ void fileBrowse_drawBottomScreen(DirEntry* entry) {
printf ("\x1b[9;0H"); printf ("\x1b[9;0H");
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color
printf ("[CLIPBOARD]\n"); printf ("[CLIPBOARD]\n");
printf (clipboardFolder ? "\x1B[37m" : "\x1B[40m"); // Print custom blue color or foreground black color for (size_t i = 0; i < clipboard.size(); ++i) {
printf (clipboardFilename); printf (clipboard[i].folder ? "\x1B[37m" : "\x1B[40m"); // Print custom blue color or foreground black color
if (i < 5) {
printf ("%s\n", clipboard[i].name);
} else {
printf ("%d more files...\n", clipboard.size() - 5);
break;
}
}
} }
} }
@ -544,7 +561,7 @@ string browseForFile (void) {
} }
} while (!(pressed & KEY_UP) && !(pressed & KEY_DOWN) && !(pressed & KEY_LEFT) && !(pressed & KEY_RIGHT) } while (!(pressed & KEY_UP) && !(pressed & KEY_DOWN) && !(pressed & KEY_LEFT) && !(pressed & KEY_RIGHT)
&& !(pressed & KEY_A) && !(pressed & KEY_B) && !(pressed & KEY_X) && !(pressed & KEY_Y) && !(pressed & KEY_A) && !(pressed & KEY_B) && !(pressed & KEY_X) && !(pressed & KEY_Y)
&& !(pressed & KEY_SELECT)); && !(pressed & KEY_L) && !(pressed & KEY_SELECT));
printf ("\x1B[47m"); // Print foreground white color printf ("\x1B[47m"); // Print foreground white color
iprintf ("\x1b[%d;0H", fileOffset - screenOffset + ENTRIES_START_ROW); iprintf ("\x1b[%d;0H", fileOffset - screenOffset + ENTRIES_START_ROW);
@ -567,7 +584,7 @@ string browseForFile (void) {
// Scroll screen if needed // Scroll screen if needed
if (fileOffset < screenOffset) { if (fileOffset < screenOffset) {
screenOffset = fileOffset; screenOffset = fileOffset;
} }
if (fileOffset > screenOffset + ENTRIES_PER_SCREEN - 1) { if (fileOffset > screenOffset + ENTRIES_PER_SCREEN - 1) {
@ -640,7 +657,7 @@ string browseForFile (void) {
// Rename file/folder // Rename file/folder
if ((held & KEY_R) && (pressed & KEY_X) && (strcmp (entry->name.c_str(), "..") != 0) && (strncmp (path, "nitro:/", 7) != 0)) { if ((held & KEY_R) && (pressed & KEY_X) && (strcmp (entry->name.c_str(), "..") != 0) && (strncmp (path, "nitro:/", 7) != 0)) {
printf ("\x1b[0;27H"); printf ("\x1b[0;27H");
printf (" "); // Clear time printf (" "); // Clear time
pressed = 0; pressed = 0;
consoleDemoInit(); consoleDemoInit();
Keyboard *kbd = keyboardDemoInit(); Keyboard *kbd = keyboardDemoInit();
@ -730,10 +747,15 @@ string browseForFile (void) {
} }
char filePath[256]; char filePath[256];
snprintf(filePath, sizeof(filePath), "%s%s", path, entry->name.c_str()); snprintf(filePath, sizeof(filePath), "%s%s", path, entry->name.c_str());
if (strcmp(filePath, clipboard) == 0) { auto it = clipboard.begin();
clipboardUsed = false; // Disable clipboard restore while (it != clipboard.end()) {
clipboardOn = false; if (!strcmp(filePath, it->path))
it = clipboard.erase(it); // Remove deleted file from clipboard if it was in it
else
++it;
} }
if (clipboard.empty())
clipboardUsed = false;
getDirectoryContents (dirContents); getDirectoryContents (dirContents);
fileOffset--; fileOffset--;
} }
@ -750,7 +772,7 @@ string browseForFile (void) {
// Create new folder // Create new folder
if ((held & KEY_R) && (pressed & KEY_Y) && (strncmp (path, "nitro:/", 7) != 0)) { if ((held & KEY_R) && (pressed & KEY_Y) && (strncmp (path, "nitro:/", 7) != 0)) {
printf ("\x1b[0;27H"); printf ("\x1b[0;27H");
printf (" "); // Clear time printf (" "); // Clear time
pressed = 0; pressed = 0;
consoleDemoInit(); consoleDemoInit();
Keyboard *kbd = keyboardDemoInit(); Keyboard *kbd = keyboardDemoInit();
@ -788,27 +810,31 @@ string browseForFile (void) {
} }
} }
// Copy file/folder // Copy
if (pressed & KEY_Y) { if (pressed & KEY_L && strcmp (entry->name.c_str(), "..") != 0) {
if (clipboardOn) { if (!clipboardOn)
char destPath[256]; clipboard.clear();
snprintf(destPath, sizeof(destPath), "%s%s", path, clipboardFilename); char file[256];
if (strncmp (path, "nitro:/", 7) != 0 && string(clipboard) != string(destPath)) { snprintf(file, sizeof(file), "%s%s", path, entry->name.c_str());
if (fileBrowse_paste(destPath)) { bool exists = false;
getDirectoryContents (dirContents); for (auto it = clipboard.begin(); it != clipboard.end(); ++it) {
} if (strcmp (it->path, file)) // Check if file already in clipboard
} continue;
} else if (strcmp(entry->name.c_str(), "..") != 0) { exists = true;
snprintf(clipboard, sizeof(clipboard), "%s%s", path, entry->name.c_str()); break;
snprintf(clipboardFilename, sizeof(clipboardFilename), "%s", entry->name.c_str()); }
clipboardFolder = entry->isDirectory; if (!exists) {
clipboard.emplace_back(file, entry->name.c_str(), entry->isDirectory, currentDrive, !strncmp (path, "nitro:/", 7));
clipboardOn = true; clipboardOn = true;
clipboardDrive = currentDrive;
clipboardInNitro = (strncmp (path, "nitro:/", 7) == 0);
clipboardUsed = true; clipboardUsed = true;
} }
} }
// Paste
if (pressed & KEY_Y && clipboardOn && strncmp (path, "nitro:/", 7) != 0 && fileBrowse_paste(path)) {
getDirectoryContents (dirContents);
}
if ((pressed & KEY_SELECT) && clipboardUsed) { if ((pressed & KEY_SELECT) && clipboardUsed) {
clipboardOn = !clipboardOn; clipboardOn = !clipboardOn;
} }