diff --git a/radio/releasenotes.txt b/radio/releasenotes.txt index 05f7efaca..050ac9ae4 100644 --- a/radio/releasenotes.txt +++ b/radio/releasenotes.txt @@ -7,6 +7,7 @@
  • 9XE top LDC fixes: added TX battery blinking on battery warning, fixed display problem when battery voltage lower than batlow value. (#2671)
  • Timers range extended (it was limited to around 9 hours before) (#2702)
  • Fixed: Playing two background sounds at once causes sound to stop (#2704)
  • +
  • Several fixes to the SD card manager menu (#2623)
  • [Sky9x / 9XR-PRO] diff --git a/radio/src/gui/Taranis/menu_general_sdmanager.cpp b/radio/src/gui/Taranis/menu_general_sdmanager.cpp index 95257a827..4dfc3f4db 100755 --- a/radio/src/gui/Taranis/menu_general_sdmanager.cpp +++ b/radio/src/gui/Taranis/menu_general_sdmanager.cpp @@ -36,7 +36,10 @@ #include "../../opentx.h" -#define REFRESH_FILES() reusableBuffer.sdmanager.offset = 65535 +#define REFRESH_FILES() do { reusableBuffer.sdmanager.offset = 65535; m_posVert = 0; } while(0) +#define NODE_TYPE(fname) fname[SD_SCREEN_FILE_LENGTH+1] +#define IS_DIRECTORY(fname) ((bool)(!NODE_TYPE(fname))) +#define IS_FILE(fname) ((bool)(NODE_TYPE(fname))) void menuGeneralSdManagerInfo(uint8_t event) { @@ -66,12 +69,12 @@ void menuGeneralSdManagerInfo(uint8_t event) inline bool isFilenameGreater(bool isfile, const char * fn, const char * line) { - return (isfile && !line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) > 0); + return (isfile && IS_DIRECTORY(line)) || (isfile==IS_FILE(line) && strcasecmp(fn, line) > 0); } inline bool isFilenameLower(bool isfile, const char * fn, const char * line) { - return (!isfile && line[SD_SCREEN_FILE_LENGTH+1]) || (isfile==(bool)line[SD_SCREEN_FILE_LENGTH+1] && strcasecmp(fn, line) < 0); + return (!isfile && IS_FILE(line)) || (isfile==IS_FILE(line) && strcasecmp(fn, line) < 0); } bool isBootloader(const char *filename) @@ -172,19 +175,31 @@ void onSdManagerMenu(const char *result) } else if (result == STR_PASTE) { f_getcwd(lfn, _MAX_LFN); - POPUP_WARNING(fileCopy(clipboard.data.sd.filename, clipboard.data.sd.directory, lfn)); - REFRESH_FILES(); + // if destination is dir, copy into that dir + if (IS_DIRECTORY(line)) { + strcat(lfn, PSTR("/")); + strcat(lfn, line); + } + if (strcmp(clipboard.data.sd.directory, lfn)) { // prevent copying to the same directory + POPUP_WARNING(fileCopy(clipboard.data.sd.filename, clipboard.data.sd.directory, lfn)); + REFRESH_FILES(); + } } else if (result == STR_RENAME_FILE) { + memcpy(reusableBuffer.sdmanager.originalName, line, sizeof(reusableBuffer.sdmanager.originalName)); char *ext = getFileExtension(line, SD_SCREEN_FILE_LENGTH+1); if (ext) { - memcpy(reusableBuffer.sdmanager.originalName, line, sizeof(reusableBuffer.sdmanager.originalName)); // write spaces to allow a longer filename memset(ext, ' ', SD_SCREEN_FILE_LENGTH-LEN_FILE_EXTENSION-(ext-line)); line[SD_SCREEN_FILE_LENGTH-LEN_FILE_EXTENSION] = '\0'; - s_editMode = EDIT_MODIFY_STRING; - editNameCursorPos = 0; } + else { + int len = strlen(line); + memset(line + strlen(line), ' ', SD_SCREEN_FILE_LENGTH - len); + line[SD_SCREEN_FILE_LENGTH] = '\0'; + } + s_editMode = EDIT_MODIFY_STRING; + editNameCursorPos = 0; } else if (result == STR_DELETE_FILE) { getSelectionFullPath(lfn); @@ -193,9 +208,6 @@ void onSdManagerMenu(const char *result) strcpy_P(statusLineMsg+min((uint8_t)strlen(statusLineMsg), (uint8_t)13), STR_REMOVED); showStatusLine(); REFRESH_FILES(); - if (m_posVert == reusableBuffer.sdmanager.count-1) { - m_posVert--; - } } else if (result == STR_PLAY_FILE) { getSelectionFullPath(lfn); @@ -279,7 +291,7 @@ void menuGeneralSdManager(uint8_t _event) break; } else { - if (!reusableBuffer.sdmanager.lines[index][SD_SCREEN_FILE_LENGTH+1]) { + if (IS_DIRECTORY(reusableBuffer.sdmanager.lines[index])) { f_chdir(reusableBuffer.sdmanager.lines[index]); s_pgOfs = 0; m_posVert = 1; @@ -296,6 +308,9 @@ void menuGeneralSdManager(uint8_t _event) killEvents(_event); char *line = reusableBuffer.sdmanager.lines[index]; char *ext = getFileExtension(line, SD_SCREEN_FILE_LENGTH+1); + if (!strcmp(line, "..")) { + break; // no menu for parent dir + } if (ext) { if (!strcasecmp(ext, SOUNDS_EXT)) { MENU_ADD_ITEM(STR_PLAY_FILE); @@ -326,12 +341,13 @@ void menuGeneralSdManager(uint8_t _event) } } if (!READ_ONLY()) { - if (line[SD_SCREEN_FILE_LENGTH+1]) // it's a file + if (IS_FILE(line)) // it's a file MENU_ADD_ITEM(STR_COPY_FILE); if (clipboard.type == CLIPBOARD_TYPE_SD_FILE) MENU_ADD_ITEM(STR_PASTE); MENU_ADD_ITEM(STR_RENAME_FILE); - MENU_ADD_ITEM(STR_DELETE_FILE); + if (IS_FILE(line)) + MENU_ADD_ITEM(STR_DELETE_FILE); } menuHandler = onSdManagerMenu; } @@ -357,7 +373,7 @@ void menuGeneralSdManager(uint8_t _event) else if (s_pgOfs > reusableBuffer.sdmanager.offset) { memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], 6*sizeof(reusableBuffer.sdmanager.lines[0])); memset(reusableBuffer.sdmanager.lines[6], 0xff, SD_SCREEN_FILE_LENGTH); - reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = 1; + NODE_TYPE(reusableBuffer.sdmanager.lines[6]) = 1; } else { memmove(reusableBuffer.sdmanager.lines[1], reusableBuffer.sdmanager.lines[0], 6*sizeof(reusableBuffer.sdmanager.lines[0])); @@ -388,9 +404,9 @@ void menuGeneralSdManager(uint8_t _event) char *line = reusableBuffer.sdmanager.lines[i]; if (line[0] == '\0' || isFilenameLower(isfile, fn, line)) { if (i < 6) memmove(reusableBuffer.sdmanager.lines[i+1], line, sizeof(reusableBuffer.sdmanager.lines[i]) * (6-i)); - memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i])); + memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); strcpy(line, fn); - line[SD_SCREEN_FILE_LENGTH+1] = isfile; + NODE_TYPE(line) = isfile; break; } } @@ -400,9 +416,9 @@ void menuGeneralSdManager(uint8_t _event) char *line = reusableBuffer.sdmanager.lines[i]; if (line[0] == '\0' || isFilenameGreater(isfile, fn, line)) { if (i > 0) memmove(reusableBuffer.sdmanager.lines[0], reusableBuffer.sdmanager.lines[1], sizeof(reusableBuffer.sdmanager.lines[0]) * i); - memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[i])); + memset(line, 0, sizeof(reusableBuffer.sdmanager.lines[0])); strcpy(line, fn); - line[SD_SCREEN_FILE_LENGTH+1] = isfile; + NODE_TYPE(line) = isfile; break; } } @@ -411,14 +427,14 @@ void menuGeneralSdManager(uint8_t _event) if (isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[5]) && isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[6])) { memset(reusableBuffer.sdmanager.lines[6], 0, sizeof(reusableBuffer.sdmanager.lines[0])); strcpy(reusableBuffer.sdmanager.lines[6], fn); - reusableBuffer.sdmanager.lines[6][SD_SCREEN_FILE_LENGTH+1] = isfile; + NODE_TYPE(reusableBuffer.sdmanager.lines[6]) = isfile; } } else { if (isFilenameLower(isfile, fn, reusableBuffer.sdmanager.lines[1]) && isFilenameGreater(isfile, fn, reusableBuffer.sdmanager.lines[0])) { memset(reusableBuffer.sdmanager.lines[0], 0, sizeof(reusableBuffer.sdmanager.lines[0])); strcpy(reusableBuffer.sdmanager.lines[0], fn); - reusableBuffer.sdmanager.lines[0][SD_SCREEN_FILE_LENGTH+1] = isfile; + NODE_TYPE(reusableBuffer.sdmanager.lines[0]) = isfile; } } } @@ -432,7 +448,7 @@ void menuGeneralSdManager(uint8_t _event) lcdNextPos = 0; LcdFlags attr = (index == i ? BSS|INVERS : BSS); if (reusableBuffer.sdmanager.lines[i][0]) { - if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(0, y, '[', s_editMode == EDIT_MODIFY_STRING ? 0 : attr); } + if (IS_DIRECTORY(reusableBuffer.sdmanager.lines[i])) { lcd_putcAtt(0, y, '[', s_editMode == EDIT_MODIFY_STRING ? 0 : attr); } if (s_editMode == EDIT_MODIFY_STRING && attr) { editName(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], SD_SCREEN_FILE_LENGTH-4, _event, attr, 0); if (s_editMode == 0) { @@ -441,6 +457,9 @@ void menuGeneralSdManager(uint8_t _event) if (ext) { strAppend(&reusableBuffer.sdmanager.lines[i][len], ext); } + else { + reusableBuffer.sdmanager.lines[i][len] = 0; + } f_rename(reusableBuffer.sdmanager.originalName, reusableBuffer.sdmanager.lines[i]); REFRESH_FILES(); } @@ -448,7 +467,7 @@ void menuGeneralSdManager(uint8_t _event) else { lcd_putsAtt(lcdNextPos, y, reusableBuffer.sdmanager.lines[i], attr); } - if (!reusableBuffer.sdmanager.lines[i][SD_SCREEN_FILE_LENGTH+1]) { lcd_putcAtt(lcdNextPos, y, ']', s_editMode == EDIT_MODIFY_STRING ? 0 : attr); } + if (IS_DIRECTORY(reusableBuffer.sdmanager.lines[i])) { lcd_putcAtt(lcdNextPos, y, ']', s_editMode == EDIT_MODIFY_STRING ? 0 : attr); } } } diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 6f108351b..a74e3fad1 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -929,14 +929,24 @@ FRESULT f_mkdir (const TCHAR*) return FR_OK; } -FRESULT f_unlink (const TCHAR*) +FRESULT f_unlink (const TCHAR* name) { + char *path = convertSimuPath(name); + if (unlink(path)) { + TRACE("f_unlink(%s) = error %d (%s)", path, errno, strerror(errno)); + return FR_INVALID_NAME; + } + TRACE("f_unlink(%s) = OK", path); return FR_OK; } FRESULT f_rename(const TCHAR *oldname, const TCHAR *newname) { - TRACE("f_rename(%s, %s)", oldname, newname); + if (rename(oldname, newname) < 0) { + TRACE("f_rename(%s, %s) = error %d (%s)", oldname, newname, errno, strerror(errno)); + return FR_INVALID_NAME; + } + TRACE("f_rename(%s, %s) = OK", oldname, newname); return FR_OK; } @@ -966,7 +976,12 @@ int f_printf (FIL *fil, const TCHAR * format, ...) FRESULT f_getcwd (TCHAR *path, UINT sz_path) { - strcpy(path, "."); + // remove simuSdDirectory from the cwd + char * cwd = get_current_dir_name(); + std::string c(cwd + strlen(simuSdDirectory)); + free(cwd); + strcpy(path, c.c_str()); + TRACE("f_getcwd() = %s", path); return FR_OK; }