feat: Model templates for color radios (update SD card for bundled templates) (#1569)
* Model templates - select and load after Create Model for color radios * Model templates - save model as template, only for color radios * Small fix to drawTextLines(...) to handle consecutive spaces * Change title of button for empty template folder * I found out why "no trailing slash = important" in path names! * Reworked file and path name string manipulation No longer using chdir, as Lua scripts etc. could be messing with the working dir Use buffers more and std::string less * Adjusting the size of buffers I think that I got it right now. Really hard to figure out the right size constants! Also added storageDirty(EE_MODEL) after reading the template file and renaming the model * Added storage checks * Slight simplification - all template buttons are similar * Added "Blank Model" button * Wizard Lua script If there is a Lua script with the same name as the template file in the folder, then it is run after reading the template.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<uint8_t(void)> 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<std::string> 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<std::string> 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()) {
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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 "类型:"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 "初始化"
|
||||
|
||||
Reference in New Issue
Block a user