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:
Jesper Frickmann
2022-03-09 11:00:38 +10:00
committed by GitHub
parent e0e196a6e6
commit dcc5cfb352
22 changed files with 399 additions and 32 deletions
+1 -1
View File
@@ -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;
+268 -6
View File
@@ -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()) {
+2
View File
@@ -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"
+25 -4
View File
@@ -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");
+4 -2
View File
@@ -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();
+4 -4
View File
@@ -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)
+1 -1
View File
@@ -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);
+6
View File
@@ -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;
+6
View File
@@ -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[];
+6
View 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 "类型:"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+7 -2
View File
@@ -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"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+6 -1
View File
@@ -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"
+9 -2
View File
@@ -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 "初始化"