feat(color): New label based Model Selector (#1374)

* Model Labels Selector

* Portrait Layout

* Receiver ID Check

* Fix Labels .yml format

* Companion Initial Commit

commit 967ddf3979b4954402fe62c858faba4b7a416bba
Author: dlktdr <cblackburn320@gmail.com>
Date:   Mon Aug 29 01:49:15 2022 -0700

    Fix Labels .yml format

commit 534221cad9e01146c47a9ac1080a655e04f1f6c8
Author: dlktdr <cblackburn320@gmail.com>
Date:   Mon Aug 29 01:20:57 2022 -0700

    Receiver ID Check

commit f32c0939d44e9ae60bc0705a9176354c23fec198
Author: dlktdr <cblackburn320@gmail.com>
Date:   Sun Aug 28 23:13:25 2022 -0700

    Portrait Layout

commit 961181217c7841ff3f21299ac6aa419b810f80e9
Author: dlktdr <cblackburn320@gmail.com>
Date:   Sat Dec 11 16:56:13 2021 -0800

    Model Labels Selector

commit dc99dd40d2
Author: David PHAM-VAN <1387855+DavBfr@users.noreply.github.com>
Date:   Fri Aug 26 03:04:34 2022 -0300

    feat: Allow Lua widget to override built-in widget with same name (#2208)

    * Allow CPP Widgets Override with LUA

    * Reset a widget option it the type differs

commit 4b747caff9
Author: eshifri <46511024+eshifri@users.noreply.github.com>
Date:   Thu Aug 25 19:47:53 2022 -0700

    fix: Write model name into models.yml when duplicating model (#2224)

    * Update model name in the models.yml file (#2214)

    * Fix the length of the name.

commit e97f23a305
Author: eshifri <46511024+eshifri@users.noreply.github.com>
Date:   Wed Aug 24 21:19:52 2022 -0700

    fix(cpn): Fix full path to model notes for Simulator (#2223)

* Correct Highlighted Column

* labels .yml indentation

* Update da.h

New defines translated to Danish

* Update dataconstants.h

Omit warnings due to difference of LEN_MODEL_FILENAME and LEN_MODEL_NAME in modellist.cpp

* Update modelslist.cpp

Wonder if this are the right file in PR #1374 (?), seems a lot are changed to the better in #1374

* Update dataconstants.h

Restore #define for LEN_MODEL_FILENAME to 16

* Rebase, Correct Issues

Delete now deletes instead of select
New model stores correct information
Duplicate save all information in cell
Rework items to use cell over button
Reword function variables

* CMPN: Add context menu

Fix output not functional. Removed Yaml::null at some point :)
Fix some compiler warnings

* CMPN: Compiler warning, replace ,->_ in list

* FW: Various Changes

Change view to a grid
Don't allow comma in label name
Add scroll indicators
Save sort order

Co-authored-by: HThuren <99370924+HThuren@users.noreply.github.com>
This commit is contained in:
Cliff
2022-09-03 09:01:19 +10:00
committed by GitHub
co-authored by HThuren
parent 20dc9c4d26
commit c8693569b0
85 changed files with 4006 additions and 2067 deletions
+38 -33
View File
@@ -46,6 +46,7 @@ option(TRACE_SIMPGMSPACE "Turn on traces in simpgmspace.cpp" ON)
option(TRACE_LUA_INTERNALS "Turn on traces for Lua internals" OFF)
option(DEBUG_WINDOWS "Turn on windows traces" OFF)
option(DEBUG_YAML "Turn on YAML traces" OFF)
option(DEBUG_LABELS "Turn on Labels traces" OFF)
option(FRSKY_STICKS "Reverse sticks for FrSky sticks" OFF)
option(NANO "Use nano newlib and binalloc")
option(TEST_BUILD_WARNING "Warn this is a test build" OFF)
@@ -210,11 +211,11 @@ if(LUA)
if(LUA_MIXER)
add_definitions(-DLUA_MODEL_SCRIPTS)
endif()
# TODO: LUA CMAKE
set(SRC ${SRC}
lua/interface.cpp
lua/api_general.cpp
set(SRC ${SRC}
lua/interface.cpp
lua/api_general.cpp
lua/api_model.cpp
lua/api_filesystem.cpp
lua/lua_event.cpp
@@ -226,37 +227,37 @@ if(LUA)
set(SRC ${SRC} lua/api_stdlcd.cpp)
endif()
set(LUA_SRC
lapi.c
lcode.c
lctype.c
ldebug.c
ldo.c
ldump.c
lfunc.c
lgc.c
llex.c
lmem.c
lobject.c
lopcodes.c
set(LUA_SRC
lapi.c
lcode.c
lctype.c
ldebug.c
ldo.c
ldump.c
lfunc.c
lgc.c
llex.c
lmem.c
lobject.c
lopcodes.c
lparser.c
lstate.c
lstring.c
ltable.c
lrotable.c
ltm.c
lundump.c
lvm.c
lzio.c
lstate.c
lstring.c
ltable.c
lrotable.c
ltm.c
lundump.c
lvm.c
lzio.c
linit.c
lbaselib.c
lmathlib.c
lbitlib.c
loadlib.c
lauxlib.c
ltablib.c
lcorolib.c
liolib.c
lbaselib.c
lmathlib.c
lbitlib.c
loadlib.c
lauxlib.c
ltablib.c
lcorolib.c
liolib.c
lstrlib.c
)
@@ -393,6 +394,10 @@ if(DEBUG_YAML)
add_definitions(-DDEBUG_YAML)
endif()
if(DEBUG_LABELS)
add_definitions(-DDEBUG_LABELS)
endif()
if(FRSKY_STICKS)
add_definitions(-DFRSKY_STICKS)
endif()
Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 B

+3
View File
@@ -37,6 +37,9 @@
#define LUA_EXPORT_EXTRA(...)
#endif
#define LABELS_LENGTH 100 // Maximum length of the label string
#define LABEL_LENGTH 20 // Maximum length of a single label
#if defined(PCBHORUS) || defined(PCBNV14)
#define MAX_MODELS 60
#define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32
+4 -4
View File
@@ -83,7 +83,7 @@ static inline void check_struct()
CHKSIZE(FlightModeData, 44);
CHKSIZE(TimerData, 17);
CHKSIZE(SwashRingData, 8);
CHKSIZE(ModelHeader, 31);
CHKSIZE(ModelHeader, 131);
CHKSIZE(CurveHeader, 4);
CHKSIZE(CustomScreenData, 850);
CHKTYPE(TopBarPersistentData, 300);
@@ -137,14 +137,14 @@ static inline void check_struct()
#elif defined(PCBHORUS)
#if defined(PCBX10)
CHKSIZE(RadioData, 924);
CHKSIZE(ModelData, 11028);
CHKSIZE(ModelData, 11128);
#else
CHKSIZE(RadioData, 906);
CHKSIZE(ModelData, 11026);
CHKSIZE(ModelData, 11126);
#endif
#elif defined(PCBNV14)
CHKSIZE(RadioData, 852);
CHKSIZE(ModelData, 10842);
CHKSIZE(ModelData, 10942);
#endif
#undef CHKSIZE
+3
View File
@@ -550,6 +550,9 @@ PACK(struct ModelHeader {
char name[LEN_MODEL_NAME]; // must be first for eeLoadModelName
uint8_t modelId[NUM_MODULES];
MODEL_HEADER_BITMAP_FIELD
#if defined(STORAGE_MODELSLIST)
char labels[LABELS_LENGTH];
#endif
});
#if defined(COLORLCD)
+1
View File
@@ -389,6 +389,7 @@ enum DebugTimers {
debugTimerAudioIterval,
debugTimerAudioDuration,
debugTimerAudioConsume,
debugTimerYamlScan,
DEBUG_TIMERS_COUNT
};
+1
View File
@@ -67,6 +67,7 @@ set(GUI_SRC
model_outputs.cpp
model_curves.cpp
model_gvars.cpp
model_templates.cpp
model_logical_switches.cpp
special_functions.cpp
model_telemetry.cpp
+1 -1
View File
@@ -595,8 +595,8 @@ void drawTextLines(BitmapBuffer * dc, coord_t left, coord_t top, coord_t width,
case '(':
case '{':
case '[':
case ' ':
nxt++;
case ' ':
case '\n':
case '\0':
done = true;
+41 -2
View File
@@ -107,6 +107,18 @@ void ListBase::setSelected(int selected)
select(selected, 0);
}
void ListBase::setSelected(std::set<uint32_t> selected)
{
if(!multiSelect) return;
for(int i=0; i < getRowCount(); i++) {
if(selected.find(i) != selected.end())
lv_table_add_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
else
lv_table_clear_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
}
}
int ListBase::getSelected() const
{
uint16_t row, col;
@@ -115,6 +127,17 @@ int ListBase::getSelected() const
return -1;
}
std::set<uint32_t> ListBase::getSelection()
{
if(!multiSelect) return std::set<uint32_t>();
std::set<uint32_t> selectedIndexes;
for(int i=0; i < getRowCount(); i++) {
if(lv_table_has_cell_ctrl(lvobj, i, 0, LV_TABLE_CELL_CTRL_CUSTOM_1))
selectedIndexes.insert(i);
}
return selectedIndexes;
}
void ListBase::setActiveItem(int item)
{
if (item != activeItem) {
@@ -133,7 +156,20 @@ void ListBase::onPress(uint16_t row, uint16_t col)
if (row == LV_TABLE_CELL_NONE) return;
TRACE("SHORT_PRESS");
if (pressHandler) { pressHandler(); }
if(multiSelect && row < getRowCount()) {
std::set<uint32_t> lastSelection = getSelection();
bool chk = lv_table_has_cell_ctrl(lvobj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
if(chk) lv_table_clear_cell_ctrl(lvobj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
else lv_table_add_cell_ctrl(lvobj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1);
if(_multiSelectHandler) {
_multiSelectHandler(getSelection(),lastSelection);
}
} else {
if (pressHandler) { pressHandler(); }
}
}
void ListBase::onLongPressed()
@@ -147,6 +183,7 @@ void ListBase::onClicked()
{
if (!getAutoEdit()) {
lv_group_set_editing((lv_group_t*)lv_obj_get_group(lvobj), true);
} else {
TableField::onClicked();
}
@@ -164,7 +201,9 @@ void ListBase::onCancel()
void ListBase::onDrawEnd(uint16_t row, uint16_t col, lv_obj_draw_part_dsc_t* dsc)
{
if (row != activeItem) return;
if ((multiSelect == false && row != activeItem) ||
(multiSelect == true && !lv_table_has_cell_ctrl(lvobj, dsc->id, 0, LV_TABLE_CELL_CTRL_CUSTOM_1)))
return;
lv_area_t coords;
lv_coord_t area_h = lv_area_get_height(dsc->draw_area);
+15 -1
View File
@@ -35,6 +35,7 @@ class ListBase : public TableField
{
std::function<void()> longPressHandler = nullptr;
std::function<void()> pressHandler = nullptr;
std::function<void(std::set<uint32_t>, std::set<uint32_t>)> _multiSelectHandler = nullptr;
bool autoEdit = false;
public:
@@ -49,11 +50,23 @@ class ListBase : public TableField
void setLineHeight(uint8_t height);
virtual void setSelected(int selected);
virtual void setSelected(std::set<uint32_t> selected);
int getSelected() const;
std::set<uint32_t> getSelection();
void setMultiSelect(bool mode) {
multiSelect = mode;
}
virtual void setActiveItem(int item);
int getActiveItem() const;
void setMultiSelectHandler(std::function<void(std::set<uint32_t>, std::set<uint32_t>)> handler)
{
_multiSelectHandler = std::move(handler);
}
void setLongPressHandler(std::function<void()> handler)
{
longPressHandler = std::move(handler);
@@ -71,6 +84,7 @@ class ListBase : public TableField
protected:
static void event_cb(lv_event_t* e);
int activeItem = -1;
bool multiSelect = false;
void onPress(uint16_t row, uint16_t col) override;
void onLongPressed();
File diff suppressed because it is too large Load Diff
+93 -5
View File
@@ -22,12 +22,100 @@
#ifndef _MODEL_SELECT_H_
#define _MODEL_SELECT_H_
#include <algorithm>
#include <functional>
#include "libopenui.h"
#include "listbox.h"
#include "storage/modelslist.h"
#include "tabsgroup.h"
class ModelSelectMenu: public TabsGroup {
public:
ModelSelectMenu();
void build(int index=-1);
constexpr int MAX_LABEL_SIZE = 20;
class ModelButton;
class ModelsPageBody : public FormWindow
{
public:
ModelsPageBody(Window *parent, const rect_t &rect);
void setLabels(LabelsVector labels)
{
selectedLabels = labels;
update();
}
void update(int selected = -1);
inline void setSortOrder(ModelsSortBy sortOrder)
{
modelslabels.setSortOrder(sortOrder);
update();
}
void setLblRefreshFunc(std::function<void()> fnc)
{
refreshLabels = std::move(fnc);
}
protected:
ModelsSortBy _sortOrder;
bool isDirty = false;
bool refresh = false;
std::string selectedLabel;
LabelsVector selectedLabels;
std::function<void()> refreshLabels = nullptr;
void selectModel(ModelCell* model);
void duplicateModel(ModelCell* model);
void deleteModel(ModelCell* model);
void editLabels(ModelCell* model);
};
#endif // _MODEL_SELECT_H_
class ModelLabelsWindow : public Page
{
public:
ModelLabelsWindow();
protected:
ModelsSortBy sort = DEFAULT_MODEL_SORT;
char tmpLabel[MAX_LABEL_SIZE + 1] = "\0";
ListBox *lblselector;
ModelsPageBody *mdlselector;
std::string currentLabel;
LabelsVector getLabels()
{
auto labels = modelslabels.getLabels();
if (modelslabels.getUnlabeledModels().size() > 0)
labels.emplace_back(STR_UNLABELEDMODEL);
return labels;
}
void newModel();
void buildHead(PageHeader *window);
void buildBody(FormWindow *window);
void updateFilteredLabels(std::set<uint32_t> selected, bool setdirty = true);
void labelRefreshRequest();
};
class ProgressDialog : public Dialog
{
uint32_t lastUpdate = 0;
Progress *progress;
std::function<void()> onClose;
public:
ProgressDialog(Window *parent, std::string title,
std::function<void()> onClose);
void updateProgress(const char *filename, int percentage);
// disable keys
void onEvent(event_t) override;
protected:
std::string _title;
};
#endif // _MODEL_SELECT_H_
+25 -2
View File
@@ -45,11 +45,9 @@ ModelSetupPage::ModelSetupPage() :
static void onModelNameChanged()
{
modelslist.load();
auto model = modelslist.getCurrentModel();
if (model) {
model->setModelName(g_model.header.name);
modelslist.save();
}
SET_DIRTY();
}
@@ -233,6 +231,31 @@ void ModelSetupPage::build(FormWindow * window)
new StaticText(line, rect_t{}, STR_MODELNAME, 0, COLOR_THEME_PRIMARY1);
new ModelNameEdit(line, rect_t{});
// Model labels
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_LABELS, 0, COLOR_THEME_PRIMARY1);
auto curmod = modelslist.getCurrentModel();
labelTextButton =
new TextButton(line, rect_t{}, modelslabels.getLabelString(curmod ,STR_UNLABELEDMODEL), [=] () {
Menu *menu = new Menu(window, true);
menu->setTitle(STR_LABELS);
for (auto &label: modelslabels.getLabels()) {
menu->addLine(label,
[=] () {
if (!modelslabels.isLabelSelected(label, curmod))
modelslabels.addLabelToModel(label, curmod);
else
modelslabels.removeLabelFromModel(label, curmod);
labelTextButton->setText(modelslabels.getLabelString(curmod,STR_UNLABELEDMODEL));
strcpy(g_model.header.labels, modelslabels.getLabelString(curmod,STR_UNLABELEDMODEL).c_str());
SET_DIRTY();
}, [=] () {
return modelslabels.isLabelSelected(label, curmod);
});
}
return 0;
});
// Bitmap
line = window->newLine(&grid);
new StaticText(line, rect_t{}, STR_BITMAP, 0, COLOR_THEME_PRIMARY1);
+2
View File
@@ -26,4 +26,6 @@ class ModelSetupPage: public PageTab {
ModelSetupPage();
void build(FormWindow * window) override;
private:
TextButton *labelTextButton = nullptr;
};
+260
View File
@@ -0,0 +1,260 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "model_templates.h"
#include "standalone_lua.h"
#include "str_functions.h"
char TemplatePage::path[LEN_PATH + 1];
std::function<void(void)> TemplatePage::update = nullptr;
void TemplatePage::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 TemplatePage::onEvent(event_t event)
{
if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
killEvents(event);
deleteLater();
} else {
Page::onEvent(event);
}
}
#endif
void TemplatePage::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);
}
}
SelectTemplate::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);
// Dismiss template pages
deleteLater();
templateFolderPage->deleteLater();
#if defined(LUA)
// 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);
// Need to update() the ModelCategoryPageBody before attaching StandaloneLuaWindow to not mess up focus
update();
update = nullptr;
StandaloneLuaWindow::instance()->attach();
}
#endif
return 0;
});
tb->setFocusHandler([=](bool active) {
if (active) {
snprintf(buffer, LEN_BUFFER, "%s%c%s%s", path, '/', name.c_str(), TEXT_EXT);
updateInfo();
}
});
tb->setHeight(PAGE_LINE_HEIGHT * 2);
grid.spacer(tb->height() + 5);
}
}
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);
#if LCD_W > LCD_H
rect.h = PAGE_LINE_HEIGHT;
int charBreak = 60;
#else
rect.h = PAGE_LINE_HEIGHT * 2;
int charBreak = 40;
#endif
new StaticText(&body, rect, wrap(STR_NO_TEMPLATES, charBreak), 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 * 2);
rect.w = 100;
rect.h = PAGE_LINE_HEIGHT * 2;
new TextButton(&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();
}
}
SelectTemplateFolder::SelectTemplateFolder(std::function<void(void)> update)
{
TemplatePage::update = update;
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(), STR_BLANK_MODEL, [=]() -> uint8_t {
deleteLater();
return 0;
});
snprintf(infoText, LEN_INFO_TEXT, "%s", STR_BLANK_MODEL_INFO);
tfb->setFocusHandler([=](bool active) {
if (active) {
snprintf(infoText, LEN_INFO_TEXT, "%s", STR_BLANK_MODEL_INFO);
invalidate();
}
});
tfb->setHeight(PAGE_LINE_HEIGHT * 2);
grid.spacer(tfb->height() + 5);
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) {
#if not defined(LUA)
// Don't show wizards dir if no lua
if (!strcasecmp(name.c_str(), "WIZARD") == 0) {
#endif
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();
}
});
tfb->setHeight(PAGE_LINE_HEIGHT * 2);
grid.spacer(tfb->height() + 5);
}
#if not defined(LUA)
}
#endif
}
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);
}
}
SelectTemplateFolder::~SelectTemplateFolder()
{
if (update)
update();
}
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#pragma once
#include <functional>
#include "opentx.h"
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;
class TemplatePage : public Page
{
public:
TemplatePage() : Page(ICON_MODEL_SELECT)
{ }
void updateInfo();
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#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;
static std::function<void(void)> update;
void paint(BitmapBuffer *dc) override;
};
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);
protected:
TemplatePage* templateFolderPage;
};
class SelectTemplateFolder : public TemplatePage
{
public:
SelectTemplateFolder(std::function<void(void)> update);
~SelectTemplateFolder();
};
+39 -7
View File
@@ -31,6 +31,7 @@
#include "custom_failsafe.h"
#include "ppm_settings.h"
#include "channel_range.h"
#include "storage/modelslist.h"
#if defined(PXX2)
#include "access_settings.h"
@@ -70,7 +71,7 @@ class ModuleWindow : public FormGroup
void updateSubType();
uint8_t getModuleIdx() const { return moduleIdx; }
protected:
uint8_t moduleIdx;
@@ -82,8 +83,11 @@ class ModuleWindow : public FormGroup
TextButton *registerButton = nullptr;
Window *fsLine = nullptr;
Choice *rfPower = nullptr;
StaticText *idUnique = nullptr;
void startRSSIDialog(std::function<void()> closeHandler = nullptr);
void updateIDStaticText(int mdIdx);
};
struct FailsafeChoice : public FormGroup {
@@ -138,6 +142,22 @@ ModuleWindow::ModuleWindow(Window* parent, uint8_t moduleIdx) :
updateModule();
}
void ModuleWindow::updateIDStaticText(int mdIdx)
{
if(idUnique == nullptr)
return;
char buffer[50];
std::string idStr = STR_MODELIDUNIQUE;
if(!modelslist.isModelIdUnique(mdIdx, buffer, sizeof(buffer))) {
idStr = STR_MODELIDUSED;
idStr = idStr + buffer;
idUnique->setTextFlags(COLOR_THEME_WARNING);
} else {
idUnique->setTextFlags(COLOR_THEME_PRIMARY1);
}
idUnique->setText(idStr);
}
void ModuleWindow::updateModule()
{
FlexGridLayout grid(col_dsc, row_dsc, 2);
@@ -194,6 +214,15 @@ void ModuleWindow::updateModule()
// Bind and Range buttons
if (!isModuleRFAccess(moduleIdx) && (isModuleModelIndexAvailable(moduleIdx) ||
isModuleBindRangeAvailable(moduleIdx))) {
// Is Reciever ID Unique
if(isModuleModelIndexAvailable(moduleIdx)) {
auto line = newLine(&grid);
new StaticText(line, rect_t{},"");
auto box = new FormGroup(line, rect_t{});
box->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(8));
idUnique = new StaticText(box, rect_t{}, "", 0, 0);
updateIDStaticText(moduleIdx);
}
auto line = newLine(&grid);
new StaticText(line, rect_t{}, STR_RECEIVER, 0, COLOR_THEME_PRIMARY1);
@@ -207,6 +236,8 @@ void ModuleWindow::updateModule()
GET_DEFAULT(*modelId), [=](int32_t newValue) {
if (newValue != *modelId) {
*modelId = newValue;
modelslist.updateCurrentModelCell();
updateIDStaticText(moduleIdx);
#if defined(CROSSFIRE)
if (isModuleCrossfire(moduleIdx)) {
moduleState[moduleIdx].counter =
@@ -217,6 +248,7 @@ void ModuleWindow::updateModule()
}
});
if (isModuleBindRangeAvailable(moduleIdx)) {
bindButton = new TextButton(box, rect_t{},STR_MODULE_BIND);
bindButton->setPressHandler([=]() -> uint8_t {
@@ -303,7 +335,7 @@ void ModuleWindow::updateModule()
#if defined(PXX2)
else if (isModuleRFAccess(moduleIdx)) {
// Register and Range buttons
// Register and Range buttons
auto line = newLine(&grid);
new StaticText(line, rect_t{}, STR_MODULE, 0, COLOR_THEME_PRIMARY1);
@@ -517,7 +549,7 @@ void ModuleSubTypeChoice::update()
setValues(STR_R9M_REGION);
setGetValueHandler(GET_DEFAULT(md->subType));
setSetValueHandler(SET_DEFAULT(md->subType));
setAvailableHandler(nullptr);
setAvailableHandler(nullptr);
}
#if defined(PXX2)
else if (isModulePXX2(moduleIdx)) {
@@ -526,7 +558,7 @@ void ModuleSubTypeChoice::update()
setValues(STR_ISRM_RF_PROTOCOLS);
setGetValueHandler(GET_DEFAULT(md->subType));
setSetValueHandler(SET_DEFAULT(md->subType));
setAvailableHandler(nullptr);
setAvailableHandler(nullptr);
}
#endif
#if defined(AFHDS2) || defined(AFHDS3)
@@ -590,9 +622,9 @@ void ModuleSubTypeChoice::update()
lv_obj_add_flag(lvobj, LV_OBJ_FLAG_HIDDEN);
return;
}
lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_HIDDEN);
// update choice value
lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr);
}
@@ -669,7 +701,7 @@ ModulePage::ModulePage(uint8_t moduleIdx) : Page(ICON_MODEL_SETUP)
: isExternalModuleAvailable(moduleType);
});
auto subTypeChoice = new ModuleSubTypeChoice(box, moduleIdx);
auto subTypeChoice = new ModuleSubTypeChoice(box, moduleIdx);
auto moduleWindow = new ModuleWindow(form, moduleIdx);
// This needs to be after moduleWindow has been created
+1 -1
View File
@@ -240,7 +240,7 @@ void ViewMain::onEvent(event_t event)
break;
case EVT_KEY_LONG(KEY_MODEL):
new ModelSelectMenu();
new ModelLabelsWindow();
break;
// TODO:
+1 -1
View File
@@ -46,7 +46,7 @@ ViewMainMenu::ViewMainMenu(Window* parent) :
auto carousel = new SelectFabCarousel(this);
carousel->addButton(ICON_MODEL_SELECT, STR_MAIN_MENU_SELECT_MODEL, [=]() -> uint8_t {
deleteLater();
new ModelSelectMenu();
new ModelLabelsWindow();
return 0;
});
+1
View File
@@ -284,5 +284,6 @@ PACK(union u_int8int16_t {
constexpr uint8_t EE_GENERAL = 0x01;
constexpr uint8_t EE_MODEL = 0x02;
constexpr uint8_t EE_LABELS = 0x04;
#endif // _MYEEPROM_H_
+6 -2
View File
@@ -34,6 +34,7 @@ extern FIL g_oLogFile;
#define PATH_SEPARATOR "/"
#define ROOT_PATH PATH_SEPARATOR
#define MODELS_PATH ROOT_PATH "MODELS" // no trailing slash = important
#define DELETED_MODELS_PATH MODELS_PATH PATH_SEPARATOR "DELETED"
#define RADIO_PATH ROOT_PATH "RADIO" // no trailing slash = important
#define TEMPLATES_PATH ROOT_PATH "TEMPLATES"
#define PERS_TEMPL_PATH TEMPLATES_PATH "/PERSONAL"
@@ -65,8 +66,11 @@ extern FIL g_oLogFile;
const char RADIO_MODELSLIST_PATH[] = RADIO_PATH PATH_SEPARATOR "models.txt";
const char RADIO_SETTINGS_PATH[] = RADIO_PATH PATH_SEPARATOR RADIO_FILENAME;
#if defined(SDCARD_YAML)
const char MODELSLIST_YAML_PATH[] = MODELS_PATH PATH_SEPARATOR "models.yml";
const char FALLBACK_MODELSLIST_YAML_PATH[] = RADIO_PATH PATH_SEPARATOR "models.yml";
#define LABELS_FILENAME "labels.yml"
#define MODELS_FILENAME "models.yml"
const char MODELSLIST_YAML_PATH[] = MODELS_PATH PATH_SEPARATOR MODELS_FILENAME;
const char FALLBACK_MODELSLIST_YAML_PATH[] = RADIO_PATH PATH_SEPARATOR MODELS_FILENAME;
const char LABELSLIST_YAML_PATH[] = MODELS_PATH PATH_SEPARATOR LABELS_FILENAME;
const char RADIO_SETTINGS_YAML_PATH[] = RADIO_PATH PATH_SEPARATOR "radio.yml";
const char RADIO_SETTINGS_TMPFILE_YAML_PATH[] = RADIO_PATH PATH_SEPARATOR "radio_new.yml";
const char RADIO_SETTINGS_ERRORFILE_YAML_PATH[] = RADIO_PATH PATH_SEPARATOR "radio_error.yml";
+22 -41
View File
@@ -105,56 +105,37 @@ void convertBinRadioData(const char * path, int version)
#endif
const char* error = nullptr;
for (auto category_ptr : modelslist.getCategories()) {
for(auto model_it = modelslist.begin(); model_it != modelslist.end(); ++model_it) {
uint8_t model_version = 0;
auto* model_ptr = *model_it;
char* filename = model_ptr->modelFilename;
auto model_it = category_ptr->begin();
TRACE("converting '%s' (%d/%d)", filename, converted, to_convert);
drawProgressScreen(filename, converted, to_convert);
while(model_it != category_ptr->end()) {
// read only the version number (size=0)
error = readModelBin(filename, nullptr, 0, &model_version);
if (!error) {
// TODO: error handling
error = convertBinModelData(filename, model_version);
uint8_t model_version = 0;
auto* model_ptr = *model_it;
char* filename = model_ptr->modelFilename;
TRACE("converting '%s' (%d/%d)", filename, converted, to_convert);
drawProgressScreen(filename, converted, to_convert);
// read only the version number (size=0)
error = readModelBin(filename, nullptr, 0, &model_version);
if (!error) {
// TODO: error handling
error = convertBinModelData(filename, model_version);
++model_it;
if (error) {
TRACE("ERROR converting '%s': %s", filename, error);
category_ptr->removeModel(model_ptr);
} else {
PartialModel partial;
memclear(&partial, sizeof(PartialModel));
readModelYaml(filename, reinterpret_cast<uint8_t*>(&partial), sizeof(partial));
model_ptr->setModelName(partial.header.name);
}
} else {
TRACE("ERROR reading '%s': %s", filename, error);
// remove that file from the models list
++model_it;
category_ptr->removeModel(model_ptr);
if (error) {
TRACE("ERROR converting '%s': %s", filename, error);
}
} else {
TRACE("ERROR reading '%s': %s", filename, error);
}
converted++;
converted++;
#if defined(SIMU)
RTOS_WAIT_MS(200);
RTOS_WAIT_MS(200);
#endif
}
}
#if defined(SDCARD_YAML) || defined(STORAGE_MODELSLIST)
modelslist.save();
// trigger models list reload
modelslist.clear();
modelslist.load();
#endif
}
@@ -179,7 +160,7 @@ const char* convertBinModelData(char* filename, int version)
memcpy(path, MODELS_PATH, sizeof(MODELS_PATH)-1);
path[sizeof(MODELS_PATH)-1] = '/';
strcpy(&path[sizeof(MODELS_PATH)], filename);
#if STORAGE_CONVERSIONS < 220
if (version == 219) {
const char* error = convertModelData_219_to_220(path);
@@ -206,7 +187,7 @@ const char* convertBinModelData(char* filename, int version)
void eeConvertModel(int id, int version)
{
TRACE("eeConvertModel(%d,%d)", id, version);
#if STORAGE_CONVERSIONS < 220
if (version == 219) {
convertModelData_219_to_220(id);
@@ -269,7 +250,7 @@ bool eeConvert(uint8_t start_version)
#if defined(STORAGE_MODELSLIST)
modelslist.clear();
#endif
#if LCD_W >= 212
lcdDrawRect(60, 6*FH+4, 132, 3);
#else
File diff suppressed because it is too large Load Diff
+172 -88
View File
@@ -23,86 +23,189 @@
#define _MODELSLIST_H_
#include <stdint.h>
#include <algorithm>
#include <functional>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "sdcard.h"
#if !defined(SDCARD_YAML)
#include "sdcard_raw.h"
#endif
#include "dataconstants.h"
// #define MODELCELL_WIDTH 172
// #define MODELCELL_HEIGHT 59
#include "rtc.h"
// modelXXXXXXX.bin F,FF F,3F,FF\r\n
#define LEN_MODELS_IDX_LINE (LEN_MODEL_FILENAME + sizeof(" F,FF F,3F,FF\r\n")-1)
#define LEN_MODELS_IDX_LINE \
(LEN_MODEL_FILENAME + sizeof(" F,FF F,3F,FF\r\n") - 1)
#define DEFAULT_MODEL_SORT NAME_ASC
struct ModelData;
struct ModuleData;
struct SimpleModuleData
{
uint8_t type;
uint8_t subType;
struct SimpleModuleData {
uint8_t type = 0;
uint8_t subType = 0;
};
typedef struct PACKED {
FSIZE_t fsize; /* File size */
WORD fdate; /* Modified date */
WORD ftime; /* Modified time */
} FInfoH;
#define FILE_HASH_LENGTH (sizeof(FInfoH) * 2) // Hex string output
class ModelCell
{
public:
char modelFilename[LEN_MODEL_FILENAME + 1];
char modelName[LEN_MODEL_NAME + 1] = {};
public:
char modelFilename[LEN_MODEL_FILENAME + 1] = "";
char modelName[LEN_MODEL_NAME + 1] = "";
char modelFinfoHash[FILE_HASH_LENGTH + 1] = "";
#if LEN_BITMAP_NAME > 0
char modelBitmap[LEN_BITMAP_NAME] = "";
#endif
gtime_t lastOpened = 0;
bool _isDirty = true;
bool valid_rfData;
uint8_t modelId[NUM_MODULES];
SimpleModuleData moduleData[NUM_MODULES];
bool valid_rfData;
uint8_t modelId[NUM_MODULES] = {0, 0};
SimpleModuleData moduleData[NUM_MODULES];
explicit ModelCell(const char * name);
explicit ModelCell(const char * name, uint8_t len);
~ModelCell();
explicit ModelCell(const char *fileName);
explicit ModelCell(const char *fileName, uint8_t len);
void save(FIL * file);
void setModelName(char *name);
void setModelName(char *name, uint8_t len);
void setRfData(ModelData *model);
void setModelName(char * name);
void setModelName(char* name, uint8_t len);
void setRfData(ModelData * model);
void setModelId(uint8_t moduleIdx, uint8_t id);
void setRfModuleData(uint8_t moduleIdx, ModuleData* modData);
bool fetchRfData();
void setModelId(uint8_t moduleIdx, uint8_t id);
void setRfModuleData(uint8_t moduleIdx, ModuleData *modData);
bool fetchRfData();
};
class ModelsCategory: public std::list<ModelCell *>
typedef struct {
std::string icon;
// Anything else?
} SLabelDetail;
typedef std::vector<std::pair<uint16_t, ModelCell *>> ModelLabelsVector;
typedef std::vector<std::string> LabelsVector;
typedef std::vector<ModelCell *> ModelsVector;
typedef enum {
NO_SORT,
NAME_ASC,
NAME_DES,
DATE_ASC,
DATE_DES,
SORT_COUNT
} ModelsSortBy;
/**
* @brief ModelMap is a multimap of all models and their cooresponding
* labels. Lables are referenced by index, stored in var labels
*/
class ModelMap : protected std::multimap<uint16_t, ModelCell *>
{
public:
char name[LEN_MODEL_FILENAME + 1];
public:
ModelsVector getUnlabeledModels();
ModelsVector getAllModels();
ModelsVector getModelsByLabel(const std::string &);
ModelsVector getModelsByLabels(const LabelsVector &);
ModelsVector getModelsInLabels(const LabelsVector &lbls);
LabelsVector getLabelsByModel(ModelCell *);
std::map<std::string, bool> getSelectedLabels(ModelCell *);
bool isLabelSelected(const std::string &, ModelCell *);
LabelsVector getLabels();
int addLabel(std::string lbl);
bool addLabelToModel(const std::string &, ModelCell *, bool update = false);
bool removeLabelFromModel(const std::string &label, ModelCell *,
bool update = false);
bool removeLabel(
const std::string &,
std::function<void(const char *file, int progress)> progress = nullptr);
bool moveLabelTo(unsigned current, unsigned newind);
bool renameLabel(
const std::string &from, const std::string &to,
std::function<void(const char *file, int progress)> progress = nullptr);
std::string getCurrentLabel() { return currentlabel; };
void setCurrentLabel(const std::string &lbl)
{
currentlabel = lbl;
setDirty();
}
std::string getLabelString(ModelCell *, const char *noresults = "");
void setDirty(bool save = false);
bool isDirty() { return _isDirty; }
explicit ModelsCategory(const char * name);
explicit ModelsCategory(const char * name, uint8_t len);
~ModelsCategory();
// Currently selected labels in the GUI
void setFilteredLabels(std::set<uint32_t> filtlbls)
{
this->filtlbls = std::move(filtlbls);
}
void addFilteredLabel(const std::string &lbl);
bool isLabelFiltered(const std::string &lbl);
std::set<uint32_t> filteredLabels() { return filtlbls; }
ModelCell* addModel(const char* fileName, const char* modelName = nullptr);
void removeModel(ModelCell * model);
void moveModel(ModelCell * model, int8_t step);
void setSortOrder(ModelsSortBy sortby);
ModelsSortBy sortOrder() {return _sortOrder;}
int getModelIndex(const ModelCell* model);
protected:
ModelsSortBy _sortOrder = DEFAULT_MODEL_SORT;
bool _isDirty = true;
std::set<uint32_t> filtlbls;
std::string currentlabel = "";
void save(FIL * file);
void updateModelCell(ModelCell *);
bool removeModels(
ModelCell *); // Should only be called from ModelsList remove model
bool updateModelFile(ModelCell *);
void sortModelsBy(ModelsVector &mv, ModelsSortBy sortby);
void clear()
{
_isDirty = true;
labels.clear();
std::multimap<uint16_t, ModelCell *>::clear();
}
int getIndexByLabel(const std::string &str)
{
auto a = std::find(labels.begin(), labels.end(), str);
return a == labels.end() ? -1 : a - labels.begin();
}
std::string getLabelByIndex(uint16_t index)
{
if (index < (uint16_t)labels.size())
return labels.at(index);
else
return std::string();
}
friend class ModelsList;
private:
LabelsVector labels; // Storage space for discovered labels
};
class ModelsList
class ModelsList : public ModelsVector
{
bool loaded;
std::list<ModelsCategory *> categories;
ModelsCategory * currentCategory;
ModelCell * currentModel;
unsigned int modelsCount;
ModelCell *currentModel;
void init();
public:
public:
enum class Format {
txt,
#if defined(SDCARD_YAML)
@@ -113,73 +216,54 @@ public:
load_default = txt,
#endif
};
ModelsList();
~ModelsList();
bool load(Format fmt = Format::load_default);
void save();
const char *save(LabelsVector newOrder=LabelsVector());
void clear();
const std::list<ModelsCategory *> & getCategories() const
{
return categories;
}
std::list<ModelsCategory *>& getCategories()
{
return categories;
}
void setCurrentModel(ModelCell *cell);
void updateCurrentModelCell();
void setCurrentCategory(ModelsCategory * cat);
ModelsCategory * getCurrentCategory() const
{
return currentCategory;
}
int getCurrentCategoryIdx() const;
void setCurrentModel(ModelCell * cell);
ModelCell * getCurrentModel() const
{
return currentModel;
}
void incModelsCount() {
modelsCount++;
}
ModelCell *getCurrentModel() const { return currentModel; }
unsigned int getModelsCount() const
{
return modelsCount;
return std::vector<ModelCell *>::size();
}
bool readNextLine(char * line, int maxlen);
bool readNextLine(char *line, int maxlen);
ModelsCategory * createCategory(bool save=true);
ModelsCategory * createCategory(const char * name, bool save=true);
void removeCategory(ModelsCategory * category);
ModelCell *addModel(const char *name, bool save = true, ModelCell *copyCell = nullptr);
bool removeModel(ModelCell *model);
bool moveModelTo(unsigned curindex, unsigned toindex);
ModelCell * addModel(ModelsCategory * category, const char * name, const char* modelName = nullptr, bool save=true);
void removeModel(ModelsCategory * category, ModelCell * model);
void moveModel(ModelsCategory * category, ModelCell * model, int8_t step);
void moveModel(ModelCell * model, ModelsCategory * previous_category, ModelsCategory * new_category);
bool isModelIdUnique(uint8_t moduleIdx, char* warn_buf, size_t warn_buf_len);
bool isModelIdUnique(uint8_t moduleIdx, char *warn_buf, size_t warn_buf_len);
uint8_t findNextUnusedModelId(uint8_t moduleIdx);
void onNewModelCreated(ModelCell* cell, ModelData* model);
typedef struct {
std::string name;
char hash[FILE_HASH_LENGTH + 1];
bool curmodel = false;
bool celladded = false;
} filedat;
std::vector<filedat> fileHashInfo;
protected:
protected:
FIL file;
bool loadTxt();
#if defined(SDCARD_YAML)
bool loadYaml();
bool loadYamlDirScanner();
#endif
};
extern ModelsList modelslist;
ModelLabelsVector getUniqueLabels();
#endif // _MODELSLIST_H_
extern ModelsList modelslist;
extern ModelMap modelslabels;
#endif // _MODELSLIST_H_
+16 -8
View File
@@ -26,9 +26,6 @@
#include "conversions/conversions.h"
#include "model_init.h"
// defined either in sdcard_raw.cpp or sdcard_yaml.cpp
void storageCreateModelsList();
void getModelPath(char * path, const char * filename, const char* pathName)
{
unsigned int len = strlen(pathName);
@@ -71,9 +68,6 @@ void storageFormat()
sdCheckAndCreateDirectory(MODELS_PATH);
generalDefault();
setModelDefaults();
#if defined(STORAGE_MODELSLIST)
storageCreateModelsList();
#endif
}
void storageCheck(bool immediately)
@@ -87,10 +81,24 @@ void storageCheck(bool immediately)
}
}
#if defined(STORAGE_MODELSLIST)
if (storageDirtyMsk & EE_LABELS) {
TRACE("SD card write labels");
storageDirtyMsk &= ~EE_LABELS;
const char * error = modelslist.save();
if (error) {
TRACE("writeLabels error=%s", error);
}
}
#endif
if (storageDirtyMsk & EE_MODEL) {
TRACE("eeprom write model");
storageDirtyMsk &= ~EE_MODEL;
const char * error = writeModel();
#if defined(STORAGE_MODELSLIST)
modelslist.updateCurrentModelCell();
#endif
if (error) {
TRACE("writeModel error=%s", error);
}
@@ -206,14 +214,14 @@ void storageReadAll()
storageDirty(EE_GENERAL);
storageCheck(true);
}
if (loadModel(g_eeGeneral.currModelFilename, false) != nullptr) {
TRACE("No current model or SD card error");
}
#else
if (loadModel(g_eeGeneral.currModel, false) != nullptr) {
TRACE("No current model or SD card error");
}
}
#endif
}
-2
View File
@@ -25,8 +25,6 @@
#include "ff.h"
#include "translations.h"
#define DEFAULT_CATEGORY "Models"
#define MODEL_FILENAME_PREFIX "model"
#if defined(SDCARD_RAW)
#define MODEL_FILENAME_SUFFIX ".bin"
-12
View File
@@ -191,15 +191,3 @@ const char * writeGeneralSettingsBin()
return writeFileBin(RADIO_SETTINGS_PATH, (uint8_t *)&g_eeGeneral, sizeof(g_eeGeneral));
}
#if !defined(SDCARD_YAML)
void storageCreateModelsList()
{
FIL file;
FRESULT result = f_open(&file, RADIO_MODELSLIST_PATH, FA_CREATE_ALWAYS | FA_WRITE);
if (result == FR_OK) {
f_puts("[" DEFAULT_CATEGORY "]\n" DEFAULT_MODEL_FILENAME "\n", &file);
f_close(&file);
}
}
#endif
+6 -23
View File
@@ -122,27 +122,6 @@ const char * readYamlFile(const char* fullpath, const YamlParserCalls* calls, vo
return NULL;
}
//
// Generic storage interface
//
#if defined(STORAGE_MODELSLIST)
void storageCreateModelsList()
{
modelslist.clear();
ModelsCategory* cat = modelslist.createCategory(DEFAULT_CATEGORY, false);
ModelCell* model = nullptr;
if (g_eeGeneral.currModelFilename[0] != '\0') {
model = modelslist.addModel(cat, g_eeGeneral.currModelFilename, nullptr, false);
} else {
model = modelslist.addModel(cat, DEFAULT_MODEL_FILENAME, nullptr, false);
}
model->setModelName(g_model.header.name);
modelslist.save();
}
#endif
//
// SDCARD storage interface
//
@@ -224,12 +203,16 @@ const char * loadRadioSettings()
#endif
}
#if defined(DEFAULT_INTERNAL_MODULE)
g_eeGeneral.internalModule = DEFAULT_INTERNAL_MODULE;
#endif
const char* error = loadRadioSettingsYaml();
if (!error) {
g_eeGeneral.chkSum = evalChkSum();
}
postRadioSettingsLoad();
return error;
}
@@ -345,7 +328,7 @@ const char * writeGeneralSettings()
return p;
}
f_unlink(RADIO_SETTINGS_YAML_PATH);
FRESULT result = f_rename(RADIO_SETTINGS_TMPFILE_YAML_PATH, RADIO_SETTINGS_YAML_PATH);
if(result != FR_OK)
return SDCARD_ERROR(result);
+1
View File
@@ -22,6 +22,7 @@
#pragma once
enum class ChecksumResult {Success, Failed, None};
#include "sdcard_common.h" // TODO CHECK REQUIRED
constexpr uint8_t MODELIDX_STRLEN = sizeof(MODEL_FILENAME_PREFIX "00");
+3 -2
View File
@@ -6,9 +6,10 @@ set(SRC ${SRC} storage/yaml/yaml_tree_walker.cpp
storage/yaml/yaml_datastructs.cpp)
if(STORAGE_MODELSLIST)
set(SRC ${SRC} storage/yaml/yaml_modelslist.cpp)
set(SRC ${SRC} storage/yaml/yaml_labelslist.cpp)
add_definitions(-DSTORAGE_MODELSLIST)
endif()
# Warning: this file must be kept in sync with 'yaml_datastructs.cpp'
# in the same directory.
@@ -455,6 +455,7 @@ static const struct YamlNode struct_ModelHeader[] = {
YAML_STRING("name", 15),
YAML_ARRAY("modelId", 8, 2, struct_unsigned_8, NULL),
YAML_STRING("bitmap", 14),
YAML_STRING("labels", 100),
YAML_END
};
static const struct YamlNode struct_TimerData[] = {
@@ -837,7 +838,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = {
};
static const struct YamlNode struct_ModelData[] = {
YAML_CUSTOM("semver",nullptr,w_semver),
YAML_STRUCT("header", 248, struct_ModelHeader, NULL),
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
YAML_UNSIGNED( "telemetryProtocol", 3 ),
YAML_UNSIGNED( "thrTrim", 1 ),
@@ -889,7 +890,7 @@ static const struct YamlNode struct_ModelData[] = {
YAML_END
};
static const struct YamlNode struct_PartialModel[] = {
YAML_STRUCT("header", 248, struct_ModelHeader, NULL),
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
YAML_END
};
@@ -480,6 +480,7 @@ static const struct YamlNode struct_ModelHeader[] = {
YAML_STRING("name", 15),
YAML_ARRAY("modelId", 8, 2, struct_unsigned_8, NULL),
YAML_STRING("bitmap", 14),
YAML_STRING("labels", 100),
YAML_END
};
static const struct YamlNode struct_TimerData[] = {
@@ -862,7 +863,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = {
};
static const struct YamlNode struct_ModelData[] = {
YAML_CUSTOM("semver",nullptr,w_semver),
YAML_STRUCT("header", 248, struct_ModelHeader, NULL),
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
YAML_UNSIGNED( "telemetryProtocol", 3 ),
YAML_UNSIGNED( "thrTrim", 1 ),
@@ -914,7 +915,7 @@ static const struct YamlNode struct_ModelData[] = {
YAML_END
};
static const struct YamlNode struct_PartialModel[] = {
YAML_STRUCT("header", 248, struct_ModelHeader, NULL),
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
YAML_END
};
@@ -478,6 +478,7 @@ static const struct YamlNode struct_ModelHeader[] = {
YAML_STRING("name", 15),
YAML_ARRAY("modelId", 8, 2, struct_unsigned_8, NULL),
YAML_STRING("bitmap", 14),
YAML_STRING("labels", 100),
YAML_END
};
static const struct YamlNode struct_TimerData[] = {
@@ -860,7 +861,7 @@ static const struct YamlNode struct_TopBarPersistentData[] = {
};
static const struct YamlNode struct_ModelData[] = {
YAML_CUSTOM("semver",nullptr,w_semver),
YAML_STRUCT("header", 248, struct_ModelHeader, NULL),
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
YAML_UNSIGNED( "telemetryProtocol", 3 ),
YAML_UNSIGNED( "thrTrim", 1 ),
@@ -912,7 +913,7 @@ static const struct YamlNode struct_ModelData[] = {
YAML_END
};
static const struct YamlNode struct_PartialModel[] = {
YAML_STRUCT("header", 248, struct_ModelHeader, NULL),
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
YAML_ARRAY("timers", 136, 3, struct_TimerData, NULL),
YAML_END
};
+301
View File
@@ -0,0 +1,301 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "yaml_labelslist.h"
#include "yaml_parser.h"
#include "debug.h"
#include "storage/modelslist.h"
#include <cstring>
#ifdef DEBUG_LABELS
#define TRACE_LABELS_YAML(...) TRACE(__VA_ARGS__)
#else
#define TRACE_LABELS_YAML(...)
#endif
using std::list;
struct labelslist_iter
{
enum ItemData {
Root=0,
ModelsRoot=1,
ModelName=2,
ModelData=3,
LabelsRoot=4,
LabelName=5,
LabelData=6,
SortRoot=7,
};
ModelCell *curmodel;
bool modeldatavalid; // Used to determine if reading yaml values is necessary
uint8_t level;
char current_attr[LABEL_LENGTH+1]; // set after find_node()
char current_label[LABEL_LENGTH+1]; // set after find_node()
};
static labelslist_iter __labelslist_iter_inst;
void* get_labelslist_iter()
{
// Thoughts... record the time here.
// If time > xxx while parsing models. pop up a window showing updating?
__labelslist_iter_inst.modeldatavalid = false;
__labelslist_iter_inst.curmodel = NULL;
__labelslist_iter_inst.level = 0;
TRACE_LABELS_YAML("YAML Label Reader Start %u", 0);
return &__labelslist_iter_inst;
}
static bool to_parent(void* ctx)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
if (mi->level == labelslist_iter::Root)
return false;
if(mi->level == labelslist_iter::ModelName ||
mi->level == labelslist_iter::LabelName) {
mi->level = labelslist_iter::Root;
}
else
mi->level--;
TRACE_LABELS_YAML("YAML To Parent %u", mi->level);
return true;
}
static bool to_child(void* ctx)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
mi->level++;
TRACE_LABELS_YAML("YAML To Child");
TRACE_LABELS_YAML("YAML Level %u", mi->level);
return true;
}
static bool to_next_elmt(void* ctx)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
if (mi->level == labelslist_iter::Root) {
return false;
}
TRACE_LABELS_YAML("YAML To Next Element");
TRACE_LABELS_YAML("YAML Current Level %u", mi->level);
return true;
}
static bool find_node(void* ctx, char* buf, uint8_t len)
{
labelslist_iter* mi = (labelslist_iter*)ctx;
memcpy(mi->current_attr, buf, len);
mi->current_attr[len] = '\0';
TRACE_LABELS_YAML("YAML On Node %s", mi->current_attr);
TRACE_LABELS_YAML("YAML Current Level %u", mi->level);
// If in the labels node, force to labelsroot enum
if(mi->level == labelslist_iter::Root && strcasecmp(mi->current_attr,"labels") == 0) {
TRACE_LABELS_YAML("Forced root");
mi->level = labelslist_iter::LabelsRoot;
TRACE_LABELS_YAML("YAML New Level %u", mi->level);
}
if(mi->level == labelslist_iter::Root && strcasecmp(mi->current_attr,"models") == 0) {
TRACE_LABELS_YAML("Forced root");
mi->level = labelslist_iter::ModelsRoot;
TRACE_LABELS_YAML("YAML New Level %u", mi->level);
}
if(mi->level == labelslist_iter::Root && strcasecmp(mi->current_attr,"sort") == 0) {
TRACE_LABELS_YAML("Forced root");
mi->level = labelslist_iter::SortRoot;
TRACE_LABELS_YAML("YAML New Level %u", mi->level);
}
// Model List
if(mi->level == labelslist_iter::ModelName) {
bool found=false;
for(auto &filehash : modelslist.fileHashInfo) {
if(filehash.name == mi->current_attr) {
TRACE_LABELS_YAML(" Model %s has a real file, creating a modelcell");
ModelCell *model = new ModelCell(mi->current_attr);
strcpy(model->modelFinfoHash, filehash.hash);
modelslist.push_back(model);
filehash.celladded = true;
if(filehash.curmodel == true)
modelslist.setCurrentModel(model);
mi->curmodel = model;
mi->modeldatavalid = false;
mi->curmodel->_isDirty = true;
found = true;
break;
}
}
if(!found) {
mi->curmodel = NULL;
TRACE_LABELS_YAML("File does not exist in /MODELS");
}
}
// Labels List
if(mi->level == labelslist_iter::LabelName) {
TRACE_LABELS_YAML("Label Found -- %s", mi->current_attr);
modelslabels.addLabel(mi->current_attr);
strncpy(mi->current_label,mi->current_attr, LABEL_LENGTH);
mi->current_label[LABEL_LENGTH] = '\0';
}
return true;
}
static void set_attr(void* ctx, char* buf, uint8_t len)
{
char value[40];
memcpy(value, buf, len);
value[len] = '\0';
labelslist_iter* mi = (labelslist_iter*)ctx;
TRACE_LABELS_YAML("YAML Attr Level %u, %s = %s", mi->level, mi->current_attr, value);
// Model Section
if(mi->level == labelslist_iter::ModelData) {
// File Hash
if(!strcasecmp(mi->current_attr, "hash")) {
if(mi->curmodel != NULL) {
if(!strcmp(mi->curmodel->modelFinfoHash, value)) {
TRACE_LABELS_YAML("FILE HASH MATCHES, No need to scan this model, just load the settings");
mi->modeldatavalid = true;
mi->curmodel->valid_rfData = true;
mi->curmodel->_isDirty = false;
} else {
TRACE_LABELS_YAML("FILE HASH Does not Match, Open model and rebuild modelcell");
mi->modeldatavalid = false;
mi->curmodel->_isDirty = true;
}
}
// Model Name
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "name")) {
if(mi->curmodel != NULL) {
mi->curmodel->setModelName(value);
TRACE_LABELS_YAML("Set the models name");
}
// Last Opened
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "lastopen")) {
if(mi->curmodel != NULL) {
mi->curmodel->lastOpened = (gtime_t)strtol(value, NULL, 0);
TRACE_LABELS_YAML("Last Opened %lu", value);
}
// Model Bitmap
#if LEN_BITMAP_NAME > 0
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "bitmap")) {
if(mi->curmodel != NULL) {
// TODO Check if it exists ?
strcpy(mi->curmodel->modelBitmap, value);
TRACE_LABELS_YAML("Set the models bitmap");
}
#endif
// Model Labels
} else if(mi->modeldatavalid && !strcasecmp(mi->current_attr, "labels")) {
if(mi->curmodel != NULL) {
char *cma;
cma = strtok(value, ",");
int numTokens = 0;
while(cma != NULL) {
modelslabels.addLabelToModel(cma,mi->curmodel);
TRACE_LABELS_YAML(" Adding the label - %s", cma);
cma = strtok(NULL, ",");
numTokens++;
}
}
// RF Module Data
} else {
char cmp[15];
for(int i=0; i < NUM_MODULES; i++) {
snprintf(cmp, sizeof(cmp), MODULE_ID_STR, i);
cmp[sizeof(cmp)-1] = '\0';
if(mi->curmodel != NULL && mi->modeldatavalid && !strcasecmp(mi->current_attr, cmp)) {
mi->curmodel->modelId[i] = strtol(value,NULL,10);
TRACE_LABELS_YAML("Set the module %d rfId to %s", i, value);
}
snprintf(cmp, sizeof(cmp), MODULE_TYPE_STR, i);
cmp[sizeof(cmp)-1] = '\0';
if(mi->curmodel != NULL && mi->modeldatavalid && !strcasecmp(mi->current_attr, cmp)) {
mi->curmodel->moduleData[i].type = strtol(value,NULL,10);
TRACE_LABELS_YAML("Set the module %d rfType to %s", i, value);
}
snprintf(cmp, sizeof(cmp), MODULE_RFPROTOCOL_STR, i);
cmp[sizeof(cmp)-1] = '\0';
if(mi->curmodel != NULL && mi->modeldatavalid && !strcasecmp(mi->current_attr, cmp)) {
mi->curmodel->moduleData[i].subType = strtol(value,NULL,10);
TRACE_LABELS_YAML("Set the module %d rfProtocol to %s", i, value);
}
}
}
// Label Section
} else if(mi->level == labelslist_iter::LabelData) {
if(!strcasecmp(mi->current_attr, "icon")) {
TRACE_LABELS_YAML("Label Icon - %s", value);
// TODO - Check icon exists, or ignore it.
} else if(!strcasecmp(mi->current_attr, "selected")) {
TRACE("FOUND %s Label is selected", mi->current_label);
modelslabels.addFilteredLabel(mi->current_label);
}
// Sort Order
} else if (mi->level == labelslist_iter::SortRoot) {
TRACE("Sort Order Found -- %s", mi->current_attr);
mi->level = labelslist_iter::Root;
modelslabels.setSortOrder((ModelsSortBy)strtol(value,NULL,10));
}
}
static const YamlParserCalls labelslistCalls = {
to_parent,
to_child,
to_next_elmt,
find_node,
set_attr
};
const YamlParserCalls* get_labelslist_parser_calls()
{
return &labelslistCalls;
}
@@ -19,12 +19,16 @@
* GNU General Public License for more details.
*/
#ifndef _YAML_MODELSLIST_H_
#define _YAML_MODELSLIST_H_
#ifndef _YAML_LABELSLIST_H_
#define _YAML_LABELSLIST_H_
#define MODULE_ID_STR "mod%did"
#define MODULE_TYPE_STR "mod%dtype"
#define MODULE_RFPROTOCOL_STR "mod%drf"
struct YamlParserCalls;
void* get_modelslist_iter(const char* currentModel, unsigned currentModel_len);
const YamlParserCalls* get_modelslist_parser_calls();
void* get_labelslist_iter();
const YamlParserCalls* get_labelslist_parser_calls();
#endif
-153
View File
@@ -1,153 +0,0 @@
/*
* Copyright (C) EdgeTX
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "yaml_modelslist.h"
#include "yaml_parser.h"
#include "storage/modelslist.h"
#include <cstring>
using std::list;
struct modelslist_iter
{
enum Level {
Root=0,
Category=1,
Model=2
};
ModelsList* root;
const char* currentModel;
unsigned currentModel_len;
uint8_t level;
char current_attr[16]; // set after find_node()
};
static modelslist_iter __modelslist_iter_inst;
void* get_modelslist_iter(const char* currentModel, unsigned currentModel_len)
{
__modelslist_iter_inst.root = &modelslist;
__modelslist_iter_inst.currentModel = currentModel;
__modelslist_iter_inst.currentModel_len = currentModel_len;
__modelslist_iter_inst.level = 0;
return &__modelslist_iter_inst;
}
static bool to_parent(void* ctx)
{
modelslist_iter* mi = (modelslist_iter*)ctx;
if (mi->level == modelslist_iter::Root) {
return false;
}
mi->level--;
return true;
}
static bool to_child(void* ctx)
{
modelslist_iter* mi = (modelslist_iter*)ctx;
if (mi->level == modelslist_iter::Model) {
return false;
}
mi->level++;
return true;
}
static bool to_next_elmt(void* ctx)
{
modelslist_iter* mi = (modelslist_iter*)ctx;
if (mi->level == modelslist_iter::Root) {
return false;
}
return true;
}
static bool find_node(void* ctx, char* buf, uint8_t len)
{
modelslist_iter* mi = (modelslist_iter*)ctx;
if (len > sizeof(modelslist_iter::current_attr)-1)
len = sizeof(modelslist_iter::current_attr)-1;
memcpy(mi->current_attr, buf, len);
mi->current_attr[len] = '\0';
list<ModelsCategory *>& cats = mi->root->getCategories();
if (mi->level == modelslist_iter::Category) {
ModelsCategory* cat = new ModelsCategory(buf,len);
cats.push_back(cat);
}
return true;
}
static void set_attr(void* ctx, char* buf, uint8_t len)
{
modelslist_iter* mi = (modelslist_iter*)ctx;
auto ml = mi->root;
list<ModelsCategory*>& cats = ml->getCategories();
switch (mi->level) {
case modelslist_iter::Model:
if (!strcmp(mi->current_attr, "filename")) {
if (!cats.empty()) {
ModelCell* model = new ModelCell(buf, len);
auto cat = cats.back();
cat->push_back(model);
ml->incModelsCount();
if (!strncmp(model->modelFilename, mi->currentModel,
mi->currentModel_len)) {
ml->setCurrentCategory(cat);
ml->setCurrentModel(model);
}
}
} else if (!strcmp(mi->current_attr, "name")) {
if (!cats.empty()) {
auto cat = cats.back();
if (!cat->empty()) {
auto model = cat->back();
model->setModelName(buf, len);
}
}
}
break;
}
}
static const YamlParserCalls modelslistCalls = {
to_parent,
to_child,
to_next_elmt,
find_node,
set_attr
};
const YamlParserCalls* get_modelslist_parser_calls()
{
return &modelslistCalls;
}
@@ -65,6 +65,7 @@ constexpr uint32_t MENU_HEADER_BACK_BUTTON_WIDTH = MENU_HEADER_HEIGHT;
constexpr uint32_t MENU_HEADER_BACK_BUTTON_HEIGHT = MENU_HEADER_HEIGHT;
constexpr coord_t PAGE_PADDING = 6;
constexpr uint32_t LABELS_LINE_HEIGHT = 30;
constexpr uint32_t PAGE_LINE_HEIGHT = 20;
constexpr coord_t LINE_HEIGHT = PAGE_LINE_HEIGHT;
+14 -5
View File
@@ -130,6 +130,7 @@ const char STR_DELETEMODEL[] = TR_DELETEMODEL;
const char STR_COPYINGMODEL[] = TR_COPYINGMODEL;
const char STR_MOVINGMODEL[] = TR_MOVINGMODEL;
const char STR_LOADINGMODEL[] = TR_LOADINGMODEL;
const char STR_UNLABELEDMODEL[] = TR_UNLABELEDMODEL;
const char STR_NAME[] = TR_NAME;
const char STR_BITMAP[] = TR_BITMAP;
const char STR_TIMER[] = TR_TIMER;
@@ -329,17 +330,17 @@ const char STR_CURRENT_CALIB[] = TR_CURRENT_CALIB;
const char STR_UNITS_SYSTEM[] = TR_UNITS_SYSTEM;
const char STR_VOICE_LANGUAGE[] = TR_VOICE_LANGUAGE;
const char STR_MODELIDUSED[] = TR_MODELIDUSED;
const char STR_MODELIDUNIQUE[] = TR_MODELIDUNIQUE;
const char STR_BEEP_VOLUME[] = INDENT TR_BEEP_VOLUME;
const char STR_WAV_VOLUME[] = INDENT TR_WAV_VOLUME;
const char STR_BG_VOLUME[] = INDENT TR_BG_VOLUME;
const char STR_SELECT_MODEL[] = TR_SELECT_MODEL;
const char STR_MODEL_CATEGORIES[] = TR_MODEL_CATEGORIES;
const char STR_MODELS[] = TR_MODELS;
const char STR_SELECT_MODE[] = TR_SELECT_MODE;
const char STR_CREATE_CATEGORY[] = TR_CREATE_CATEGORY;
const char STR_RENAME_CATEGORY[] = TR_RENAME_CATEGORY;
const char STR_DELETE_CATEGORY[] = TR_DELETE_CATEGORY;
const char STR_CREATE_MODEL[] = TR_CREATE_MODEL;
const char STR_FAVORITE_LABEL[] = TR_FAVORITE_LABEL;
const char STR_NEW_MODEL[] = TR_NEW_MODEL;
const char STR_EDIT_LABELS[] = TR_EDIT_LABELS;
const char STR_DUPLICATE_MODEL[] = TR_DUPLICATE_MODEL;
const char STR_COPY_MODEL[] = TR_COPY_MODEL;
const char STR_MOVE_MODEL[] = TR_MOVE_MODEL;
@@ -405,7 +406,6 @@ const char STR_WAITING_FOR_RX[] = TR_WAITING_FOR_RX;
const char STR_WAITING_FOR_TX[] = TR_WAITING_FOR_TX;
const char STR_WAITING_FOR_MODULE[] = TR_WAITING_FOR_MODULE;
const char STR_WARN_5VOLTS[] = TR_WARN_5VOLTS;
const char STR_CAT_NOT_EMPTY[] = TR_CAT_NOT_EMPTY;
const char STR_WARNING[] = TR_WARNING;
const char STR_THROTTLE_WARNING[] = TR_THROTTLE_WARNING;
const char STR_CUSTOM_THROTTLE_WARNING[] = TR_CUSTOM_THROTTLE_WARNING;
@@ -998,8 +998,17 @@ const char STR_EDIT_THEME[] = TR_EDIT_THEME;
const char STR_DETAILS[] = TR_DETAILS;
const char STR_THEME_EDITOR[] = TR_THEME_EDITOR;
#if defined(COLORLCD)
const char STR_ENTER_LABEL[] = TR_ENTER_LABEL;
const char STR_LABEL[] = TR_LABEL;
const char STR_LABELS[] = TR_LABELS;
const char STR_CURRENT_MODEL[] = TR_CURRENT_MODEL;
const char STR_NEW[] = TR_NEW;
const char STR_NEW_LABEL[] = TR_NEW_LABEL;
const char STR_RENAME_LABEL[] = TR_RENAME_LABEL;
const char STR_DELETE_LABEL[] = TR_DELETE_LABEL;
const char STR_MAIN_MENU_SELECT_MODEL[] = TR_MAIN_MENU_SELECT_MODEL;
const char STR_MAIN_MENU_MODEL_NOTES[] = TR_MAIN_MENU_MODEL_NOTES;
const char STR_MAIN_MENU_CHANNEL_MONITOR[] = TR_MAIN_MENU_CHANNEL_MONITOR;
+17 -5
View File
@@ -234,6 +234,7 @@ extern const char STR_DELETEMODEL[];
extern const char STR_COPYINGMODEL[];
extern const char STR_MOVINGMODEL[];
extern const char STR_LOADINGMODEL[];
extern const char STR_UNLABELEDMODEL[];
extern const char STR_NAME[];
extern const char STR_BITMAP[];
extern const char STR_TIMER[];
@@ -528,17 +529,17 @@ extern const char STR_CURRENT_CALIB[];
extern const char STR_UNITS_SYSTEM[];
extern const char STR_VOICE_LANGUAGE[];
extern const char STR_MODELIDUSED[];
extern const char STR_MODELIDUNIQUE[];
extern const char STR_BEEP_VOLUME[];
extern const char STR_WAV_VOLUME[];
extern const char STR_BG_VOLUME[];
extern const char STR_SELECT_MODEL[];
extern const char STR_MODEL_CATEGORIES[];
extern const char STR_MODELS[];
extern const char STR_SELECT_MODE[];
extern const char STR_CREATE_CATEGORY[];
extern const char STR_RENAME_CATEGORY[];
extern const char STR_DELETE_CATEGORY[];
extern const char STR_CREATE_MODEL[];
extern const char STR_FAVORITE_LABEL[];
extern const char STR_NEW_MODEL[];
extern const char STR_EDIT_LABELS[];
extern const char STR_DUPLICATE_MODEL[];
extern const char STR_COPY_MODEL[];
extern const char STR_MOVE_MODEL[];
@@ -631,7 +632,6 @@ extern const char STR_ASK_OVERWRITE[];
extern const char STR_NEEDS_FILE[];
extern const char STR_EXT_MULTI_SPEC[];
extern const char STR_INT_MULTI_SPEC[];
extern const char STR_CAT_NOT_EMPTY[];
extern const char STR_WARNING[];
extern const char STR_STORAGE_WARNING[];
extern const char STR_EEPROM_CONVERTING[];
@@ -1196,8 +1196,20 @@ extern const char STR_EDIT_THEME[];
extern const char STR_DETAILS[];
extern const char STR_THEME_EDITOR[];
#if defined(COLORLCD)
extern const char STR_ENTER_LABEL[];
extern const char STR_LABEL[];
extern const char STR_LABELS[];
extern const char STR_SELECT_MODEL[];
extern const char STR_NONE[];
extern const char STR_CURRENT_MODEL[];
extern const char STR_NEW[];
extern const char STR_NEW_LABEL[];
extern const char STR_RENAME_LABEL[];
extern const char STR_DELETE_LABEL[];
extern const char STR_MAIN_MENU_SELECT_MODEL[];
extern const char STR_MAIN_MENU_MODEL_NOTES[];
extern const char STR_MAIN_MENU_CHANNEL_MONITOR[];
+15 -11
View File
@@ -331,6 +331,7 @@
#define TR_COPYINGMODEL "复制模型..."
#define TR_MOVINGMODEL "移动模型..."
#define TR_LOADINGMODEL "载入模型..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "名称"
#define TR_MODELNAME "模型名称"
#define TR_PHASENAME "模式名称"
@@ -626,13 +627,20 @@
#define TR_VOLTAGE TR(INDENT "电压源", INDENT "电压来源")
#define TR_CURRENT TR(INDENT "电流源", INDENT "电流来源")
#define TR_SELECT_MODEL "选择模型"
#define TR_MODEL_CATEGORIES "模型分类"
#define TR_MODELS "个模型"
#define TR_SELECT_MODE "选择模式"
#define TR_CREATE_CATEGORY "创建分类"
#define TR_RENAME_CATEGORY "分类改名"
#define TR_DELETE_CATEGORY "删除分类"
#define TR_CREATE_MODEL "创建模型"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "复制模型"
#define TR_COPY_MODEL "复制模型"
#define TR_MOVE_MODEL "移动模型"
@@ -640,7 +648,6 @@
#define TR_DELETE_MODEL "删除模型"
#define TR_RESTORE_MODEL "恢复模型"
#define TR_DELETE_ERROR "删除失败"
#define TR_CAT_NOT_EMPTY "分类未清空"
#define TR_SDCARD_ERROR TR("存储卡错误", "存储卡错误")
#define TR_SDCARD "存储卡"
#define TR_NO_FILES_ON_SD "存储卡中没有文件!"
@@ -911,11 +918,8 @@
#define TR_TRAINER "教练"
#define TR_CHANS "通道"
#define TR_ANTENNAPROBLEM CENTER "发射机天线故障!"
#if defined(COLORLCD)
#define TR_MODELIDUSED "ID已使用:"
#else
#define TR_MODELIDUSED TR("ID已使用:","ID已使用:")
#endif
#define TR_MODELIDUSED "ID已使用:"
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "模块"
#define TR_RX_NAME "接收机名称"
#define TR_TELEMETRY_TYPE TR("类型", "回传类型")
@@ -1334,4 +1338,4 @@
#define TR_PROTOCOL "协议"
#define TR_YEAR "年"
#define TR_MONTH "月"
#define TR_DAY "日"
#define TR_DAY "日"
+13 -5
View File
@@ -349,6 +349,7 @@
#define TR_COPYINGMODEL "Kopíruji model..."
#define TR_MOVINGMODEL "Přesouvám model..."
#define TR_LOADINGMODEL "Aktivuji model..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Název"
#define TR_MODELNAME TR("Model", "Název modelu")
#define TR_PHASENAME "Název"
@@ -642,13 +643,20 @@
#define TR_VOLTAGE INDENT"Napětí"
#define TR_CURRENT INDENT"Proud"
#define TR_SELECT_MODEL "Vyber model"
#define TR_MODEL_CATEGORIES "Kategorie modelů"
#define TR_MODELS "Modely"
#define TR_SELECT_MODE "Vybrat mód"
#define TR_CREATE_CATEGORY "Nová kategorie"
#define TR_RENAME_CATEGORY "Přejmenovat kategorii"
#define TR_DELETE_CATEGORY "Odstranit kategorii"
#define TR_CREATE_MODEL "Nový model"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplikovat model"
#define TR_COPY_MODEL "Kopírovat"
#define TR_MOVE_MODEL "Přesunout model"
@@ -656,7 +664,6 @@
#define TR_DELETE_MODEL "Smaž model"
#define TR_RESTORE_MODEL "Obnov model z SD"
#define TR_DELETE_ERROR "Nelze odstranit"
#define TR_CAT_NOT_EMPTY "Kategorie není prázdná"
#define TR_SDCARD_ERROR "Chyba SD karty"
#define TR_SDCARD "SD karta"
#define TR_NO_FILES_ON_SD "Žádné soubory na SD kartě!"
@@ -927,6 +934,7 @@
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "Problém s TX anténou!"
#define TR_MODELIDUSED TR("ID již použito","ID modelu je již použito")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Modul"
#define TR_RX_NAME "Jméno RX"
#define TR_TELEMETRY_TYPE TR("Typ", "Typ telemetrie")
+22 -18
View File
@@ -332,6 +332,7 @@
#define TR_COPYINGMODEL "Kopier model..."
#define TR_MOVINGMODEL "Flytter model..."
#define TR_LOADINGMODEL "Indlæser model..."
#define TR_UNLABELEDMODEL "Typeløs"
#define TR_NAME "Navn"
#define TR_MODELNAME "Model navn"
#define TR_PHASENAME "Mode navn"
@@ -601,7 +602,7 @@
#define TR_PROTOCOL_INVALID TR("Prot. ugyldig", "Protocol ugyldig")
#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status")
#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Proto Sync Status")
#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo opdaterings rate")
#define TR_MULTI_SERVOFREQ TR("Servo hastighed", "Servo opdaterings hastighed")
#define TR_MULTI_MAX_THROW TR("Max. Throw", "Enable max. throw")
#define TR_MULTI_RFCHAN TR("RF kanal", "Vælg RF kanal")
#define TR_AFHDS3_RX_FREQ TR("RX frekv.", "RX frekvens")
@@ -612,7 +613,7 @@
#define TR_SYNCMENU "[Sync]"
#define TR_LIMIT INDENT "Grænse"
#define TR_MINRSSI "Min Rssi"
#define TR_FLYSKY_TELEMETRY TR("FlySky RSSI #", "Brug FlySky RSSI value without rescalling")
#define TR_FLYSKY_TELEMETRY TR("FlySky RSSI #", "Brug FlySky RSSI værdi uden reskalering")
#define TR_LATITUDE "Breddegrad"
#define TR_LONGITUDE "Længdegrad"
#define TR_GPS_COORDS_FORMAT TR("GPS Coords", "Coordinate format")
@@ -627,13 +628,20 @@
#define TR_VOLTAGE TR(INDENT "Spænding", INDENT "Spænding kilde")
#define TR_CURRENT TR(INDENT "Strøm", INDENT "Strøm kilde")
#define TR_SELECT_MODEL "Vælg model"
#define TR_MODEL_CATEGORIES "Model kategorier"
#define TR_MODELS "Modeller"
#define TR_SELECT_MODE "Vælg tilstand"
#define TR_CREATE_CATEGORY "Opret category"
#define TR_RENAME_CATEGORY "Omdøb category"
#define TR_DELETE_CATEGORY "Slet category"
#define TR_CREATE_MODEL "Opret model"
#define TR_FAVORITE_LABEL "Favoritter"
#define TR_NEW_MODEL "Ny model"
#define TR_EDIT_LABELS "Ret type"
#define TR_ENTER_LABEL "Vælg type"
#define TR_LABEL "Type"
#define TR_LABELS "Typer"
#define TR_CURRENT_MODEL "Aktuelle"
#define TR_NEW "Ny"
#define TR_NEW_LABEL "Ny type"
#define TR_RENAME_LABEL "Omdøb type"
#define TR_DELETE_LABEL "Slet type"
#define TR_DUPLICATE_MODEL "Dupliker model"
#define TR_COPY_MODEL "Kopier model"
#define TR_MOVE_MODEL "Flyt model"
@@ -641,7 +649,6 @@
#define TR_DELETE_MODEL "Slet model"
#define TR_RESTORE_MODEL "Genskab model"
#define TR_DELETE_ERROR "Slet fejl"
#define TR_CAT_NOT_EMPTY "Kategori er ikke tom"
#define TR_SDCARD_ERROR TR("SD fejl", "SD kort fejl")
#define TR_SDCARD "SD kort"
#define TR_NO_FILES_ON_SD "Ingen filer på SD!"
@@ -887,7 +894,7 @@
#define TR_BUZZER INDENT "Biper"
#define TR_BYTES "bytes"
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed"
#define TR_POWERMETER_ATTN_NEEDED "Attestering nøvendig"
#define TR_PXX2_SELECT_RX "Vælg RX"
#define TR_PXX2_DEFAULT "<default>"
#define TR_BT_SELECT_DEVICE "Vælg enhed"
@@ -906,17 +913,14 @@
#define TR_DEBUG "Fejlfind"
#define TR_KEYS_BTN BUTTON("Taster")
#define TR_ANALOGS_BTN BUTTON(TR("Analo", "Analoge"))
#define TR_TOUCH_NOTFOUND "Touch hardware not found"
#define TR_TOUCH_EXIT "Touch screen to exit"
#define TR_TOUCH_NOTFOUND "Tryk skærm ikke fundet"
#define TR_TOUCH_EXIT "Tryk på skærm for at forlade"
#define TR_SET BUTTON("Set")
#define TR_TRAINER "Træner"
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "TX antenne problem!"
#if defined(COLORLCD)
#define TR_MODELIDUSED "ID brugt i:"
#else
#define TR_MODELIDUSED TR("ID brugt i:","Modtager ID brugt i:")
#endif
#define TR_MODELIDUSED "ID brugt i:"
#define TR_MODELIDUNIQUE "ID er entydig"
#define TR_MODULE "Modul"
#define TR_RX_NAME "Rx Navn"
#define TR_TELEMETRY_TYPE TR("Type", "Telemetri type")
@@ -980,13 +984,13 @@
#define TR_INPUTS "Indgange"
#define TR_OUTPUTS "Udgange"
#define STR_EEBACKUP "EEPROM backup"
#define STR_FACTORYRESET "Factory reset"
#define STR_FACTORYRESET "Nulstil til fabrik indstillinger"
#define TR_CONFIRMRESET TR("Slet ALLE", "Slet ALLE modeller og indstillinger?")
#define TR_TOO_MANY_LUA_SCRIPTS "Too many Lua scripts!"
#define TR_TOO_MANY_LUA_SCRIPTS "For mannge Lua scripts!"
#define TR_SPORT_UPDATE_POWER_MODE "SP Strøm"
#define TR_SPORT_UPDATE_POWER_MODES "AUTO","TIL"
#define TR_NO_TELEMETRY_SCREENS "Ingen telemetri skærme"
#define TR_TOUCH_PANEL "Touch panel:"
#define TR_TOUCH_PANEL "Tryk panel:"
#define TR_FILE_SIZE "Fil størrelse"
#define TR_FILE_OPEN "Åbn alligevel?"
+13 -10
View File
@@ -336,6 +336,7 @@
#define TR_COPYINGMODEL "Kopiere Modell"
#define TR_MOVINGMODEL "Schiebe Modell"
#define TR_LOADINGMODEL "Lade Modell..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Name"
#define TR_MODELNAME "Modellname"
#define TR_PHASENAME "Phase-Name"
@@ -625,13 +626,20 @@
#define TR_VOLTAGE TR(INDENT "Spg", INDENT "Spannungsquelle") //9XR-Pro
#define TR_CURRENT TR(INDENT "Strom", INDENT "Stromquelle")
#define TR_SELECT_MODEL "Modell auswählen"
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Modelltyp erstellen"
#define TR_RENAME_CATEGORY "Modelltyp umbenennen"
#define TR_DELETE_CATEGORY "Modelltyp löschen"
#define TR_CREATE_MODEL TR("Neues Modell" , "Neues Modell erstellen")
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Kopiere Modell"
#define TR_COPY_MODEL "Kopiere Modell"
#define TR_MOVE_MODEL "Verschiebe Modell"
@@ -639,7 +647,6 @@
#define TR_DELETE_MODEL "Lösche Modell" // TODO merged into DELETEMODEL?
#define TR_RESTORE_MODEL TR("Modell wiederher.", "Modell wiederherstellen")
#define TR_DELETE_ERROR "Fehler beim\nLöschen"
#define TR_CAT_NOT_EMPTY "Modelltyp nicht leer"
#define TR_SDCARD_ERROR "SD-Kartenfehler"
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -911,11 +918,7 @@
#define TR_TRAINER "DSC Buchse PPM In/Out"
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "TX-Antennenproblem!"
#if defined(COLORLCD)
#define TR_MODELIDUSED "ID used in:"
#else
#define TR_MODELIDUSED TR("ID used in:","Receiver ID used in:")
#endif
#define TR_MODELIDUSED "ID used in:"#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Modul-Typ"
#define TR_RX_NAME "Rx Name"
#define TR_TELEMETRY_TYPE TR("Typ", "Telemetrietyp")
+18 -14
View File
@@ -331,6 +331,7 @@
#define TR_COPYINGMODEL "Copying model..."
#define TR_MOVINGMODEL "Moving model..."
#define TR_LOADINGMODEL "Loading model..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Name"
#define TR_MODELNAME "Model name"
#define TR_PHASENAME "Mode name"
@@ -626,13 +627,20 @@
#define TR_VOLTAGE TR(INDENT "Voltage", INDENT "Voltage source")
#define TR_CURRENT TR(INDENT "Current", INDENT "Current source")
#define TR_SELECT_MODEL "Select model"
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Create category"
#define TR_RENAME_CATEGORY "Rename category"
#define TR_DELETE_CATEGORY "Delete category"
#define TR_CREATE_MODEL "Create model"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplicate model"
#define TR_COPY_MODEL "Copy model"
#define TR_MOVE_MODEL "Move model"
@@ -640,7 +648,6 @@
#define TR_DELETE_MODEL "Delete model"
#define TR_RESTORE_MODEL "Restore model"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR TR("SD error", "SD card error")
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -750,7 +757,7 @@
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:"
#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"
@@ -794,7 +801,7 @@
#define TR_PATH_TOO_LONG "Path too long"
#define TR_VIEW_TEXT "View text"
#define TR_FLASH_BOOTLOADER "Flash bootloader"
#define TR_FLASH_DEVICE TR("Flash device","Flash device")
#define TR_FLASH_DEVICE TR("Flash device","Flash device")
#define TR_FLASH_EXTERNAL_DEVICE TR("Flash S.Port", "Flash S.Port device")
#define TR_FLASH_RECEIVER_OTA "Flash receiver OTA"
#define TR_FLASH_RECEIVER_BY_EXTERNAL_MODULE_OTA "Flash RX by ext. OTA"
@@ -911,11 +918,8 @@
#define TR_TRAINER "Trainer"
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "TX antenna problem!"
#if defined(COLORLCD)
#define TR_MODELIDUSED "ID used in:"
#else
#define TR_MODELIDUSED TR("ID used in:","Receiver ID used in:")
#endif
#define TR_MODELIDUSED "ID used in:"
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Module"
#define TR_RX_NAME "Rx Name"
#define TR_TELEMETRY_TYPE TR("Type", "Telemetry type")
@@ -1300,9 +1304,9 @@
#define TR_ADD_ALL_TRIMS_TO_SUBTRIMS "Add all Trims to Subtrims"
#if LCD_W > LCD_H
#define TR_OPEN_CHANNEL_MONITORS "Open Channel Monitor"
#define TR_OPEN_CHANNEL_MONITORS "Open Channel Monitor"
#else
#define TR_OPEN_CHANNEL_MONITORS "Open Channel Mon."
#define TR_OPEN_CHANNEL_MONITORS "Open Channel Mon."
#endif
#define TR_DUPLICATE "Duplicate"
#define TR_ACTIVATE "Set Active"
+14 -6
View File
@@ -333,6 +333,7 @@
#define TR_COPYINGMODEL "Copiando modelo.."
#define TR_MOVINGMODEL "Moviendo modelo..."
#define TR_LOADINGMODEL "Cargando modelo..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Nombre"
#define TR_MODELNAME TR("Nom. modelo", "Nombre modelo")
#define TR_PHASENAME "Nombre fase "
@@ -627,13 +628,20 @@
#define TR_VOLTAGE INDENT"Voltaje"
#define TR_CURRENT INDENT"Actual"
#define TR_SELECT_MODEL TR("Selec. modelo", "Seleccionar modelo")
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Crear categoría"
#define TR_RENAME_CATEGORY "Renombrar categoría"
#define TR_DELETE_CATEGORY "Borrar categoría"
#define TR_CREATE_MODEL "Crear modelo"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplicar modelo"
#define TR_COPY_MODEL "Copiar modelo"
#define TR_MOVE_MODEL "Mover modelo"
@@ -641,7 +649,6 @@
#define TR_DELETE_MODEL "Borrar modelo"
#define TR_RESTORE_MODEL "Restaurar modelo"
#define TR_DELETE_ERROR "Error de borrado"
#define TR_CAT_NOT_EMPTY "Categoría no esta vacía"
#define TR_SDCARD_ERROR "Error SDCARD"
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -751,7 +758,7 @@
#define TR_SAMPLE_MODE "Modo de muestra"
#define TR_SAMPLE_MODES "Normal","OneBit"
#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:"
#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"
@@ -913,6 +920,7 @@
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "Problema antena TX!"
#define TR_MODELIDUSED TR("ID en uso", "ID modelo en uso")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Módulo"
#define TR_RX_NAME "Nombre Rx"
#define TR_TELEMETRY_TYPE TR("Tipo", "Tipo telemetría")
+13 -5
View File
@@ -343,6 +343,7 @@
#define TR_COPYINGMODEL "Copying model..."
#define TR_MOVINGMODEL "Moving model..."
#define TR_LOADINGMODEL "Loading model..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Name"
#define TR_MODELNAME "Model Name"
#define TR_PHASENAME "Mode Name"
@@ -641,13 +642,20 @@
#define TR_VOLTAGE INDENT"Jännite"
#define TR_CURRENT INDENT"Virta"
#define TR_SELECT_MODEL "Select Model"
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Create Category"
#define TR_RENAME_CATEGORY "Rename Category"
#define TR_DELETE_CATEGORY "Delete Category"
#define TR_CREATE_MODEL "Create Model"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplicate Model"
#define TR_COPY_MODEL "Copy Model"
#define TR_MOVE_MODEL "Move Model"
@@ -655,7 +663,6 @@
#define TR_DELETE_MODEL "Delete Model"
#define TR_RESTORE_MODEL "Restore Model"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Luokka ei ole tyhjä"
#define TR_SDCARD_ERROR "SDCARD Error"
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -926,6 +933,7 @@
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "Lähettimen antenniongelma!"
#define TR_MODELIDUSED TR("ID used in:", "Receiver ID used in:")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Module"
#define TR_RX_NAME "Rx Name"
#define TR_TELEMETRY_TYPE TR("Type", "Telemetry Type")
+14 -6
View File
@@ -353,6 +353,7 @@
#define TR_COPYINGMODEL "Copie..."
#define TR_MOVINGMODEL "Déplacement..."
#define TR_LOADINGMODEL "Chargement..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Nom"
#define TR_MODELNAME TR("Nom modèle", "Nom du modèle")
#define TR_PHASENAME "Nom phase"
@@ -646,13 +647,20 @@
#define TR_VOLTAGE TR(INDENT "Tension",INDENT "Source tension")
#define TR_CURRENT TR(INDENT "Courant",INDENT "Source courant")
#define TR_SELECT_MODEL "Sélect. modèle"
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Créer une catégorie"
#define TR_RENAME_CATEGORY "Renommer la catégorie"
#define TR_DELETE_CATEGORY "Supprimer la catégorie"
#define TR_CREATE_MODEL "Créer modèle"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Dupliquer modèle"
#define TR_COPY_MODEL "Copier modèle"
#define TR_MOVE_MODEL "Déplacer modèle"
@@ -660,7 +668,6 @@
#define TR_DELETE_MODEL "Supprimer modèle"
#define TR_RESTORE_MODEL "Restaurer modèle"
#define TR_DELETE_ERROR "Effacement impossible"
#define TR_CAT_NOT_EMPTY "Categorie non vide"
#define TR_SDCARD_ERROR "Erreur carte SD"
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -769,7 +776,7 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal""OneBit"
#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:"
#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"
@@ -930,6 +937,7 @@
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "Antenne radio défect.!"
#define TR_MODELIDUSED TR("ID affecté à :", "No de récepteur utilisé par :")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Module"
#define TR_RX_NAME "Nom Rx"
#define TR_TELEMETRY_TYPE TR("Type tél.", "Type télémétrie")
+13 -5
View File
@@ -338,6 +338,7 @@
#define TR_COPYINGMODEL "Copia in corso.."
#define TR_MOVINGMODEL "Spostamento..."
#define TR_LOADINGMODEL "Caricamento..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Nome"
#define TR_MODELNAME TR("Nome Mode.", "Nome Modello")
#define TR_PHASENAME "Nome fase"
@@ -627,13 +628,20 @@
#define TR_VOLTAGE TR(INDENT "Voltagg.",INDENT "Voltaggio")
#define TR_CURRENT TR(INDENT "Corrente",INDENT "Corrente")
#define TR_SELECT_MODEL TR("Scegli mod.", "Scegli Modello")
#define TR_MODEL_CATEGORIES "Categorie Modelli"
#define TR_MODELS "Modelli"
#define TR_SELECT_MODE "Seleziona modo"
#define TR_CREATE_CATEGORY "Crea Categoria"
#define TR_RENAME_CATEGORY "Rinomina Categoria"
#define TR_DELETE_CATEGORY "Cancella Categoria"
#define TR_CREATE_MODEL "Crea Modello"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplica Modello"
#define TR_COPY_MODEL "Copia Modello"
#define TR_MOVE_MODEL "Sposta Modello"
@@ -641,7 +649,6 @@
#define TR_DELETE_MODEL TR("Elim. Modello", "Elimina Modello")
#define TR_RESTORE_MODEL TR("Ripr. Modello", "Ripristina Modello")
#define TR_DELETE_ERROR "Errore cancell."
#define TR_CAT_NOT_EMPTY "Categoria non vuota"
#define TR_SDCARD_ERROR TR("Errore SD", "Errore SDCard")
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "SD senza file!"
@@ -912,6 +919,7 @@
#define TR_CHANS "Canali"
#define TR_ANTENNAPROBLEM CENTER "Problemi antenna TX!"
#define TR_MODELIDUSED TR("ID già usato", "ID Modello già usato")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Modulo"
#define TR_RX_NAME "Nome RX"
#define TR_TELEMETRY_TYPE "Tipo Telemetria"
+14 -6
View File
@@ -336,6 +336,7 @@
#define TR_COPYINGMODEL "Kopieer Model"
#define TR_MOVINGMODEL "Verplaats Model"
#define TR_LOADINGMODEL "Laad Model..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Naam"
#define TR_MODELNAME "Modelnaam"
#define TR_PHASENAME "Modus"
@@ -632,13 +633,20 @@
#define TR_VOLTAGE TR(INDENT "Spg", INDENT "Spanningsbron") //9XR-Pro
#define TR_CURRENT TR(INDENT "Stroom", INDENT "Stroombron")
#define TR_SELECT_MODEL "Kies Model"
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Create Category"
#define TR_RENAME_CATEGORY "Rename Category"
#define TR_DELETE_CATEGORY "Delete Category"
#define TR_CREATE_MODEL "Nieuw Model"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Dupliceer Model"
#define TR_COPY_MODEL "Kopieer Model"
#define TR_MOVE_MODEL "Verplaats Model"
@@ -646,7 +654,6 @@
#define TR_DELETE_MODEL "Wis Model"
#define TR_RESTORE_MODEL "Model Terugzetten"
#define TR_DELETE_ERROR "Fout bij verwijderen"
#define TR_CAT_NOT_EMPTY "Categorie is niet leeg"
#define TR_SDCARD_ERROR "SD-Kaart fout"
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -755,7 +762,7 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal""OneBit"
#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:"
#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"
@@ -916,6 +923,7 @@
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "TX-Antenneprobleem!"
#define TR_MODELIDUSED TR("ID al gebruikt", "Model-ID al gebruikt")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Module-Type"
#define TR_RX_NAME "Rx Name"
#define TR_TELEMETRY_TYPE TR("Type", "Telemetrietype")
+14 -6
View File
@@ -333,6 +333,7 @@
#define TR_COPYINGMODEL "Kopiuj model.."
#define TR_MOVINGMODEL "Przenieś model."
#define TR_LOADINGMODEL "Załaduj model.."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Nazwa"
#define TR_MODELNAME "Nazwa modelu"
#define TR_PHASENAME "Nazwa Fazy"
@@ -623,13 +624,20 @@
#define TR_VOLTAGE TR (INDENT"Napięcie",INDENT"Źródło Napięcia")
#define TR_CURRENT TR (INDENT"Prąd",INDENT"Źródło Prądu")
#define TR_SELECT_MODEL "Wybór modelu"
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Create Category"
#define TR_RENAME_CATEGORY "Rename Category"
#define TR_DELETE_CATEGORY "Delete Category"
#define TR_CREATE_MODEL "Nowy model"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplicate Model"
#define TR_COPY_MODEL "Skopiuj model"
#define TR_MOVE_MODEL "Przenieś model"
@@ -637,7 +645,6 @@
#define TR_DELETE_MODEL "Skasuj model"
#define TR_RESTORE_MODEL "Odtwórz model"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "Błąd karty SD"
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -746,7 +753,7 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:"
#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"
@@ -907,6 +914,7 @@
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "Problem z anteną TX"
#define TR_MODELIDUSED TR("ID zajęte","ID modelu zajęte")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Moduł "
#define TR_RX_NAME "Rx Name"
#define TR_TELEMETRY_TYPE TR("Typ ", "Typ Telemetrii")
+14 -6
View File
@@ -330,6 +330,7 @@
#define TR_COPYINGMODEL "Copiando modelo"
#define TR_MOVINGMODEL "Movendo modelo"
#define TR_LOADINGMODEL "Carregar modelo"
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Nome"
#define TR_MODELNAME "Model Name"
#define TR_PHASENAME "Phase Name"
@@ -628,13 +629,20 @@
#define TR_VOLTAGE INDENT"Volts"
#define TR_CURRENT INDENT"Amperes"
#define TR_SELECT_MODEL "Selec. Modelo"
#define TR_MODEL_CATEGORIES "Model Categories"
#define TR_MODELS "Models"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Create Category"
#define TR_RENAME_CATEGORY "Rename Category"
#define TR_DELETE_CATEGORY "Delete Category"
#define TR_CREATE_MODEL "Criar Modelo"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplicate Model"
#define TR_COPY_MODEL "Copy Model"
#define TR_MOVE_MODEL "Move Model"
@@ -642,7 +650,6 @@
#define TR_DELETE_MODEL "Apagar Modelo"
#define TR_RESTORE_MODEL "Restaura Modelo"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "SDCARD Erro"
#define TR_SDCARD "SD Card"
#define TR_NO_FILES_ON_SD "No files on SD!"
@@ -751,7 +758,7 @@
#define TR_BAUDRATE "Baudrate"
#define TR_SAMPLE_MODE "Sample Mode"
#define TR_SAMPLE_MODES "Normal","OneBit"
#define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:"
#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"
@@ -912,6 +919,7 @@
#define TR_CHANS "Chans"
#define TR_ANTENNAPROBLEM CENTER "TX Antenna problem!"
#define TR_MODELIDUSED TR("ID used in:", "Receiver ID used in:")
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Module"
#define TR_RX_NAME "Rx Name"
#define TR_TELEMETRY_TYPE TR("Type", "Telemetry Type")
+14 -10
View File
@@ -354,6 +354,7 @@
#define TR_COPYINGMODEL "Kopierar..."
#define TR_MOVINGMODEL "Flyttar..."
#define TR_LOADINGMODEL "Laddar..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "Namn"
#define TR_MODELNAME "Modellnamn"
#define TR_PHASENAME "Lägesnamn"
@@ -653,13 +654,20 @@
#define TR_VOLTAGE INDENT"Volt"
#define TR_CURRENT INDENT"Ampere"
#define TR_SELECT_MODEL "Välj modell"
#define TR_MODEL_CATEGORIES "Modellkategori"
#define TR_MODELS "Modeller"
#define TR_SELECT_MODE "Select mode"
#define TR_CREATE_CATEGORY "Skapa kategori"
#define TR_RENAME_CATEGORY "Byt kategorinamn"
#define TR_DELETE_CATEGORY "Ta bort kategori"
#define TR_CREATE_MODEL "Skapa modell"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "Duplicera modell"
#define TR_COPY_MODEL "Kopiera modell"
#define TR_MOVE_MODEL "Flytta modell"
@@ -667,7 +675,6 @@
#define TR_DELETE_MODEL "Ta bort modell"
#define TR_RESTORE_MODEL "Återställ modell"
#define TR_DELETE_ERROR "Delete error"
#define TR_CAT_NOT_EMPTY "Category is not empty"
#define TR_SDCARD_ERROR "SD-kortfel"
#define TR_SDCARD "SD-kort"
#define TR_NO_FILES_ON_SD "Inga filer på SD!"
@@ -941,11 +948,8 @@
#define TR_TRAINER "Lärare"
#define TR_CHANS "Kan"
#define TR_ANTENNAPROBLEM CENTER "Fel på TX-antennen"
#if defined(COLORLCD)
#define TR_MODELIDUSED "ID använt i:"
#else
#define TR_MODELIDUSED TR("ID använt i:","Mottagar-ID använt i:")
#endif
#define TR_MODELIDUSED "ID använt i:"
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "Modul"
#define TR_RX_NAME "RX namn"
#define TR_TELEMETRY_TYPE "Telemetrityp"
+15 -11
View File
@@ -331,6 +331,7 @@
#define TR_COPYINGMODEL "複製模型..."
#define TR_MOVINGMODEL "移動模型..."
#define TR_LOADINGMODEL "載入模型..."
#define TR_UNLABELEDMODEL "Unlabeled"
#define TR_NAME "名稱"
#define TR_MODELNAME "模型名稱"
#define TR_PHASENAME "模式名稱"
@@ -626,13 +627,20 @@
#define TR_VOLTAGE TR(INDENT "電壓源", INDENT "電壓來源")
#define TR_CURRENT TR(INDENT "電流源", INDENT "電流來源")
#define TR_SELECT_MODEL "選擇模型"
#define TR_MODEL_CATEGORIES "模型分類"
#define TR_MODELS "個模型"
#define TR_SELECT_MODE "選擇模式"
#define TR_CREATE_CATEGORY "創建分類"
#define TR_RENAME_CATEGORY "分類改名"
#define TR_DELETE_CATEGORY "刪除分類"
#define TR_CREATE_MODEL "創建模型"
#define TR_FAVORITE_LABEL "Favorites"
#define TR_NEW_MODEL "New Model"
#define TR_EDIT_LABELS "Edit Labels"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_LABELS "Labels"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"
#define TR_DUPLICATE_MODEL "複製模型"
#define TR_COPY_MODEL "複製模型"
#define TR_MOVE_MODEL "移動模型"
@@ -640,7 +648,6 @@
#define TR_DELETE_MODEL "刪除模型"
#define TR_RESTORE_MODEL "恢復模型"
#define TR_DELETE_ERROR "刪除失敗"
#define TR_CAT_NOT_EMPTY "分類未清空"
#define TR_SDCARD_ERROR TR("存儲卡錯誤", "存儲卡錯誤")
#define TR_SDCARD "存儲卡"
#define TR_NO_FILES_ON_SD "存儲卡中沒有文件!"
@@ -911,11 +918,8 @@
#define TR_TRAINER "教練"
#define TR_CHANS "通道"
#define TR_ANTENNAPROBLEM CENTER "發射機天線故障!"
#if defined(COLORLCD)
#define TR_MODELIDUSED "ID已使用:"
#else
#define TR_MODELIDUSED TR("ID已使用:","ID已使用:")
#endif
#define TR_MODELIDUSED "ID已使用:"
#define TR_MODELIDUNIQUE "ID is unique"
#define TR_MODULE "模塊"
#define TR_RX_NAME "接收機名稱"
#define TR_TELEMETRY_TYPE TR("類型", "回傳類型")
@@ -1334,4 +1338,4 @@
#define TR_PROTOCOL "協議"
#define TR_YEAR "年"
#define TR_MONTH "月"
#define TR_DAY "日"
#define TR_DAY "日"
+9
View File
@@ -371,3 +371,12 @@
#define STR_HOTT_ID_EAM_VV "EAvv"
#define STR_HOTT_ID_EAM_RPM "EArp"
#define STR_HOTT_ID_EAM_SPEED "EAsp"
#define TR_ENTER_LABEL "Enter Label"
#define TR_LABEL "Label"
#define TR_NONE "None"
#define TR_CURRENT_MODEL "Current"
#define TR_NEW "New"
#define TR_NEW_LABEL "New Label"
#define TR_RENAME_LABEL "Rename Label"
#define TR_DELETE_LABEL "Delete Label"