diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 47c5f4657bb..3a27b49d7ab 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -972,6 +972,12 @@ PACK(struct RadioData { NOBACKUP(uint8_t modelCustomScriptsDisabled:1); NOBACKUP(uint8_t modelTelemetryDisabled:1); +#if defined(COLORLCD) + uint8_t labelSingleSelect:1; // 0 = multi-select, 1 = single select labels + uint8_t labelMultiMode:1; // 0 = match all labels (AND), 1 = match any labels (OR) + uint8_t favMultiMode:1; // 0 = match all (AND), 1 = match any (OR) +#endif + NOBACKUP(uint8_t getBrightness() const { #if defined(OLED_SCREEN) diff --git a/radio/src/gui/colorlcd/listbox.cpp b/radio/src/gui/colorlcd/listbox.cpp index 4a95701288d..e8ab986235a 100644 --- a/radio/src/gui/colorlcd/listbox.cpp +++ b/radio/src/gui/colorlcd/listbox.cpp @@ -102,9 +102,9 @@ void ListBase::setLineHeight(uint8_t height) lv_obj_set_style_max_height(lvobj, height, LV_PART_ITEMS); } -void ListBase::setSelected(int selected) +void ListBase::setSelected(int selected, bool force) { - select(selected, 0); + select(selected, 0, force); } void ListBase::setSelected(std::set selected) @@ -127,6 +127,11 @@ int ListBase::getSelected() const return -1; } +bool ListBase::isRowSelected(uint16_t row) +{ + return lv_table_has_cell_ctrl(lvobj, row, 0, LV_TABLE_CELL_CTRL_CUSTOM_1); +} + std::set ListBase::getSelection() { if(!multiSelect) return std::set(); @@ -212,9 +217,13 @@ void ListBase::onDrawEnd(uint16_t row, uint16_t col, lv_obj_draw_part_dsc_t* dsc lv_coord_t font_h = getFontHeight(FONT(STD)); coords.x1 = dsc->draw_area->x2 - cell_right - font_h; - coords.x2 = coords.x1 + font_h; + coords.x2 = coords.x1 + 36; coords.y1 = dsc->draw_area->y1 + (area_h - font_h) / 2; coords.y2 = coords.y1 + font_h - 1; - lv_draw_label(dsc->draw_ctx, dsc->label_dsc, &coords, LV_SYMBOL_OK, nullptr); + const char* sym = LV_SYMBOL_OK; + if (getSelectedSymbol) + sym = getSelectedSymbol(row); + + lv_draw_label(dsc->draw_ctx, dsc->label_dsc, &coords, sym, nullptr); } diff --git a/radio/src/gui/colorlcd/listbox.h b/radio/src/gui/colorlcd/listbox.h index ea0d59ad0ee..e2ba848a8f6 100644 --- a/radio/src/gui/colorlcd/listbox.h +++ b/radio/src/gui/colorlcd/listbox.h @@ -36,6 +36,7 @@ class ListBase : public TableField std::function longPressHandler = nullptr; std::function pressHandler = nullptr; std::function, std::set)> _multiSelectHandler = nullptr; + std::function getSelectedSymbol = nullptr; bool autoEdit = false; public: @@ -49,10 +50,11 @@ class ListBase : public TableField void setNames(const std::vector& names); void setLineHeight(uint8_t height); - virtual void setSelected(int selected); + virtual void setSelected(int selected, bool force = false); virtual void setSelected(std::set selected); int getSelected() const; + bool isRowSelected(uint16_t row); std::set getSelection(); void setMultiSelect(bool mode) { @@ -67,6 +69,11 @@ class ListBase : public TableField _multiSelectHandler = std::move(handler); } + void setGetSelectedSymbol(std::function handler) + { + getSelectedSymbol = std::move(handler); + } + void setLongPressHandler(std::function handler) { longPressHandler = std::move(handler); diff --git a/radio/src/gui/colorlcd/model_select.cpp b/radio/src/gui/colorlcd/model_select.cpp index 792f277a1eb..46c48f9f9e7 100644 --- a/radio/src/gui/colorlcd/model_select.cpp +++ b/radio/src/gui/colorlcd/model_select.cpp @@ -604,26 +604,38 @@ void ModelLabelsWindow::onLongPressTELE() } void ModelLabelsWindow::onPressPG(bool isNext) { - std::set curSel = lblselector->getSelection(); - std::set sellist; - int select = 0; int rowcount = lblselector->getRowCount(); + std::set sellist; + int select = -1; + + if (g_eeGeneral.labelSingleSelect) { + select = lblselector->getActiveItem(); + } else { + std::set sel = lblselector->getSelection(); + if (sel.size()) { + if (isNext) + select = *sel.rbegin(); + else + select = *sel.begin(); + } + } if (isNext) { - if (curSel.size()) select = (*curSel.rbegin() + 1) % rowcount; + select = (select + 1) % rowcount; } else { - if (curSel.size()) { - select = (int)*curSel.begin() - 1; - if (select < 0) select += rowcount; - } else { + select = select - 1; + if (select < 0) select = rowcount - 1; - } } - sellist.insert(select); + if (g_eeGeneral.labelSingleSelect) + lblselector->setActiveItem(select); + + if (select >= 0) + sellist.insert(select); lblselector->setSelected(sellist); // Check the items - lblselector->setSelected(-1); // Force update - lblselector->setSelected(select); // Causes the list to scroll + lblselector->setSelected(select, true); // Causes the list to scroll + updateFilteredLabels(sellist); // Update the models } void ModelLabelsWindow::onPressPGUP() { onPressPG(false); } @@ -789,32 +801,73 @@ void ModelLabelsWindow::buildBody(FormWindow *window) lv_obj_update_layout(mdl_obj); lblselector->setColumnWidth(0, lv_obj_get_content_width(lbl_obj)); - lblselector->setMultiSelect(true); - lblselector->setSelected(modelslabels.filteredLabels()); - updateFilteredLabels(modelslabels.filteredLabels(), false); lv_obj_set_scrollbar_mode(lbl_obj, LV_SCROLLBAR_MODE_AUTO); lv_obj_set_scrollbar_mode(mdl_obj, LV_SCROLLBAR_MODE_AUTO); - lblselector->setMultiSelectHandler([=](std::set selected, - std::set oldselection) { - if (modelslabels.getUnlabeledModels().size() != 0) { - // Special case for mutually exclusive Unsorted - bool unsrt_is_selected = - selected.find(lblselector->getRowCount() - 1) != selected.end(); - bool unsrt_was_selected = oldselection.find(lblselector->getRowCount() - - 1) != oldselection.end(); - - // Unsorted was just picked - if (unsrt_is_selected && !unsrt_was_selected) { - selected.clear(); - selected.insert(lblselector->getRowCount() - 1); - } else if (unsrt_is_selected && unsrt_was_selected) { - selected.erase(selected.find(lblselector->getRowCount() - 1)); + std::set filteredLabels = modelslabels.filteredLabels(); + + if (g_eeGeneral.labelSingleSelect == 0) { + lblselector->setMultiSelect(true); + lblselector->setSelected(filteredLabels); + lblselector->setMultiSelectHandler([=](std::set selected, + std::set oldselection) { + if (modelslabels.getUnlabeledModels().size() != 0) { + // Special case for mutually exclusive Unsorted + bool unsrt_is_selected = + selected.find(lblselector->getRowCount() - 1) != selected.end(); + bool unsrt_was_selected = oldselection.find(lblselector->getRowCount() - + 1) != oldselection.end(); + + // Unsorted was just picked + if (unsrt_is_selected && !unsrt_was_selected) { + selected.clear(); + selected.insert(lblselector->getRowCount() - 1); + } else if (unsrt_is_selected && unsrt_was_selected) { + selected.erase(selected.find(lblselector->getRowCount() - 1)); + } } - } - lblselector->setSelected(selected); - updateFilteredLabels(selected); + lblselector->setSelected(selected); + updateFilteredLabels(selected); + }); + } else { + if (filteredLabels.size() > 0) + lblselector->setActiveItem(*filteredLabels.begin()); + lblselector->setPressHandler([=]() { + int item = lblselector->getActiveItem(); + int selected = lblselector->getSelected(); + std::set newset; + // Clicking active label unselects it and selects all models + if (selected == item) { + lblselector->setActiveItem(-1); + } else { + lblselector->setActiveItem(selected); + newset.insert(selected); + } + updateFilteredLabels(newset); + }); + } + + updateFilteredLabels(filteredLabels, false); + + lblselector->setGetSelectedSymbol([=](uint16_t row) { + if (g_eeGeneral.labelSingleSelect) + return LV_SYMBOL_OK; + if (lblselector->getSelection().size() == 1) + return LV_SYMBOL_OK; + bool hasMoreSelections = false; + for (uint16_t i = row + 1; i < lblselector->getRowCount(); i += 1) + if (lblselector->isRowSelected(i)) { + hasMoreSelections = true; + break; + } + if (!hasMoreSelections) + return LV_SYMBOL_OK; + if (row == 0 && (g_eeGeneral.labelMultiMode == 0 || g_eeGeneral.favMultiMode == 0)) + return STR_VCSWFUNC[7]; // AND + if (g_eeGeneral.labelMultiMode == 0) + return STR_VCSWFUNC[7]; // AND + return STR_VCSWFUNC[8]; // OR }); lblselector->setLongPressHandler([=]() { diff --git a/radio/src/gui/colorlcd/radio_setup.cpp b/radio/src/gui/colorlcd/radio_setup.cpp index 0821b0013ba..7ab26ff3636 100644 --- a/radio/src/gui/colorlcd/radio_setup.cpp +++ b/radio/src/gui/colorlcd/radio_setup.cpp @@ -25,6 +25,7 @@ #include "opentx.h" #include "libopenui.h" #include "input_mapping.h" +#include "storage/modelslist.h" #include "tasks/mixer_task.h" #include "hal/adc_driver.h" @@ -677,6 +678,71 @@ class ViewOptionsPage : public SubPage } }; +class ManageModelsSetupPage : public SubPage +{ + public: + ManageModelsSetupPage() : SubPage(ICON_MODEL, STR_MANAGE_MODELS, false) + { + FlexGridLayout grid(col_two_dsc, row_dsc, 2); + + auto form = new FormWindow(&body, rect_t{}); + form->setFlexLayout(); + form->padAll(0); + + // Model quick select + auto line = form->newLine(&grid); + new StaticText(line, rect_t{}, STR_MODEL_QUICK_SELECT, 0, + COLOR_THEME_PRIMARY1); + new ToggleSwitch(line, rect_t{}, + GET_SET_DEFAULT(g_eeGeneral.modelQuickSelect)); + + // Label single/multi select + line = form->newLine(&grid); + new StaticText(line, rect_t{}, STR_LABELS_SELECT, 0, COLOR_THEME_PRIMARY1); + new Choice(line, rect_t{}, STR_LABELS_SELECT_MODE, 0, 1, + GET_DEFAULT(g_eeGeneral.labelSingleSelect), + [=](int newValue) { + g_eeGeneral.labelSingleSelect = newValue; + modelslabels.clearFilter(); + SET_DIRTY(); + }); + + // Label multi select matching mode + multiSelectMatch = form->newLine(&grid); + new StaticText(multiSelectMatch, rect_t{}, STR_LABELS_MATCH, 0, + COLOR_THEME_PRIMARY1); + new Choice(multiSelectMatch, rect_t{}, STR_LABELS_MATCH_MODE, 0, 1, + GET_SET_DEFAULT(g_eeGeneral.labelMultiMode)); + + // Favorites multi select matching mode + favSelectMatch = form->newLine(&grid); + new StaticText(favSelectMatch, rect_t{}, STR_FAV_MATCH, 0, + COLOR_THEME_PRIMARY1); + new Choice(favSelectMatch, rect_t{}, STR_FAV_MATCH_MODE, 0, 1, + GET_SET_DEFAULT(g_eeGeneral.favMultiMode)); + + checkEvents(); + } + + void checkEvents() override + { + if (g_eeGeneral.labelSingleSelect) { + lv_obj_add_flag(multiSelectMatch->getLvObj(), LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(favSelectMatch->getLvObj(), LV_OBJ_FLAG_HIDDEN); + } else { + lv_obj_clear_flag(multiSelectMatch->getLvObj(), LV_OBJ_FLAG_HIDDEN); + if (g_eeGeneral.labelMultiMode == 0) + lv_obj_add_flag(favSelectMatch->getLvObj(), LV_OBJ_FLAG_HIDDEN); + else + lv_obj_clear_flag(favSelectMatch->getLvObj(), LV_OBJ_FLAG_HIDDEN); + } + } + + protected: + Window* multiSelectMatch = nullptr; + Window* favSelectMatch = nullptr; +}; + RadioSetupPage::RadioSetupPage(): PageTab(STR_RADIO_SETUP, ICON_RADIO_SETUP) { @@ -690,6 +756,10 @@ void RadioSetupPage::build(FormWindow * window) // Date & time picker including labels new DateTimeWindow(window, rect_t{}); + // TODO: sort out all caps title strings VS quick menu strings + std::string manageModelsTitle(STR_MAIN_MENU_MANAGE_MODELS); + std::replace(manageModelsTitle.begin(), manageModelsTitle.end(), '\n', ' '); + // Sub-pages new WindowButtonGroup(window, rect_t{}, { {STR_SOUND_LABEL, []() { new SoundPage(); }}, @@ -703,6 +773,7 @@ void RadioSetupPage::build(FormWindow * window) {STR_BACKLIGHT_LABEL, []() { new BacklightPage(); }}, {STR_GPS, [](){new GpsPage();}}, {STR_ENABLED_FEATURES, [](){new ViewOptionsPage();}}, + {manageModelsTitle.c_str(), []() { new ManageModelsSetupPage(); }}, }); // Splash screen @@ -867,9 +938,4 @@ void RadioSetupPage::build(FormWindow * window) std::string(getMainControlLabel(stick0)) + "+" + std::string(getMainControlLabel(stick1)); }); - - // Model quick select - line = window->newLine(&grid); - new StaticText(line, rect_t{}, STR_MODEL_QUICK_SELECT, 0, COLOR_THEME_PRIMARY1); - new ToggleSwitch(line, rect_t{}, GET_SET_DEFAULT(g_eeGeneral.modelQuickSelect)); } diff --git a/radio/src/storage/modelslist.cpp b/radio/src/storage/modelslist.cpp index ddd59798bae..ca0260cbc5b 100644 --- a/radio/src/storage/modelslist.cpp +++ b/radio/src/storage/modelslist.cpp @@ -210,7 +210,7 @@ ModelsVector ModelMap::getModelsByLabels(const LabelsVector &lbls) } /** - * @brief Returns all models that are in multiple labels (AND function) + * @brief Returns all models that match the selected labels * * @param lbls Labels to search * @return ModelsVector aka vector of all models belonging to a @@ -229,17 +229,37 @@ ModelsVector ModelMap::getModelsInLabels(const LabelsVector &lbls) for (const auto &mdl : modelslist) { bool hasAllLabels = true; + bool hasAnyLabels = false; + bool favLabelIncluded = false; + bool hasFavLabel = false; LabelsVector mdllables = getLabelsByModel(mdl); for (const auto &lbl : lbls) { if (lbl == STR_UNLABELEDMODEL) // If requesting unlabeled model ignore it break; - if (std::find(mdllables.begin(), mdllables.end(), lbl) == - mdllables.end()) { - hasAllLabels = false; - break; + bool hasLabel = std::find(mdllables.begin(), mdllables.end(), lbl) != mdllables.end(); + if (lbl == STR_FAVORITE_LABEL) { + favLabelIncluded = true; + hasFavLabel = hasLabel; + } else { + if (hasLabel) { + hasAnyLabels = true; + } else { + hasAllLabels = false; + } + } + } + if (favLabelIncluded) { + if (g_eeGeneral.favMultiMode == 0) { + hasAnyLabels = hasAnyLabels && hasFavLabel; + hasAllLabels = hasAllLabels && hasFavLabel; + } else if (g_eeGeneral.favMultiMode == 1) { + hasAnyLabels = hasAnyLabels || hasFavLabel; + hasAllLabels = hasAllLabels && hasFavLabel; } } - if (hasAllLabels) rv.push_back(mdl); + if (((g_eeGeneral.labelMultiMode == 0) && hasAllLabels) || + ((g_eeGeneral.labelMultiMode == 1) && hasAnyLabels)) + rv.push_back(mdl); } sortModelsBy(rv, _sortOrder); diff --git a/radio/src/storage/modelslist.h b/radio/src/storage/modelslist.h index 34235d4055a..98c5485020e 100644 --- a/radio/src/storage/modelslist.h +++ b/radio/src/storage/modelslist.h @@ -157,6 +157,7 @@ class ModelMap : protected std::multimap { this->filtlbls = std::move(filtlbls); } + void clearFilter() { filtlbls.clear(); } void addFilteredLabel(const std::string &lbl); bool isLabelFiltered(const std::string &lbl); std::set filteredLabels() { return filtlbls; } diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index 99636753747..cb00ce40469 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -379,6 +379,9 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelSFDisabled", 1 ), YAML_UNSIGNED( "modelCustomScriptsDisabled", 1 ), YAML_UNSIGNED( "modelTelemetryDisabled", 1 ), + YAML_UNSIGNED( "labelSingleSelect", 1 ), + YAML_UNSIGNED( "labelMultiMode", 1 ), + YAML_UNSIGNED( "favMultiMode", 1 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp index 7b3aa92091f..78cd8e650ff 100644 --- a/radio/src/storage/yaml/yaml_datastructs_pl18.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_pl18.cpp @@ -379,6 +379,9 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelSFDisabled", 1 ), YAML_UNSIGNED( "modelCustomScriptsDisabled", 1 ), YAML_UNSIGNED( "modelTelemetryDisabled", 1 ), + YAML_UNSIGNED( "labelSingleSelect", 1 ), + YAML_UNSIGNED( "labelMultiMode", 1 ), + YAML_UNSIGNED( "favMultiMode", 1 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index abbfb21f809..1c7c459ea27 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -381,6 +381,9 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelSFDisabled", 1 ), YAML_UNSIGNED( "modelCustomScriptsDisabled", 1 ), YAML_UNSIGNED( "modelTelemetryDisabled", 1 ), + YAML_UNSIGNED( "labelSingleSelect", 1 ), + YAML_UNSIGNED( "labelMultiMode", 1 ), + YAML_UNSIGNED( "favMultiMode", 1 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp index abbfb21f809..1c7c459ea27 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp @@ -381,6 +381,9 @@ static const struct YamlNode struct_RadioData[] = { YAML_UNSIGNED( "modelSFDisabled", 1 ), YAML_UNSIGNED( "modelCustomScriptsDisabled", 1 ), YAML_UNSIGNED( "modelTelemetryDisabled", 1 ), + YAML_UNSIGNED( "labelSingleSelect", 1 ), + YAML_UNSIGNED( "labelMultiMode", 1 ), + YAML_UNSIGNED( "favMultiMode", 1 ), YAML_END }; static const struct YamlNode struct_unsigned_8[] = { diff --git a/radio/src/thirdparty/libopenui/src/table.cpp b/radio/src/thirdparty/libopenui/src/table.cpp index 00ccdd91a1e..ec9f125a237 100644 --- a/radio/src/thirdparty/libopenui/src/table.cpp +++ b/radio/src/thirdparty/libopenui/src/table.cpp @@ -169,20 +169,19 @@ coord_t TableField::getColumnWidth(uint16_t col) const return lv_table_get_col_width(lvobj, col); } -void TableField::select(uint16_t row, uint16_t col) +void TableField::select(uint16_t row, uint16_t col, bool force) { lv_table_t* table = (lv_table_t*)lvobj; - if (table->row_act == row && table->col_act == row) return; + if (!force && table->row_act == row && table->col_act == row) return; if (row >= table->row_cnt || col >= table->col_cnt) { table->col_act = LV_TABLE_CELL_NONE; table->row_act = LV_TABLE_CELL_NONE; - return; + } else { + table->row_act = row; + table->col_act = col; } - table->row_act = row; - table->col_act = col; - lv_obj_invalidate(lvobj); adjustScroll(); } diff --git a/radio/src/thirdparty/libopenui/src/table.h b/radio/src/thirdparty/libopenui/src/table.h index 636b143894c..ca3afe4f93b 100644 --- a/radio/src/thirdparty/libopenui/src/table.h +++ b/radio/src/thirdparty/libopenui/src/table.h @@ -39,7 +39,7 @@ class TableField : public Window void setColumnWidth(uint16_t col, coord_t w); coord_t getColumnWidth(uint16_t col) const; - void select(uint16_t row, uint16_t col); + void select(uint16_t row, uint16_t col, bool force = false); virtual void onPress(uint16_t row, uint16_t col) {} protected: diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index b3d82912af3..44cfaec6cc0 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -794,6 +794,12 @@ const char STR_SAVE_THEME[] = TR_SAVE_THEME; const char STR_EDIT_COLOR[] = TR_EDIT_COLOR; const char STR_NO_THEME_IMAGE[] = TR_NO_THEME_IMAGE; const char STR_BACKLIGHT_TIMER[] = TR_BACKLIGHT_TIMER; +const char STR_LABELS_SELECT[] = TR_LABELS_SELECT; +const char STR_LABELS_MATCH[] = TR_LABELS_MATCH; +const char STR_FAV_MATCH[] = TR_FAV_MATCH; +ISTR(LABELS_SELECT_MODE); +ISTR(LABELS_MATCH_MODE); +ISTR(FAV_MATCH_MODE); #endif #if !defined(COLORLCD) diff --git a/radio/src/translations.h b/radio/src/translations.h index 57b4f409539..83592912132 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -813,6 +813,12 @@ extern const char STR_SAVE_THEME[]; extern const char STR_EDIT_COLOR[]; extern const char STR_NO_THEME_IMAGE[]; extern const char STR_BACKLIGHT_TIMER[]; +extern const char STR_LABELS_SELECT[]; +extern const char STR_LABELS_MATCH[]; +extern const char STR_FAV_MATCH[]; +extern const char* const STR_LABELS_SELECT_MODE[]; +extern const char* const STR_LABELS_MATCH_MODE[]; +extern const char* const STR_FAV_MATCH_MODE[]; #endif extern const char STR_EXECUTE_FILE[]; extern const char STR_DELETE_FILE[]; diff --git a/radio/src/translations/cn.h b/radio/src/translations/cn.h index be0367cf4ec..7e33127c13d 100644 --- a/radio/src/translations/cn.h +++ b/radio/src/translations/cn.h @@ -702,6 +702,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "快速选择模型" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "选择一个模板文件夹:" diff --git a/radio/src/translations/cz.h b/radio/src/translations/cz.h index 0c191a7046c..6958cd016b9 100644 --- a/radio/src/translations/cz.h +++ b/radio/src/translations/cz.h @@ -719,6 +719,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Rychlý výběr modelu" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "VYBRAT SLOŽKU SE ŠABLONOU:" diff --git a/radio/src/translations/da.h b/radio/src/translations/da.h index 784deb65b45..52e592b5a6c 100644 --- a/radio/src/translations/da.h +++ b/radio/src/translations/da.h @@ -717,6 +717,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Hurtigvalg af model" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "VÆLG EN SKABELON MAPPE:" diff --git a/radio/src/translations/de.h b/radio/src/translations/de.h index 2d9444cea49..660855e801d 100644 --- a/radio/src/translations/de.h +++ b/radio/src/translations/de.h @@ -712,6 +712,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "schnelle Modellauswahl" + #define TR_LABELS_SELECT "Labelauswahl" + #define TR_LABELS_MATCH "Labelvergleich" + #define TR_FAV_MATCH "Favoriten vergleichen" + #define TR_LABELS_SELECT_MODE "Mehrfachauswahl", "Einfachauswahl" + #define TR_LABELS_MATCH_MODE "Alle", "Beliebig" + #define TR_FAV_MATCH_MODE "Muss übereinstimmen", "Alternative Übereinstimmung" #endif #define TR_SELECT_TEMPLATE_FOLDER "WÄHLE VORLAGENVERZEICHNIS:" diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h index a74baab9b71..b828a1bff03 100644 --- a/radio/src/translations/en.h +++ b/radio/src/translations/en.h @@ -717,6 +717,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Model quick select" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Select a template folder" diff --git a/radio/src/translations/es.h b/radio/src/translations/es.h index e17a8e1b2f9..a4c350ad98e 100644 --- a/radio/src/translations/es.h +++ b/radio/src/translations/es.h @@ -708,6 +708,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Model quick select" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Select a template folder" diff --git a/radio/src/translations/fi.h b/radio/src/translations/fi.h index 820daf96d6e..d20dba21135 100644 --- a/radio/src/translations/fi.h +++ b/radio/src/translations/fi.h @@ -723,6 +723,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Mallin pikavalinta" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "SELECT A TEMPLATE FOLDER:" diff --git a/radio/src/translations/fr.h b/radio/src/translations/fr.h index fd634fbfaed..f7692589667 100644 --- a/radio/src/translations/fr.h +++ b/radio/src/translations/fr.h @@ -716,6 +716,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Sélect. rapide modèle" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Sélect. dossier de modèles" diff --git a/radio/src/translations/he.h b/radio/src/translations/he.h index 412ed697170..822b76f235b 100644 --- a/radio/src/translations/he.h +++ b/radio/src/translations/he.h @@ -716,6 +716,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "בחירת מודל מהירה" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "בחר ספרית תבנית" diff --git a/radio/src/translations/it.h b/radio/src/translations/it.h index 1fe53a5ad5b..fa79d2bf160 100644 --- a/radio/src/translations/it.h +++ b/radio/src/translations/it.h @@ -711,6 +711,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Selezione rapida modello" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Seleziona Cartella Template:" diff --git a/radio/src/translations/jp.h b/radio/src/translations/jp.h index e4edcb3bda3..5446ccd92ce 100644 --- a/radio/src/translations/jp.h +++ b/radio/src/translations/jp.h @@ -707,6 +707,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "モデル クイックセレクト" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "テンプレートフォルダを選択:" diff --git a/radio/src/translations/nl.h b/radio/src/translations/nl.h index 4c7f5ea6711..19af3d0652c 100644 --- a/radio/src/translations/nl.h +++ b/radio/src/translations/nl.h @@ -709,6 +709,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Model quick select" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Select a template folder" diff --git a/radio/src/translations/pl.h b/radio/src/translations/pl.h index 5aafb1a0150..f1ea2f1c850 100644 --- a/radio/src/translations/pl.h +++ b/radio/src/translations/pl.h @@ -705,6 +705,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Szybki wybór modelu" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Wybierz folder szablonu" diff --git a/radio/src/translations/pt.h b/radio/src/translations/pt.h index 1732fdda2ff..850f47c7436 100644 --- a/radio/src/translations/pt.h +++ b/radio/src/translations/pt.h @@ -715,6 +715,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Sel rapida modelo" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Select a template folder" diff --git a/radio/src/translations/ru.h b/radio/src/translations/ru.h index 156da7a05ef..ff9c4e8c585 100644 --- a/radio/src/translations/ru.h +++ b/radio/src/translations/ru.h @@ -714,6 +714,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Быстрый выбор модели" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "Выберите папку шаблона" diff --git a/radio/src/translations/se.h b/radio/src/translations/se.h index 2f5634ec84b..1e3fd381aec 100644 --- a/radio/src/translations/se.h +++ b/radio/src/translations/se.h @@ -728,6 +728,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "Snabbval av modell" + #define TR_LABELS_SELECT "Etikettval" + #define TR_LABELS_MATCH "Etikettmatchning" + #define TR_FAV_MATCH "Matcha favoriter" + #define TR_LABELS_SELECT_MODE "Flerval","Enskilt val" + #define TR_LABELS_MATCH_MODE "Matcha alla","Matcha någon" + #define TR_FAV_MATCH_MODE "Måste matcha","Alternativt matcha" #endif #define TR_SELECT_TEMPLATE_FOLDER "VÄLJ MALLKATALOG" diff --git a/radio/src/translations/tw.h b/radio/src/translations/tw.h index 65263df62fa..a2a19ccc32f 100644 --- a/radio/src/translations/tw.h +++ b/radio/src/translations/tw.h @@ -707,6 +707,12 @@ #if defined(COLORLCD) #define TR_MODEL_QUICK_SELECT "快速選擇模型" + #define TR_LABELS_SELECT "Label select" + #define TR_LABELS_MATCH "Label matching" + #define TR_FAV_MATCH "Favorites matching" + #define TR_LABELS_SELECT_MODE "Multi select","Single select" + #define TR_LABELS_MATCH_MODE "Match all","Match any" + #define TR_FAV_MATCH_MODE "Must match","Optional match" #endif #define TR_SELECT_TEMPLATE_FOLDER "選擇一個樣板檔案夾:"