diff --git a/radio/src/gui/colorlcd/draw_functions.cpp b/radio/src/gui/colorlcd/draw_functions.cpp index e8dfe8125..6c8e57dfe 100644 --- a/radio/src/gui/colorlcd/draw_functions.cpp +++ b/radio/src/gui/colorlcd/draw_functions.cpp @@ -539,8 +539,8 @@ void drawTextLines(BitmapBuffer * dc, coord_t left, coord_t top, coord_t width, case '(': case '{': case '[': - nxt++; case ' ': + nxt++; case '\n': case '\0': done = true; diff --git a/radio/src/gui/colorlcd/model_select.cpp b/radio/src/gui/colorlcd/model_select.cpp index 58b97b568..f60fe42e8 100644 --- a/radio/src/gui/colorlcd/model_select.cpp +++ b/radio/src/gui/colorlcd/model_select.cpp @@ -24,26 +24,270 @@ #include "opentx.h" #include "storage/modelslist.h" #include "libopenui.h" +#include "standalone_lua.h" #if LCD_W > LCD_H constexpr int MODEL_CELLS_PER_LINE = 3; #else constexpr int MODEL_CELLS_PER_LINE = 2; #endif - constexpr coord_t MODEL_CELL_PADDING = 6; - constexpr coord_t MODEL_SELECT_CELL_WIDTH = (LCD_W - (MODEL_CELLS_PER_LINE + 1) * MODEL_CELL_PADDING) / MODEL_CELLS_PER_LINE; - constexpr coord_t MODEL_SELECT_CELL_HEIGHT = 92; - constexpr coord_t MODEL_IMAGE_WIDTH = MODEL_SELECT_CELL_WIDTH; constexpr coord_t MODEL_IMAGE_HEIGHT = 72; - +constexpr size_t LEN_INFO_TEXT = 300; +constexpr size_t LEN_PATH = sizeof(TEMPLATES_PATH) + TEXT_FILENAME_MAXLEN; +constexpr size_t LEN_BUFFER = sizeof(TEMPLATES_PATH) + 2 * TEXT_FILENAME_MAXLEN + 1; inline tmr10ms_t getTicks() { return g_tmr10ms; } +class TemplatePage : public Page +{ + public: + + TemplatePage() : Page(ICON_MODEL_SELECT) + { } + + void updateInfo() + { + FIL fp; + FRESULT res = f_open (&fp, buffer, FA_READ); + unsigned int bytesRead = 0; + if (res == FR_OK) { + f_read (&fp, infoText, LEN_INFO_TEXT, &bytesRead); + f_close(&fp); + } + infoText[bytesRead] = '\0'; + invalidate(); + } + +#if defined(HARDWARE_KEYS) + void onEvent(event_t event) override + { + if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) { + killEvents(event); + deleteLater(); + } else { + Page::onEvent(event); + } + } +#endif +#if defined(DEBUG_WINDOWS) + std::string getName() const { return "TemplatePage"; } +#endif + + protected: + + static char path[LEN_PATH + 1]; + char buffer[LEN_BUFFER + 1]; + char infoText[LEN_INFO_TEXT + 1] = { 0 }; + unsigned int count = 0; + + void paint(BitmapBuffer *dc) + { + Page::paint(dc); + rect_t rect = body.getRect(); + coord_t x = LCD_W / 2 + PAGE_PADDING; + coord_t y = rect.y + PAGE_PADDING; + coord_t w = LCD_W / 2 - 2 * PAGE_PADDING; + coord_t h = rect.h - 2 * PAGE_PADDING; + if (count > 0) { + if (infoText[0] == '\0') + drawTextLines(dc, x, y, w, h, STR_NO_INFORMATION, COLOR_THEME_DISABLED); + else + drawTextLines(dc, x, y, w, h, infoText, COLOR_THEME_PRIMARY1); + } + } +}; + +char TemplatePage::path[LEN_PATH + 1]; + +class TemplateButton : public TextButton +{ + public: + TemplateButton(FormGroup* parent, const rect_t& rect, std::string name, std::function pressHandler = nullptr) + : TextButton(parent, rect, name, pressHandler) + { } +}; + +class SelectTemplate : public TemplatePage +{ + public: + SelectTemplate(TemplatePage* tp) + : templateFolderPage(tp) + { + rect_t rect = {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + 10, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}; + new StaticText(&header, rect, STR_SELECT_TEMPLATE, 0, COLOR_THEME_PRIMARY2); + + FormGridLayout grid; + grid.spacer(PAGE_PADDING); + std::list files; + FILINFO fno; + DIR dir; + FRESULT res = f_opendir(&dir, path); + + if (res == FR_OK) { + // read all entries + bool firstTime = true; + for (;;) { + res = sdReadDir(&dir, &fno, firstTime); + firstTime = false; + if (res != FR_OK || fno.fname[0] == 0) + break; // Break on error or end of dir + if (strlen((const char*)fno.fname) > SD_SCREEN_FILE_LENGTH) + continue; + if (fno.fname[0] == '.') + continue; + if (!(fno.fattrib & AM_DIR)) { + const char *ext = getFileExtension(fno.fname); + if(ext && !strcasecmp(ext, YAML_EXT)) { + int len = ext - fno.fname; + if (len < FF_MAX_LFN) { + char name[FF_MAX_LFN] = { 0 }; + strncpy(name, fno.fname, len); + files.push_back(name); + } + } + } + } + + files.sort(compare_nocase); + + for (auto name: files) { + auto tb = new TemplateButton(&body, grid.getLabelSlot(), name, [=]() -> uint8_t { + // Read model template + loadModelTemplate((name + YAML_EXT).c_str(), path); + storageDirty(EE_MODEL); + storageCheck(true); + // Update model list with new name + auto model = modelslist.getCurrentModel(); + model->setModelName(g_model.header.name); + modelslist.save(); + // Dismiss template pages + deleteLater(); + templateFolderPage->deleteLater(); + // If there is a wizard Lua script, fire it up + snprintf(buffer, LEN_BUFFER, "%s%c%s%s", path, '/', name.c_str(), SCRIPT_EXT); + if (f_stat(buffer, 0) == FR_OK) { + luaExec(buffer); + StandaloneLuaWindow::instance()->attach(focusWindow); + } + + return 0; + }); + tb->setFocusHandler([=](bool active) { + if (active) { + snprintf(buffer, LEN_BUFFER, "%s%c%s%s", path, '/', name.c_str(), TEXT_EXT); + updateInfo(); + } + }); + grid.nextLine(); + } + body.setInnerHeight(grid.getWindowHeight()); + } + + f_closedir(&dir); + count = files.size(); + if (count == 0) { + rect_t rect = body.getRect(); + rect.x = PAGE_PADDING; + rect.y = PAGE_PADDING; + rect.w = rect.w - 2 * PAGE_PADDING; + rect.h = PAGE_LINE_HEIGHT; + new StaticText(&body, rect, STR_NO_TEMPLATES, 0, COLOR_THEME_PRIMARY1); + // The following button is needed because the EXIT key does not work without... + rect = body.getRect(); + rect.x = rect.w - PAGE_PADDING - 100; + rect.y = rect.h - PAGE_PADDING - PAGE_LINE_HEIGHT; + rect.w = 100; + rect.h = PAGE_LINE_HEIGHT; + new TemplateButton(&body, rect, STR_EXIT, [=]() -> uint8_t { deleteLater(); return 0; }); + } else { + snprintf(buffer, LEN_BUFFER, "%s%c%s%s", path, '/', files.front().c_str(), TEXT_EXT); + updateInfo(); + } + } + + protected: + TemplatePage* templateFolderPage; +}; + +class SelectTemplateFolder : public TemplatePage +{ + public: + SelectTemplateFolder() + { + rect_t rect = {PAGE_TITLE_LEFT, PAGE_TITLE_TOP + 10, LCD_W - PAGE_TITLE_LEFT, PAGE_LINE_HEIGHT}; + new StaticText(&header, rect, STR_SELECT_TEMPLATE_FOLDER, 0, COLOR_THEME_PRIMARY2); + + FormGridLayout grid; + grid.spacer(PAGE_PADDING); + + auto tfb = new TemplateButton(&body, grid.getLabelSlot(), "Blank Model", [=]() -> uint8_t { + deleteLater(); + return 0; + }); + tfb->setFocusHandler([=](bool active) { + if (active) { + snprintf(infoText, LEN_INFO_TEXT, "%c", '\0'); + invalidate(); + } + }); + grid.nextLine(); + + std::list directories; + FILINFO fno; + DIR dir; + FRESULT res = f_opendir(&dir, TEMPLATES_PATH); + + if (res == FR_OK) { + // read all entries + bool firstTime = true; + for (;;) { + res = sdReadDir(&dir, &fno, firstTime); + firstTime = false; + if (res != FR_OK || fno.fname[0] == 0) + break; // Break on error or end of dir + if (strlen((const char*)fno.fname) > SD_SCREEN_FILE_LENGTH) + continue; + if (fno.fname[0] == '.') + continue; + if (fno.fattrib & AM_DIR) + directories.push_back((char*)fno.fname); + } + + directories.sort(compare_nocase); + + for (auto name: directories) { + auto tfb = new TemplateButton(&body, grid.getLabelSlot(), name, + [=]() -> uint8_t { + snprintf(path, LEN_PATH, "%s%c%s", TEMPLATES_PATH, '/', name.c_str()); + new SelectTemplate(this); + return 0; + }); + tfb->setFocusHandler([=](bool active) { + if (active) { + snprintf(buffer, LEN_BUFFER, "%s%c%s%c%s%s", TEMPLATES_PATH, '/', name.c_str(), '/', "about", TEXT_EXT); + updateInfo(); + } + }); + grid.nextLine(); + } + body.setInnerHeight(grid.getWindowHeight()); + } + + f_closedir(&dir); + count = directories.size(); + if (count == 0) { + rect_t rect = grid.getLabelSlot(); + rect.w = body.getRect().w - 2 * PAGE_PADDING; + new StaticText(&body, rect, STR_NO_TEMPLATES, 0, COLOR_THEME_PRIMARY1); + } + } +}; + class ModelButton : public Button { public: @@ -258,6 +502,23 @@ class ModelCategoryPageBody : public FormWindow POPUP_WARNING("Invalid File"); } }); + menu->addLine(STR_SAVE_TEMPLATE, [=]() { + storageDirty(EE_MODEL); + storageCheck(true); + constexpr size_t size = sizeof(model->modelName) + sizeof(YAML_EXT); + char modelName[size]; + snprintf(modelName, size, "%s%s", model->modelName, YAML_EXT); + char templatePath[FF_MAX_LFN]; + snprintf(templatePath, FF_MAX_LFN, "%s%c%s", PERS_TEMPL_PATH, '/', modelName); + if (isFileAvailable(templatePath)) { + new ConfirmDialog(parent, STR_FILE_EXISTS, STR_ASK_OVERWRITE, + [=] { + sdCopyFile(model->modelFilename, MODELS_PATH, modelName, PERS_TEMPL_PATH); + }); + } else { + sdCopyFile(model->modelFilename, MODELS_PATH, modelName, PERS_TEMPL_PATH); + } + }); if (model != modelslist.getCurrentModel()) { // Move if(modelslist.getCategories().size() > 1) { @@ -370,6 +631,7 @@ class ModelCategoryPageBody : public FormWindow modelslist.setCurrentModel(model); modelslist.save(); update(category->size() - 1); + new SelectTemplateFolder(); }; } }; @@ -451,7 +713,7 @@ class CategoryEditPage : public PageTab // Details char cnt[19]; - snprintf(cnt, sizeof(cnt), "%u %s", category->size(), STR_MODELS); + snprintf(cnt, sizeof(cnt), "%u %s", (unsigned)category->size(), STR_MODELS); new StaticText(window, grid.getFieldSlot(3,1), cnt); if(category->empty()) { diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index c6e628bcb..2b5a5b711 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -35,6 +35,8 @@ extern FIL g_oLogFile; #define ROOT_PATH PATH_SEPARATOR #define MODELS_PATH ROOT_PATH "MODELS" // no trailing slash = important #define RADIO_PATH ROOT_PATH "RADIO" // no trailing slash = important +#define TEMPLATES_PATH ROOT_PATH "TEMPLATES" +#define PERS_TEMPL_PATH TEMPLATES_PATH "/PERSONAL" #define LOGS_PATH ROOT_PATH "LOGS" #define SCREENSHOTS_PATH ROOT_PATH "SCREENSHOTS" #define SOUNDS_PATH ROOT_PATH "SOUNDS/en" diff --git a/radio/src/storage/sdcard_common.cpp b/radio/src/storage/sdcard_common.cpp index 595c0812d..7f1b5e8e4 100644 --- a/radio/src/storage/sdcard_common.cpp +++ b/radio/src/storage/sdcard_common.cpp @@ -29,11 +29,12 @@ // defined either in sdcard_raw.cpp or sdcard_yaml.cpp void storageCreateModelsList(); -void getModelPath(char * path, const char * filename) +void getModelPath(char * path, const char * filename, const char* pathName) { - strcpy(path, STR_MODELS_PATH); - path[sizeof(MODELS_PATH)-1] = '/'; - strcpy(&path[sizeof(MODELS_PATH)], filename); + unsigned int len = strlen(pathName); + strcpy(path, pathName); + path[len] = '/'; + strcpy(&path[len + 1], filename); } void storageEraseAll(bool warn) @@ -142,6 +143,26 @@ const char* loadModel(char* filename, bool alarms) return nullptr; } +const char* loadModelTemplate(const char* fileName, const char* filePath) +{ + preModelLoad(); + // Assuming that the template is located in current working directory + const char* error = readModel(fileName, (uint8_t*)&g_model, sizeof(g_model), filePath); + if (error) { + TRACE("loadModel error=%s", error); + // just get some clean memory state in "g_model" so the mixer can run safely + memset(&g_model, 0, sizeof(g_model)); + applyDefaultTemplate(); + + storageCheck(true); + postModelLoad(false); + return error; + } + + postModelLoad(false); + return nullptr; +} + void storageReadAll() { TRACE("storageReadAll"); diff --git a/radio/src/storage/sdcard_common.h b/radio/src/storage/sdcard_common.h index 4f74303b0..e55ab68eb 100644 --- a/radio/src/storage/sdcard_common.h +++ b/radio/src/storage/sdcard_common.h @@ -23,6 +23,7 @@ #define _SDCARD_COMMON_H_ #include "ff.h" +#include "translations.h" #define DEFAULT_CATEGORY "Models" @@ -54,10 +55,11 @@ const char *loadFileBin(const char *fullpath, uint8_t *data, struct YamlNode; const char* writeFileYaml(const char* path, const YamlNode* root_node, uint8_t* data); -void getModelPath(char * path, const char * filename); +void getModelPath(char * path, const char * filename, const char* pathName = STR_MODELS_PATH); -const char * readModel(const char * filename, uint8_t * buffer, uint32_t size); +const char * readModel(const char * filename, uint8_t * buffer, uint32_t size, const char* pathName = STR_MODELS_PATH); const char * loadModel(char * filename, bool alarms=true); +const char * loadModelTemplate(const char* fileName, const char* filePath); const char * createModel(); const char * writeModel(); diff --git a/radio/src/storage/sdcard_yaml.cpp b/radio/src/storage/sdcard_yaml.cpp index 04c7e69af..bcb1f38df 100644 --- a/radio/src/storage/sdcard_yaml.cpp +++ b/radio/src/storage/sdcard_yaml.cpp @@ -196,7 +196,7 @@ const char * writeGeneralSettings() } -const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t size) +const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t size, const char* pathName) { // YAML reader TRACE("YAML model reader"); @@ -216,7 +216,7 @@ const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t siz } char path[256]; - getModelPath(path, filename); + getModelPath(path, filename, pathName); YamlTreeWalker tree; tree.reset(data_nodes, buffer); @@ -247,14 +247,14 @@ const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t siz static const char _wrongExtentionError[] = "wrong file extension"; -const char* readModel(const char* filename, uint8_t* buffer, uint32_t size) +const char* readModel(const char* filename, uint8_t* buffer, uint32_t size, const char* pathName) { const char* ext = strrchr(filename, '.'); if (!ext || strncmp(ext, YAML_EXT, 4) != 0) { return _wrongExtentionError; } - return readModelYaml(filename, buffer, size); + return readModelYaml(filename, buffer, size, pathName); } const char * writeModelYaml(const char* filename) diff --git a/radio/src/storage/sdcard_yaml.h b/radio/src/storage/sdcard_yaml.h index 94e678a77..884cebb44 100644 --- a/radio/src/storage/sdcard_yaml.h +++ b/radio/src/storage/sdcard_yaml.h @@ -24,5 +24,5 @@ constexpr uint8_t MODELIDX_STRLEN = sizeof(MODEL_FILENAME_PREFIX "00"); const char * loadRadioSettingsYaml(); const char * writeModelYaml(const char* filename); -const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t size); +const char * readModelYaml(const char * filename, uint8_t * buffer, uint32_t size, const char* pathName = STR_MODELS_PATH); void getModelNumberStr(uint8_t idx, char* model_idx); diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 3971f0e26..827ac3b29 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -927,6 +927,12 @@ const char STR_MODELS_PATH[] = MODELS_PATH; const char STR_MODELS_EXT[] = MODELS_EXT; const char STR_BACKUP_PATH[] = BACKUP_PATH; const char STR_YAML_EXT[] = YAML_EXT; +const char STR_SELECT_TEMPLATE[] = TR_SELECT_TEMPLATE; +const char STR_SELECT_TEMPLATE_FOLDER[] = TR_SELECT_TEMPLATE_FOLDER; +const char STR_NO_TEMPLATES[] = TR_NO_TEMPLATES; +const char STR_SAVE_TEMPLATE[] = TR_SAVE_TEMPLATE; +const char STR_FILE_EXISTS[] = TR_FILE_EXISTS; +const char STR_ASK_OVERWRITE[] = TR_ASK_OVERWRITE; const char STR_TEST_WARNING[] = TR_TEST_WARNING; const char STR_TEST_NOTSAFE[] = TR_TEST_NOTSAFE; diff --git a/radio/src/translations.h b/radio/src/translations.h index 7ff46b3e8..6e503bef9 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -608,6 +608,12 @@ extern const char STR_MODELS_PATH[]; extern const char STR_MODELS_EXT[]; extern const char STR_BACKUP_PATH[]; extern const char STR_YAML_EXT[]; +extern const char STR_SELECT_TEMPLATE[]; +extern const char STR_SELECT_TEMPLATE_FOLDER[]; +extern const char STR_NO_TEMPLATES[]; +extern const char STR_SAVE_TEMPLATE[]; +extern const char STR_FILE_EXISTS[]; +extern const char STR_ASK_OVERWRITE[]; #define STR_UPDATE_LIST STR_DELAYDOWN extern const char STR_NEEDS_FILE[]; diff --git a/radio/src/translations/cn.h.txt b/radio/src/translations/cn.h.txt index a07141fcc..3b8fc2a80 100644 --- a/radio/src/translations/cn.h.txt +++ b/radio/src/translations/cn.h.txt @@ -780,6 +780,12 @@ #define TR_BAUDRATE "蓝牙带宽" #define LEN_BLUETOOTH_MODES "\004" #define TR_BLUETOOTH_MODES "---\0" "回传" "教练" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_SD_INFO_TITLE "存储卡详情" #define TR_SD_TYPE "类型:" diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index fd62d2ed3..f4e61b19e 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -812,9 +812,14 @@ #define TR_TIME "Čas" #define TR_MAXBAUDRATE "Max baudů" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Hledat" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 5c69d6f1f..48da96486 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -814,9 +814,14 @@ #define TR_TIME "Uhrzeit:" #define TR_MAXBAUDRATE "Max Baud" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 8dbc22fda..448dcb839 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -818,9 +818,14 @@ #define TR_TIME "Time" #define TR_MAXBAUDRATE "Max bauds" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index f54a1d7c8..f23165c55 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -815,10 +815,15 @@ #define TR_TEMP_CALIB "Temp. Calib" #define TR_TIME "Hora" #define TR_MAXBAUDRATE "Máx bauds" - #define TR_SAMPLE_MODE "Modo de muestra" #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Buscar" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 8a0747d77..d5633a666 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -830,9 +830,14 @@ #define TR_TIME "Time" #define TR_MAXBAUDRATE "Max bauds" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index e6dc126b5..851db73bd 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -835,9 +835,14 @@ #define TR_TIME "Heure" #define TR_MAXBAUDRATE "Max bauds" #define TR_SAMPLE_MODE "Sample Mode" - -#define LEN_SAMPLE_MODES "\006" +#define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Découvrir" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index a6c3fd8df..714c767c0 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -836,9 +836,14 @@ #define TR_TIME "Ora" #define TR_MAXBAUDRATE "Max Bauds" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Cerca" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 68e8547d3..694a3c4d0 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -822,9 +822,14 @@ #define TR_TIME "Tijd:" #define TR_MAXBAUDRATE "Max bauds" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 5177c08a2..9de0361bc 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -833,9 +833,14 @@ #define TR_TIME "Czas" #define TR_MAXBAUDRATE "Max bauds" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 0f3d6a5ae..c053a3deb 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -841,9 +841,14 @@ #define TR_TIME "Time" #define TR_MAXBAUDRATE "Max bauds" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 9743d9700..c99bdae07 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -841,9 +841,14 @@ #define TR_TIME "Tid " #define TR_MAXBAUDRATE "Max bauds" #define TR_SAMPLE_MODE "Sample Mode" - #define LEN_SAMPLE_MODES "\006" #define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" diff --git a/radio/src/translations/tw.h.txt b/radio/src/translations/tw.h.txt index 5e2bd9756..b3733247b 100644 --- a/radio/src/translations/tw.h.txt +++ b/radio/src/translations/tw.h.txt @@ -768,9 +768,16 @@ #define TR_TEMP_CALIB "溫度校準" #define TR_TIME "時間" #define TR_MAXBAUDRATE "最大帶寬" -#define TR_SAMPLE_MODE "Sample Mode" +#define TR_SAMPLE_MODE "Sample Mode" #define LEN_SAMPLE_MODES "\006" -#define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SAMPLE_MODES "Normal""OneBit" +#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" +#define TR_SELECT_TEMPLATE "SELECT A MODEL TEMPLATE:" +#define TR_NO_TEMPLATES "No model templates were found in this folder" +#define TR_SAVE_TEMPLATE "Save as template" +#define TR_FILE_EXISTS "FILE ALREADY EXISTS" +#define TR_ASK_OVERWRITE "Do you want to overwrite?" + #define TR_BLUETOOTH "藍牙" #define TR_BLUETOOTH_DISC "發現" #define TR_BLUETOOTH_INIT "初始化"