diff --git a/radio/src/gui/colorlcd/radio_sdmanager.cpp b/radio/src/gui/colorlcd/radio_sdmanager.cpp index 3e9227cb0..5079e5269 100644 --- a/radio/src/gui/colorlcd/radio_sdmanager.cpp +++ b/radio/src/gui/colorlcd/radio_sdmanager.cpp @@ -25,12 +25,83 @@ #include "io/multi_firmware_update.h" #include "io/bootloader_flash.h" #include "standalone_lua.h" +#include "sdcard.h" + +class FileNameEditWindow : public Page +{ + public: + FileNameEditWindow(const std::string iName) : + Page(ICON_RADIO_SD_MANAGER), name(std::move(iName)) + { + buildBody(&body); + buildHeader(&header); + }; + +#if defined(DEBUG_WINDOWS) + std::string getName() const override { return "FileNameEditWindow"; } +#endif + protected: + const std::string name; + + void buildHeader(Window *window) + { + new StaticText(window, {70, 4, 180, 30}, STR_RENAME_FILE, MENU_BGCOLOR); + } + + void buildBody(Window *window) + { + GridLayout grid(window); + grid.spacer(8); + uint8_t nameLength; + uint8_t extLength; + char extension[LEN_FILE_EXTENSION_MAX + 1]; + memset(extension, 0, sizeof(extension)); + const char *ext = + getFileExtension(name.data(), 0, 0, &nameLength, &extLength); + + if (extLength > LEN_FILE_EXTENSION_MAX) extLength = LEN_FILE_EXTENSION_MAX; + if (ext) strncpy(extension, ext, extLength); + + const uint8_t maxNameLength = SD_SCREEN_FILE_LENGTH - extLength; + nameLength -= extLength; + if (nameLength > maxNameLength) nameLength = maxNameLength; + memset(reusableBuffer.sdManager.originalName, 0, SD_SCREEN_FILE_LENGTH); + + strncpy(reusableBuffer.sdManager.originalName, name.c_str(), nameLength); + reusableBuffer.sdManager.originalName[nameLength] = '\0'; + + auto newFileName = new TextEdit( + window, grid.getSlot(), reusableBuffer.sdManager.originalName, + SD_SCREEN_FILE_LENGTH - extLength, LcdFlags(0)); + newFileName->setChangeHandler([=]() { + char *newValue = reusableBuffer.sdManager.originalName; + size_t totalSize = strlen(newValue); + char changedName[SD_SCREEN_FILE_LENGTH + 1]; + memset(changedName, 0, sizeof(changedName)); + strncpy(changedName, newValue, totalSize); + changedName[totalSize] = '\0'; + if (extLength) { + strncpy(changedName + totalSize, extension, extLength); + } + changedName[totalSize + extLength] = '\0'; + f_rename((const TCHAR *)name.c_str(), (const TCHAR *)changedName); + }); + }; +}; RadioSdManagerPage::RadioSdManagerPage() : PageTab(SD_IS_HC() ? STR_SDHC_CARD : STR_SD_CARD, ICON_RADIO_SD_MANAGER) { } +void RadioSdManagerPage::rebuild(FormWindow * window) +{ + coord_t scrollPosition = window->getScrollPositionY(); + window->clear(); + build(window); + window->setScrollPositionY(scrollPosition); +} + // TODO elsewhere extern bool compare_nocase(const std::string &first, const std::string &second); @@ -38,7 +109,7 @@ extern bool compare_nocase(const std::string &first, const std::string &second); char * getFullPath(const std::string &filename) { static char full_path[FF_MAX_LFN + 1]; // TODO optimize that! - f_getcwd(full_path, FF_MAX_LFN); + f_getcwd((TCHAR*)full_path, FF_MAX_LFN); strcat(full_path, "/"); strcat(full_path, filename.c_str()); return full_path; @@ -266,20 +337,35 @@ void RadioSdManagerPage::build(FormWindow * window) } if (!READ_ONLY()) { menu->addLine(STR_COPY_FILE, [=]() { - clipboard.type = CLIPBOARD_TYPE_SD_FILE; - f_getcwd(clipboard.data.sd.directory, CLIPBOARD_PATH_LEN); - strncpy(clipboard.data.sd.filename, name.c_str(), CLIPBOARD_PATH_LEN - 1); + clipboard.type = CLIPBOARD_TYPE_SD_FILE; + f_getcwd(clipboard.data.sd.directory, CLIPBOARD_PATH_LEN); + strncpy(clipboard.data.sd.filename, name.c_str(), + CLIPBOARD_PATH_LEN - 1); }); if (clipboard.type == CLIPBOARD_TYPE_SD_FILE) { menu->addLine(STR_PASTE, [=]() { - // TODO + static char lfn[FF_MAX_LFN + 1]; // TODO optimize that! + f_getcwd((TCHAR *)lfn, FF_MAX_LFN); + // prevent copying to the same directory + if (strcmp(clipboard.data.sd.directory, lfn)) { + sdCopyFile(clipboard.data.sd.filename, + clipboard.data.sd.directory, + clipboard.data.sd.filename, lfn); + clipboard.type = CLIPBOARD_TYPE_NONE; + } + rebuild(window); }); } menu->addLine(STR_RENAME_FILE, [=]() { - // TODO + auto few = new FileNameEditWindow(name); + few->setCloseHandler([=]() { + //window->clear(); + rebuild(window); + }); + // rebuild(window); }); }); menu->addLine(STR_DELETE_FILE, [=]() { - f_unlink(getFullPath(name)); + f_unlink((const TCHAR*)getFullPath(name)); // coord_t scrollPosition = window->getScrollPositionY(); window->clear(); build(window); diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 033a7c339..cc9f4aff8 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -37,6 +37,12 @@ #include "usbd_conf.h" #endif +#if defined(LIBOPENUI) + #include "libopenui.h" +#else + #include "libopenui/src/libopenui_file.h" +#endif + #if defined(SIMU) #define SWITCH_SIMU(a, b) (a) #else