Merge pull request #926 from alvinhochun/translation-refactor
Change internal representation of translation strings
This commit is contained in:
@@ -11,7 +11,8 @@ import sys
|
||||
from datetime import datetime
|
||||
from itertools import chain
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, TextIO, Tuple, Union
|
||||
from typing import Dict, List, Optional, TextIO, Tuple, Union
|
||||
from dataclasses import dataclass
|
||||
|
||||
from bdflib import reader as bdfreader
|
||||
from bdflib.model import Font, Glyph
|
||||
@@ -78,7 +79,7 @@ def write_start(f: TextIO):
|
||||
f.write('#include "Translation.h"\n')
|
||||
|
||||
|
||||
def get_constants() -> List[str]:
|
||||
def get_constants() -> List[Tuple[str, str]]:
|
||||
# Extra constants that are used in the firmware that are shared across all languages
|
||||
return [
|
||||
("SymbolPlus", "+"),
|
||||
@@ -182,9 +183,10 @@ def get_letter_counts(defs: dict, lang: dict) -> List[str]:
|
||||
if line:
|
||||
for letter in line:
|
||||
symbol_counts[letter] = symbol_counts.get(letter, 0) + 1
|
||||
symbols_by_occurrence = sorted(symbol_counts.items(), key=lambda kv: (kv[1], kv[0]))
|
||||
# swap to Big -> little sort order
|
||||
symbols_by_occurrence = [x[0] for x in symbols_by_occurrence]
|
||||
symbols_by_occurrence = [
|
||||
x[0] for x in sorted(symbol_counts.items(), key=lambda kv: (kv[1], kv[0]))
|
||||
]
|
||||
symbols_by_occurrence.reverse()
|
||||
return symbols_by_occurrence
|
||||
|
||||
@@ -233,10 +235,9 @@ def get_cjk_glyph(sym: str) -> str:
|
||||
return s
|
||||
|
||||
|
||||
def get_chars_from_font_index(index: int) -> str:
|
||||
def get_bytes_from_font_index(index: int) -> bytes:
|
||||
"""
|
||||
Converts the font table index into its corresponding string escape
|
||||
sequence(s).
|
||||
Converts the font table index into its corresponding bytes
|
||||
"""
|
||||
|
||||
# We want to be able to use more than 254 symbols (excluding \x00 null
|
||||
@@ -272,7 +273,7 @@ def get_chars_from_font_index(index: int) -> str:
|
||||
if page > 0x0F:
|
||||
raise ValueError("page value out of range")
|
||||
if page == 0:
|
||||
return f"\\x{index:02X}"
|
||||
return bytes([index])
|
||||
else:
|
||||
# Into extended range
|
||||
# Leader is 0xFz where z is the page number
|
||||
@@ -282,13 +283,17 @@ def get_chars_from_font_index(index: int) -> str:
|
||||
|
||||
if leader > 0xFF or value > 0xFF:
|
||||
raise ValueError("value is out of range")
|
||||
return f"\\x{leader:02X}\\x{value:02X}"
|
||||
return bytes([leader, value])
|
||||
|
||||
|
||||
def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, str]]:
|
||||
def bytes_to_escaped(b: bytes) -> str:
|
||||
return "".join((f"\\x{i:02X}" for i in b))
|
||||
|
||||
|
||||
def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, bytes]]:
|
||||
# the text list is sorted
|
||||
# allocate out these in their order as number codes
|
||||
symbol_map = {"\n": "\\x01"}
|
||||
symbol_map: Dict[str, bytes] = {"\n": bytes([1])}
|
||||
index = 2 # start at 2, as 0= null terminator,1 = new line
|
||||
forced_first_symbols = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
|
||||
|
||||
@@ -310,7 +315,7 @@ def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, str]]:
|
||||
total_symbol_count = len(ordered_normal_sym_list) + len(ordered_cjk_sym_list)
|
||||
# \x00 is for NULL termination and \x01 is for newline, so the maximum
|
||||
# number of symbols allowed is as follow (see also the comments in
|
||||
# `get_chars_from_font_index`):
|
||||
# `get_bytes_from_font_index`):
|
||||
if total_symbol_count > (0x10 * 0xFF - 15) - 2: # 4063
|
||||
logging.error(
|
||||
f"Error, too many used symbols for this version (total {total_symbol_count})"
|
||||
@@ -322,7 +327,7 @@ def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, str]]:
|
||||
for sym in chain(ordered_normal_sym_list, ordered_cjk_sym_list):
|
||||
if sym in symbol_map:
|
||||
raise ValueError("Symbol not found in symbol map")
|
||||
symbol_map[sym] = get_chars_from_font_index(index)
|
||||
symbol_map[sym] = get_bytes_from_font_index(index)
|
||||
index += 1
|
||||
|
||||
font_table_strings = []
|
||||
@@ -332,12 +337,16 @@ def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, str]]:
|
||||
logging.error(f"Missing Large font element for {sym}")
|
||||
sys.exit(1)
|
||||
font_line: str = font_table[sym]
|
||||
font_table_strings.append(f"{font_line}//{symbol_map[sym]} -> {sym}")
|
||||
font_table_strings.append(
|
||||
f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}"
|
||||
)
|
||||
if sym not in font_small_table:
|
||||
logging.error(f"Missing Small font element for {sym}")
|
||||
sys.exit(1)
|
||||
font_line: str = font_small_table[sym]
|
||||
font_small_table_strings.append(f"{font_line}//{symbol_map[sym]} -> {sym}")
|
||||
font_line = font_small_table[sym]
|
||||
font_small_table_strings.append(
|
||||
f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}"
|
||||
)
|
||||
|
||||
for sym in ordered_cjk_sym_list:
|
||||
if sym in font_table:
|
||||
@@ -346,10 +355,12 @@ def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, str]]:
|
||||
if font_line is None:
|
||||
logging.error(f"Missing Large font element for {sym}")
|
||||
sys.exit(1)
|
||||
font_table_strings.append(f"{font_line}//{symbol_map[sym]} -> {sym}")
|
||||
font_table_strings.append(
|
||||
f"{font_line}//{bytes_to_escaped(symbol_map[sym])} -> {sym}"
|
||||
)
|
||||
# No data to add to the small font table
|
||||
font_small_table_strings.append(
|
||||
f"// {symbol_map[sym]} -> {sym}"
|
||||
f"// {bytes_to_escaped(symbol_map[sym])} -> {sym}"
|
||||
)
|
||||
|
||||
output_table = "const uint8_t USER_FONT_12[] = {\n"
|
||||
@@ -365,9 +376,9 @@ def get_font_map_and_table(text_list: List[str]) -> Tuple[str, Dict[str, str]]:
|
||||
return output_table, symbol_map
|
||||
|
||||
|
||||
def convert_string(symbol_conversion_table: Dict[str, str], text: str) -> str:
|
||||
# convert all of the symbols from the string into escapes for their content
|
||||
output_string = ""
|
||||
def convert_string_bytes(symbol_conversion_table: Dict[str, bytes], text: str) -> bytes:
|
||||
# convert all of the symbols from the string into bytes for their content
|
||||
output_string = b""
|
||||
for c in text.replace("\\r", "").replace("\\n", "\n"):
|
||||
if c not in symbol_conversion_table:
|
||||
logging.error(f"Missing font definition for {c}")
|
||||
@@ -377,6 +388,21 @@ def convert_string(symbol_conversion_table: Dict[str, str], text: str) -> str:
|
||||
return output_string
|
||||
|
||||
|
||||
def convert_string(symbol_conversion_table: Dict[str, bytes], text: str) -> str:
|
||||
# convert all of the symbols from the string into escapes for their content
|
||||
return bytes_to_escaped(convert_string_bytes(symbol_conversion_table, text))
|
||||
|
||||
|
||||
def escape(string: str) -> str:
|
||||
return json.dumps(string, ensure_ascii=False)
|
||||
|
||||
|
||||
@dataclass
|
||||
class TranslationItem:
|
||||
info: str
|
||||
str_index: int
|
||||
|
||||
|
||||
def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
language_code: str = lang["languageCode"]
|
||||
logging.info(f"Generating block for {language_code}")
|
||||
@@ -394,28 +420,28 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
f.write(font_table_text)
|
||||
f.write(f"\n// ---- {lang_name} ----\n\n")
|
||||
|
||||
# ----- Writing SettingsDescriptions
|
||||
str_table: List[str] = []
|
||||
str_group_messages: List[TranslationItem] = []
|
||||
str_group_messageswarn: List[TranslationItem] = []
|
||||
str_group_characters: List[TranslationItem] = []
|
||||
str_group_settingdesc: List[TranslationItem] = []
|
||||
str_group_settingshortnames: List[TranslationItem] = []
|
||||
str_group_settingmenuentries: List[TranslationItem] = []
|
||||
str_group_settingmenuentriesdesc: List[TranslationItem] = []
|
||||
|
||||
eid: str
|
||||
|
||||
# ----- Reading SettingsDescriptions
|
||||
obj = lang["menuOptions"]
|
||||
f.write("const char* SettingsDescriptions[] = {\n")
|
||||
|
||||
max_len = 25
|
||||
index = 0
|
||||
for mod in defs["menuOptions"]:
|
||||
for index, mod in enumerate(defs["menuOptions"]):
|
||||
eid = mod["id"]
|
||||
if "feature" in mod:
|
||||
f.write(f"#ifdef {mod['feature']}\n")
|
||||
f.write(f" /* [{index:02d}] {eid.ljust(max_len)[:max_len]} */ ")
|
||||
f.write(
|
||||
f"\"{convert_string(symbol_conversion_table, obj[eid]['desc'])}\",//{obj[eid]['desc']} \n"
|
||||
str_group_settingdesc.append(
|
||||
TranslationItem(f"[{index:02d}] {eid}", len(str_table))
|
||||
)
|
||||
str_table.append(obj[eid]["desc"])
|
||||
|
||||
if "feature" in mod:
|
||||
f.write("#endif\n")
|
||||
index += 1
|
||||
|
||||
f.write("};\n\n")
|
||||
|
||||
# ----- Writing Message strings
|
||||
# ----- Reading Message strings
|
||||
|
||||
obj = lang["messages"]
|
||||
|
||||
@@ -426,11 +452,8 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
source_text = mod["default"]
|
||||
if eid in obj:
|
||||
source_text = obj[eid]
|
||||
translated_text = convert_string(symbol_conversion_table, source_text)
|
||||
source_text = source_text.replace("\n", "_")
|
||||
f.write(f'const char* {eid} = "{translated_text}";//{source_text} \n')
|
||||
|
||||
f.write("\n")
|
||||
str_group_messages.append(TranslationItem(eid, len(str_table)))
|
||||
str_table.append(source_text)
|
||||
|
||||
obj = lang["messagesWarn"]
|
||||
|
||||
@@ -443,22 +466,17 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
source_text = obj[eid][0] + "\n" + obj[eid][1]
|
||||
else:
|
||||
source_text = "\n" + obj[eid]
|
||||
translated_text = convert_string(symbol_conversion_table, source_text)
|
||||
source_text = source_text.replace("\n", "_")
|
||||
f.write(f'const char* {eid} = "{translated_text}";//{source_text} \n')
|
||||
str_group_messageswarn.append(TranslationItem(eid, len(str_table)))
|
||||
str_table.append(source_text)
|
||||
|
||||
f.write("\n")
|
||||
|
||||
# ----- Writing Characters
|
||||
# ----- Reading Characters
|
||||
|
||||
obj = lang["characters"]
|
||||
|
||||
for mod in defs["characters"]:
|
||||
eid: str = mod["id"]
|
||||
f.write(
|
||||
f'const char* {eid} = "{convert_string(symbol_conversion_table, obj[eid])}";//{obj[eid]} \n'
|
||||
)
|
||||
f.write("\n")
|
||||
eid = mod["id"]
|
||||
str_group_characters.append(TranslationItem(eid, len(str_table)))
|
||||
str_table.append(obj[eid])
|
||||
|
||||
# Write out firmware constant options
|
||||
constants = get_constants()
|
||||
@@ -475,13 +493,10 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
f.write(f'\t "{convert_string(symbol_conversion_table, c)}",//{c} \n')
|
||||
f.write("};\n\n")
|
||||
|
||||
# ----- Writing SettingsDescriptions
|
||||
# ----- Reading SettingsDescriptions
|
||||
obj = lang["menuOptions"]
|
||||
f.write("const char* SettingsShortNames[] = {\n")
|
||||
|
||||
max_len = 25
|
||||
index = 0
|
||||
for mod in defs["menuOptions"]:
|
||||
for index, mod in enumerate(defs["menuOptions"]):
|
||||
eid = mod["id"]
|
||||
if isinstance(obj[eid]["text2"], list):
|
||||
if not obj[eid]["text2"][1]:
|
||||
@@ -490,25 +505,15 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
source_text = obj[eid]["text2"][0] + "\n" + obj[eid]["text2"][1]
|
||||
else:
|
||||
source_text = "\n" + obj[eid]["text2"]
|
||||
if "feature" in mod:
|
||||
f.write(f"#ifdef {mod['feature']}\n")
|
||||
f.write(f" /* [{index:02d}] {eid.ljust(max_len)[:max_len]} */ ")
|
||||
f.write(
|
||||
f'{{ "{convert_string(symbol_conversion_table, source_text)}" }},//{obj[eid]["text2"]} \n'
|
||||
str_group_settingshortnames.append(
|
||||
TranslationItem(f"[{index:02d}] {eid}", len(str_table))
|
||||
)
|
||||
str_table.append(source_text)
|
||||
|
||||
if "feature" in mod:
|
||||
f.write("#endif\n")
|
||||
index += 1
|
||||
|
||||
f.write("};\n\n")
|
||||
|
||||
# ----- Writing Menu Groups
|
||||
# ----- Reading Menu Groups
|
||||
obj = lang["menuGroups"]
|
||||
f.write(f"const char* SettingsMenuEntries[{len(obj)}] = {{\n")
|
||||
|
||||
max_len = 25
|
||||
for mod in defs["menuGroups"]:
|
||||
for index, mod in enumerate(defs["menuGroups"]):
|
||||
eid = mod["id"]
|
||||
if isinstance(obj[eid]["text2"], list):
|
||||
if not obj[eid]["text2"][1]:
|
||||
@@ -517,26 +522,135 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
source_text = obj[eid]["text2"][0] + "\n" + obj[eid]["text2"][1]
|
||||
else:
|
||||
source_text = "\n" + obj[eid]["text2"]
|
||||
f.write(f" /* {eid.ljust(max_len)[:max_len]} */ ")
|
||||
f.write(
|
||||
f'"{convert_string(symbol_conversion_table, source_text)}",//{obj[eid]["text2"]} \n'
|
||||
str_group_settingmenuentries.append(
|
||||
TranslationItem(f"[{index:02d}] {eid}", len(str_table))
|
||||
)
|
||||
str_table.append(source_text)
|
||||
|
||||
f.write("};\n\n")
|
||||
|
||||
# ----- Writing Menu Groups Descriptions
|
||||
# ----- Reading Menu Groups Descriptions
|
||||
obj = lang["menuGroups"]
|
||||
f.write(f"const char* SettingsMenuEntriesDescriptions[{(len(obj))}] = {{\n")
|
||||
|
||||
max_len = 25
|
||||
for mod in defs["menuGroups"]:
|
||||
for index, mod in enumerate(defs["menuGroups"]):
|
||||
eid = mod["id"]
|
||||
f.write(f" /* {eid.ljust(max_len)[:max_len]} */ ")
|
||||
f.write(
|
||||
f"\"{convert_string(symbol_conversion_table, (obj[eid]['desc']))}\",//{obj[eid]['desc']} \n"
|
||||
str_group_settingmenuentriesdesc.append(
|
||||
TranslationItem(f"[{index:02d}] {eid}", len(str_table))
|
||||
)
|
||||
str_table.append(obj[eid]["desc"])
|
||||
|
||||
f.write("\n")
|
||||
|
||||
@dataclass
|
||||
class RemappedTranslationItem:
|
||||
str_index: int
|
||||
str_start_offset: int = 0
|
||||
|
||||
# ----- Perform suffix merging optimization:
|
||||
#
|
||||
# We sort the backward strings so that strings with the same suffix will
|
||||
# be next to each other, e.g.:
|
||||
# "ef\0",
|
||||
# "cdef\0",
|
||||
# "abcdef\0",
|
||||
backward_sorted_table: List[Tuple[int, str, bytes]] = sorted(
|
||||
(
|
||||
(i, s, bytes(reversed(convert_string_bytes(symbol_conversion_table, s))))
|
||||
for i, s in enumerate(str_table)
|
||||
),
|
||||
key=lambda x: x[2],
|
||||
)
|
||||
str_remapping: List[Optional[RemappedTranslationItem]] = [None] * len(str_table)
|
||||
for i, (str_index, source_str, converted) in enumerate(backward_sorted_table[:-1]):
|
||||
j = i
|
||||
while backward_sorted_table[j + 1][2].startswith(converted):
|
||||
j += 1
|
||||
if j != i:
|
||||
str_remapping[str_index] = RemappedTranslationItem(
|
||||
str_index=backward_sorted_table[j][0],
|
||||
str_start_offset=len(backward_sorted_table[j][2]) - len(converted),
|
||||
)
|
||||
|
||||
# ----- Write the string table:
|
||||
str_offsets = [-1] * len(str_table)
|
||||
offset = 0
|
||||
write_null = False
|
||||
f.write("const char TranslationStringsData[] = {\n")
|
||||
for i, source_str in enumerate(str_table):
|
||||
if write_null:
|
||||
f.write(' "\\0"\n')
|
||||
write_null = True
|
||||
if str_remapping[i] is not None:
|
||||
write_null = False
|
||||
continue
|
||||
# Find what items use this string
|
||||
str_used_by = [i] + [
|
||||
j for j, r in enumerate(str_remapping) if r and r.str_index == i
|
||||
]
|
||||
for j in str_used_by:
|
||||
for group, pre_info in [
|
||||
(str_group_messages, "messages"),
|
||||
(str_group_messageswarn, "messagesWarn"),
|
||||
(str_group_characters, "characters"),
|
||||
(str_group_settingdesc, "SettingsDescriptions"),
|
||||
(str_group_settingshortnames, "SettingsShortNames"),
|
||||
(str_group_settingmenuentries, "SettingsMenuEntries"),
|
||||
(str_group_settingmenuentriesdesc, "SettingsMenuEntriesDescriptions"),
|
||||
]:
|
||||
for item in group:
|
||||
if item.str_index == j:
|
||||
f.write(f" // - {pre_info} {item.info}\n")
|
||||
if j == i:
|
||||
f.write(f" // {offset: >4}: {escape(source_str)}\n")
|
||||
str_offsets[j] = offset
|
||||
else:
|
||||
remapped = str_remapping[j]
|
||||
assert remapped is not None
|
||||
f.write(
|
||||
f" // {offset + remapped.str_start_offset: >4}: {escape(str_table[j])}\n"
|
||||
)
|
||||
str_offsets[j] = offset + remapped.str_start_offset
|
||||
converted_str = convert_string(symbol_conversion_table, source_str)
|
||||
f.write(f' "{converted_str}"')
|
||||
str_offsets[i] = offset
|
||||
# Sanity check: Each "char" in `converted_str` should be in format
|
||||
# `\xFF`, so the length should be divisible by 4.
|
||||
assert len(converted_str) % 4 == 0
|
||||
# Add the length and the null terminator
|
||||
offset += len(converted_str) // 4 + 1
|
||||
f.write("\n};\n\n")
|
||||
|
||||
def get_offset(idx: int) -> int:
|
||||
assert str_offsets[idx] >= 0
|
||||
return str_offsets[idx]
|
||||
|
||||
f.write("const TranslationIndexTable TranslationIndices = {\n")
|
||||
|
||||
# ----- Write the messages string indices:
|
||||
for group in [str_group_messages, str_group_messageswarn, str_group_characters]:
|
||||
for item in group:
|
||||
f.write(
|
||||
f" .{item.info} = {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n"
|
||||
)
|
||||
f.write("\n")
|
||||
|
||||
# ----- Write the settings index tables:
|
||||
for group, name in [
|
||||
(str_group_settingdesc, "SettingsDescriptions"),
|
||||
(str_group_settingshortnames, "SettingsShortNames"),
|
||||
(str_group_settingmenuentries, "SettingsMenuEntries"),
|
||||
(str_group_settingmenuentriesdesc, "SettingsMenuEntriesDescriptions"),
|
||||
]:
|
||||
max_len = 30
|
||||
f.write(f" .{name} = {{\n")
|
||||
for item in group:
|
||||
f.write(
|
||||
f" /* {item.info.ljust(max_len)[:max_len]} */ {get_offset(item.str_index)}, // {escape(str_table[item.str_index])}\n"
|
||||
)
|
||||
f.write(f" }}, // {name}\n\n")
|
||||
|
||||
f.write("}; // TranslationIndices\n\n")
|
||||
f.write("const TranslationIndexTable *const Tr = &TranslationIndices;\n")
|
||||
f.write("const char *const TranslationStrings = TranslationStringsData;\n\n")
|
||||
|
||||
f.write("};\n\n")
|
||||
f.write(
|
||||
f"const bool HasFahrenheit = {('true' if lang.get('tempUnitFahrenheit', True) else 'false')};\n"
|
||||
)
|
||||
@@ -547,15 +661,18 @@ def write_language(lang: dict, defs: dict, f: TextIO) -> None:
|
||||
f.write(
|
||||
f"static_assert(static_cast<uint8_t>(SettingsItemIndex::{eid}) == {i});\n"
|
||||
)
|
||||
f.write(
|
||||
f"static_assert(static_cast<uint8_t>(SettingsItemIndex::NUM_ITEMS) == {len(defs['menuOptions'])});\n"
|
||||
)
|
||||
|
||||
|
||||
def read_version() -> str:
|
||||
with open(HERE.parent / "source" / "version.h") as version_file:
|
||||
for line in version_file:
|
||||
if re.findall(r"^.*(?<=(#define)).*(?<=(BUILD_VERSION))", line):
|
||||
line = re.findall(r"\"(.+?)\"", line)
|
||||
if line:
|
||||
version = line[0]
|
||||
matches = re.findall(r"\"(.+?)\"", line)
|
||||
if matches:
|
||||
version = matches[0]
|
||||
try:
|
||||
version += f".{subprocess.check_output(['git', 'rev-parse', '--short=7', 'HEAD']).strip().decode('ascii').upper()}"
|
||||
# --short=7: the shorted hash with 7 digits. Increase/decrease if needed!
|
||||
|
||||
@@ -3,20 +3,26 @@ import unittest
|
||||
|
||||
|
||||
class TestMakeTranslation(unittest.TestCase):
|
||||
def test_get_chars_from_font_index(self):
|
||||
from make_translation import get_chars_from_font_index
|
||||
def test_get_bytes_from_font_index(self):
|
||||
from make_translation import get_bytes_from_font_index
|
||||
|
||||
self.assertEqual(get_chars_from_font_index(2), "\\x02")
|
||||
self.assertEqual(get_chars_from_font_index(239), "\\xEF")
|
||||
self.assertEqual(get_chars_from_font_index(240), "\\xF0")
|
||||
self.assertEqual(get_chars_from_font_index(241), "\\xF1\\x01")
|
||||
self.assertEqual(get_chars_from_font_index(495), "\\xF1\\xFF")
|
||||
self.assertEqual(get_chars_from_font_index(496), "\\xF2\\x01")
|
||||
self.assertEqual(get_chars_from_font_index(750), "\\xF2\\xFF")
|
||||
self.assertEqual(get_chars_from_font_index(751), "\\xF3\\x01")
|
||||
self.assertEqual(get_chars_from_font_index(0x10 * 0xFF - 15), "\\xFF\\xFF")
|
||||
self.assertEqual(get_bytes_from_font_index(2), b"\x02")
|
||||
self.assertEqual(get_bytes_from_font_index(239), b"\xEF")
|
||||
self.assertEqual(get_bytes_from_font_index(240), b"\xF0")
|
||||
self.assertEqual(get_bytes_from_font_index(241), b"\xF1\x01")
|
||||
self.assertEqual(get_bytes_from_font_index(495), b"\xF1\xFF")
|
||||
self.assertEqual(get_bytes_from_font_index(496), b"\xF2\x01")
|
||||
self.assertEqual(get_bytes_from_font_index(750), b"\xF2\xFF")
|
||||
self.assertEqual(get_bytes_from_font_index(751), b"\xF3\x01")
|
||||
self.assertEqual(get_bytes_from_font_index(0x10 * 0xFF - 15), b"\xFF\xFF")
|
||||
with self.assertRaises(ValueError):
|
||||
get_chars_from_font_index(0x10 * 0xFF - 14)
|
||||
get_bytes_from_font_index(0x10 * 0xFF - 14)
|
||||
|
||||
def test_bytes_to_escaped(self):
|
||||
from make_translation import bytes_to_escaped
|
||||
|
||||
self.assertEqual(bytes_to_escaped(b"\x00"), "\\x00")
|
||||
self.assertEqual(bytes_to_escaped(b"\xF1\xAB"), "\\xF1\\xAB")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
var def =
|
||||
{
|
||||
"messages": [
|
||||
{
|
||||
"id": "SettingsCalibrationDone"
|
||||
},
|
||||
{
|
||||
"id": "SettingsCalibrationWarning"
|
||||
},
|
||||
@@ -23,15 +20,6 @@ var def =
|
||||
"maxLen": 11,
|
||||
"note": "Preferably end with a space"
|
||||
},
|
||||
{
|
||||
"id": "WarningTipTempString",
|
||||
"maxLen": 12,
|
||||
"note": "Preferably end with a space"
|
||||
},
|
||||
{
|
||||
"id": "BadTipString",
|
||||
"maxLen": 8
|
||||
},
|
||||
{
|
||||
"id": "SleepingSimpleString",
|
||||
"maxLen": 4
|
||||
@@ -40,14 +28,6 @@ var def =
|
||||
"id": "SleepingAdvancedString",
|
||||
"maxLen": 16
|
||||
},
|
||||
{
|
||||
"id": "WarningSimpleString",
|
||||
"maxLen": 4
|
||||
},
|
||||
{
|
||||
"id": "WarningAdvancedString",
|
||||
"maxLen": 16
|
||||
},
|
||||
{
|
||||
"id": "SleepingTipAdvancedString",
|
||||
"maxLen": 6
|
||||
@@ -80,11 +60,6 @@ var def =
|
||||
{
|
||||
"id": "OffString",
|
||||
"maxLen": 3
|
||||
},
|
||||
{
|
||||
"id": "YourGainMessage",
|
||||
"maxLen": 8,
|
||||
"default": "Your Gain"
|
||||
}
|
||||
],
|
||||
"messagesWarn": [
|
||||
|
||||
@@ -12,61 +12,6 @@ extern const uint8_t USER_FONT_12[];
|
||||
extern const uint8_t USER_FONT_6x8[];
|
||||
extern const bool HasFahrenheit;
|
||||
|
||||
extern const char *SettingsShortNames[];
|
||||
extern const char *SettingsDescriptions[];
|
||||
extern const char *SettingsMenuEntries[];
|
||||
|
||||
extern const char *SettingsCalibrationDone;
|
||||
extern const char *SettingsCalibrationWarning;
|
||||
extern const char *SettingsResetWarning;
|
||||
extern const char *UVLOWarningString;
|
||||
extern const char *UndervoltageString;
|
||||
extern const char *InputVoltageString;
|
||||
extern const char *WarningTipTempString;
|
||||
extern const char *BadTipString;
|
||||
|
||||
extern const char *SleepingSimpleString;
|
||||
extern const char *SleepingAdvancedString;
|
||||
extern const char *WarningSimpleString;
|
||||
extern const char *WarningAdvancedString;
|
||||
extern const char *SleepingTipAdvancedString;
|
||||
extern const char *IdleTipString;
|
||||
extern const char *IdleSetString;
|
||||
extern const char *TipDisconnectedString;
|
||||
extern const char *SolderingAdvancedPowerPrompt;
|
||||
extern const char *OffString;
|
||||
extern const char *YourGainMessage;
|
||||
|
||||
extern const char *ResetOKMessage;
|
||||
extern const char *SettingsResetMessage;
|
||||
extern const char *NoAccelerometerMessage;
|
||||
extern const char *NoPowerDeliveryMessage;
|
||||
extern const char *LockingKeysString;
|
||||
extern const char *UnlockingKeysString;
|
||||
extern const char *WarningKeysLockedString;
|
||||
|
||||
extern const char *SettingRightChar;
|
||||
extern const char *SettingLeftChar;
|
||||
extern const char *SettingAutoChar;
|
||||
extern const char *SettingStartSolderingChar;
|
||||
extern const char *SettingStartSleepChar;
|
||||
extern const char *SettingStartSleepOffChar;
|
||||
extern const char *SettingStartNoneChar;
|
||||
extern const char *SettingSensitivityOff;
|
||||
extern const char *SettingSensitivityLow;
|
||||
extern const char *SettingSensitivityMedium;
|
||||
extern const char *SettingSensitivityHigh;
|
||||
extern const char *SettingLockDisableChar;
|
||||
extern const char *SettingLockBoostChar;
|
||||
extern const char *SettingLockFullChar;
|
||||
extern const char *SettingNAChar;
|
||||
|
||||
extern const char *SettingOffChar;
|
||||
extern const char *SettingFastChar;
|
||||
extern const char *SettingMediumChar;
|
||||
extern const char *SettingSlowChar;
|
||||
extern const char *TipModelStrings[];
|
||||
extern const char *DebugMenu[];
|
||||
extern const char *SymbolPlus;
|
||||
extern const char *SymbolMinus;
|
||||
extern const char *SymbolSpace;
|
||||
@@ -113,10 +58,66 @@ enum class SettingsItemIndex : uint8_t {
|
||||
AnimSpeed,
|
||||
PowerPulseWait,
|
||||
PowerPulseDuration,
|
||||
NUM_ITEMS,
|
||||
};
|
||||
|
||||
struct TranslationIndexTable {
|
||||
uint16_t SettingsCalibrationWarning;
|
||||
uint16_t SettingsResetWarning;
|
||||
uint16_t UVLOWarningString;
|
||||
uint16_t UndervoltageString;
|
||||
uint16_t InputVoltageString;
|
||||
|
||||
uint16_t SleepingSimpleString;
|
||||
uint16_t SleepingAdvancedString;
|
||||
uint16_t SleepingTipAdvancedString;
|
||||
uint16_t IdleTipString;
|
||||
uint16_t IdleSetString;
|
||||
uint16_t TipDisconnectedString;
|
||||
uint16_t SolderingAdvancedPowerPrompt;
|
||||
uint16_t OffString;
|
||||
|
||||
uint16_t ResetOKMessage;
|
||||
uint16_t SettingsResetMessage;
|
||||
uint16_t NoAccelerometerMessage;
|
||||
uint16_t NoPowerDeliveryMessage;
|
||||
uint16_t LockingKeysString;
|
||||
uint16_t UnlockingKeysString;
|
||||
uint16_t WarningKeysLockedString;
|
||||
|
||||
uint16_t SettingRightChar;
|
||||
uint16_t SettingLeftChar;
|
||||
uint16_t SettingAutoChar;
|
||||
uint16_t SettingFastChar;
|
||||
uint16_t SettingSlowChar;
|
||||
uint16_t SettingMediumChar;
|
||||
uint16_t SettingOffChar;
|
||||
uint16_t SettingStartSolderingChar;
|
||||
uint16_t SettingStartSleepChar;
|
||||
uint16_t SettingStartSleepOffChar;
|
||||
uint16_t SettingStartNoneChar;
|
||||
uint16_t SettingSensitivityOff;
|
||||
uint16_t SettingSensitivityLow;
|
||||
uint16_t SettingSensitivityMedium;
|
||||
uint16_t SettingSensitivityHigh;
|
||||
uint16_t SettingLockDisableChar;
|
||||
uint16_t SettingLockBoostChar;
|
||||
uint16_t SettingLockFullChar;
|
||||
uint16_t SettingNAChar;
|
||||
|
||||
uint16_t SettingsDescriptions[static_cast<uint32_t>(SettingsItemIndex::NUM_ITEMS)];
|
||||
uint16_t SettingsShortNames[static_cast<uint32_t>(SettingsItemIndex::NUM_ITEMS)];
|
||||
uint16_t SettingsMenuEntries[5];
|
||||
uint16_t SettingsMenuEntriesDescriptions[5]; // unused
|
||||
};
|
||||
|
||||
extern const TranslationIndexTable *const Tr;
|
||||
extern const char *const TranslationStrings;
|
||||
|
||||
constexpr uint8_t settings_item_index(const SettingsItemIndex i) { return static_cast<uint8_t>(i); }
|
||||
// Use a constexpr function for type-checking.
|
||||
#define SETTINGS_DESC(i) (SettingsDescriptions[settings_item_index(i)])
|
||||
#define SETTINGS_DESC(i) (settings_item_index(i) + 1)
|
||||
|
||||
const char *translatedString(uint16_t index);
|
||||
|
||||
#endif /* TRANSLATION_H_ */
|
||||
|
||||
@@ -21,7 +21,9 @@
|
||||
|
||||
// Struct for holding the function pointers and descriptions
|
||||
typedef struct {
|
||||
const char *description;
|
||||
// The settings description index, please use the `SETTINGS_DESC` macro with
|
||||
// the `SettingsItemIndex` enum. Use 0 for no description.
|
||||
uint8_t description;
|
||||
// return true if increment reached the maximum value
|
||||
bool (*const incrementHandler)(void);
|
||||
bool (*const draw)(void);
|
||||
|
||||
3
source/Core/Src/Translation.cpp
Normal file
3
source/Core/Src/Translation.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "Translation.h"
|
||||
|
||||
const char *translatedString(uint16_t offset) { return TranslationStrings + offset; }
|
||||
@@ -139,12 +139,12 @@ const menuitem rootSettingsMenu[]{
|
||||
* Advanced Menu
|
||||
* Exit
|
||||
*/
|
||||
{nullptr, settings_enterPowerMenu, settings_displayPowerMenu}, /*Power*/
|
||||
{nullptr, settings_enterSolderingMenu, settings_displaySolderingMenu}, /*Soldering*/
|
||||
{nullptr, settings_enterPowerSavingMenu, settings_displayPowerSavingMenu}, /*Sleep Options Menu*/
|
||||
{nullptr, settings_enterUIMenu, settings_displayUIMenu}, /*UI Menu*/
|
||||
{nullptr, settings_enterAdvancedMenu, settings_displayAdvancedMenu}, /*Advanced Menu*/
|
||||
{nullptr, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
{0, settings_enterPowerMenu, settings_displayPowerMenu}, /*Power*/
|
||||
{0, settings_enterSolderingMenu, settings_displaySolderingMenu}, /*Soldering*/
|
||||
{0, settings_enterPowerSavingMenu, settings_displayPowerSavingMenu}, /*Sleep Options Menu*/
|
||||
{0, settings_enterUIMenu, settings_displayUIMenu}, /*UI Menu*/
|
||||
{0, settings_enterAdvancedMenu, settings_displayAdvancedMenu}, /*Advanced Menu*/
|
||||
{0, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
const menuitem powerMenu[] = {
|
||||
@@ -158,7 +158,7 @@ const menuitem powerMenu[] = {
|
||||
#ifdef POW_QC
|
||||
{SETTINGS_DESC(SettingsItemIndex::QCMaxVoltage), settings_setQCInputV, settings_displayQCInputV}, /*Voltage input*/
|
||||
#endif
|
||||
{nullptr, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
{0, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
};
|
||||
const menuitem solderingMenu[] = {
|
||||
/*
|
||||
@@ -173,7 +173,7 @@ const menuitem solderingMenu[] = {
|
||||
{SETTINGS_DESC(SettingsItemIndex::TempChangeShortStep), settings_setTempChangeShortStep, settings_displayTempChangeShortStep}, /*Temp change short step*/
|
||||
{SETTINGS_DESC(SettingsItemIndex::TempChangeLongStep), settings_setTempChangeLongStep, settings_displayTempChangeLongStep}, /*Temp change long step*/
|
||||
{SETTINGS_DESC(SettingsItemIndex::LockingMode), settings_setLockingMode, settings_displayLockingMode}, /*Locking Mode*/
|
||||
{nullptr, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
{0, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
};
|
||||
const menuitem UIMenu[] = {
|
||||
/*
|
||||
@@ -192,7 +192,7 @@ const menuitem UIMenu[] = {
|
||||
{SETTINGS_DESC(SettingsItemIndex::ReverseButtonTempChange), settings_setReverseButtonTempChangeEnabled, settings_displayReverseButtonTempChangeEnabled}, /* Reverse Temp change buttons + - */
|
||||
{SETTINGS_DESC(SettingsItemIndex::AnimSpeed), settings_setAnimationSpeed, settings_displayAnimationSpeed}, /*Animation Speed adjustment */
|
||||
{SETTINGS_DESC(SettingsItemIndex::AnimLoop), settings_setAnimationLoop, settings_displayAnimationLoop}, /*Animation Loop switch */
|
||||
{nullptr, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
{0, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
};
|
||||
const menuitem PowerSavingMenu[] = {
|
||||
/*
|
||||
@@ -208,7 +208,7 @@ const menuitem PowerSavingMenu[] = {
|
||||
#ifdef HALL_SENSOR
|
||||
{SETTINGS_DESC(SettingsItemIndex::HallEffSensitivity), settings_setHallEffect, settings_displayHallEffect}, /* HallEffect Sensitivity*/
|
||||
#endif
|
||||
{nullptr, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
{0, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
};
|
||||
const menuitem advancedMenu[] = {
|
||||
|
||||
@@ -234,7 +234,7 @@ const menuitem advancedMenu[] = {
|
||||
{SETTINGS_DESC(SettingsItemIndex::PowerPulsePower), settings_setPowerPulse, settings_displayPowerPulse}, /*Power Pulse adjustment */
|
||||
{SETTINGS_DESC(SettingsItemIndex::PowerPulseWait), settings_setPowerPulseWait, settings_displayPowerPulseWait}, /*Power Pulse Wait adjustment*/
|
||||
{SETTINGS_DESC(SettingsItemIndex::PowerPulseDuration), settings_setPowerPulseDuration, settings_displayPowerPulseDuration}, /*Power Pulse Duration adjustment*/
|
||||
{nullptr, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
{0, nullptr, nullptr} // end of menu marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -247,7 +247,7 @@ const menuitem advancedMenu[] = {
|
||||
static void printShortDescription(SettingsItemIndex settingsItemIndex, uint16_t cursorCharPosition) {
|
||||
// print short description (default single line, explicit double line)
|
||||
uint8_t shortDescIndex = static_cast<uint8_t>(settingsItemIndex);
|
||||
OLED::printWholeScreen(SettingsShortNames[shortDescIndex]);
|
||||
OLED::printWholeScreen(translatedString(Tr->SettingsShortNames[shortDescIndex]));
|
||||
|
||||
// prepare cursor for value
|
||||
// make room for scroll indicator
|
||||
@@ -362,7 +362,7 @@ static bool settings_displayInputMinVRange(void) {
|
||||
OLED::printNumber(systemSettings.minVoltageCells % 10, 1, FontStyle::LARGE);
|
||||
} else {
|
||||
printShortDescription(SettingsItemIndex::MinVolCell, 5);
|
||||
OLED::print(SettingNAChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingNAChar), FontStyle::LARGE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -437,7 +437,7 @@ static bool settings_setSleepTime(void) {
|
||||
static bool settings_displaySleepTime(void) {
|
||||
printShortDescription(SettingsItemIndex::SleepTimeout, 5);
|
||||
if (systemSettings.SleepTime == 0) {
|
||||
OLED::print(OffString, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->OffString), FontStyle::LARGE);
|
||||
} else if (systemSettings.SleepTime < 6) {
|
||||
OLED::printNumber(systemSettings.SleepTime * 10, 2, FontStyle::LARGE);
|
||||
OLED::print(SymbolSeconds, FontStyle::LARGE);
|
||||
@@ -461,7 +461,7 @@ static bool settings_setShutdownTime(void) {
|
||||
static bool settings_displayShutdownTime(void) {
|
||||
printShortDescription(SettingsItemIndex::ShutdownTimeout, 5);
|
||||
if (systemSettings.ShutdownTime == 0) {
|
||||
OLED::print(OffString, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->OffString), FontStyle::LARGE);
|
||||
} else {
|
||||
OLED::printNumber(systemSettings.ShutdownTime, 2, FontStyle::LARGE);
|
||||
OLED::print(SymbolMinutes, FontStyle::LARGE);
|
||||
@@ -546,7 +546,7 @@ static bool settings_setPowerLimit(void) {
|
||||
static bool settings_displayPowerLimit(void) {
|
||||
printShortDescription(SettingsItemIndex::PowerLimit, 5);
|
||||
if (systemSettings.powerLimit == 0) {
|
||||
OLED::print(OffString, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->OffString), FontStyle::LARGE);
|
||||
} else {
|
||||
OLED::printNumber(systemSettings.powerLimit, 2, FontStyle::LARGE);
|
||||
OLED::print(SymbolWatts, FontStyle::LARGE);
|
||||
@@ -564,7 +564,7 @@ static bool settings_setScrollSpeed(void) {
|
||||
|
||||
static bool settings_displayScrollSpeed(void) {
|
||||
printShortDescription(SettingsItemIndex::ScrollingSpeed, 7);
|
||||
OLED::print((systemSettings.descriptionScrollSpeed) ? SettingFastChar : SettingSlowChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString((systemSettings.descriptionScrollSpeed) ? Tr->SettingFastChar : Tr->SettingSlowChar), FontStyle::LARGE);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -592,16 +592,16 @@ static bool settings_displayDisplayRotation(void) {
|
||||
|
||||
switch (systemSettings.OrientationMode) {
|
||||
case 0:
|
||||
OLED::print(SettingRightChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingRightChar), FontStyle::LARGE);
|
||||
break;
|
||||
case 1:
|
||||
OLED::print(SettingLeftChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingLeftChar), FontStyle::LARGE);
|
||||
break;
|
||||
case 2:
|
||||
OLED::print(SettingAutoChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingAutoChar), FontStyle::LARGE);
|
||||
break;
|
||||
default:
|
||||
OLED::print(SettingRightChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingRightChar), FontStyle::LARGE);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -637,7 +637,7 @@ static bool settings_displayBoostTemp(void) {
|
||||
if (systemSettings.BoostTemp) {
|
||||
OLED::printNumber(systemSettings.BoostTemp, 3, FontStyle::LARGE);
|
||||
} else {
|
||||
OLED::print(OffString, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->OffString), FontStyle::LARGE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -653,19 +653,19 @@ static bool settings_displayAutomaticStartMode(void) {
|
||||
|
||||
switch (systemSettings.autoStartMode) {
|
||||
case 0:
|
||||
OLED::print(SettingStartNoneChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingStartNoneChar), FontStyle::LARGE);
|
||||
break;
|
||||
case 1:
|
||||
OLED::print(SettingStartSolderingChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingStartSolderingChar), FontStyle::LARGE);
|
||||
break;
|
||||
case 2:
|
||||
OLED::print(SettingStartSleepChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingStartSleepChar), FontStyle::LARGE);
|
||||
break;
|
||||
case 3:
|
||||
OLED::print(SettingStartSleepOffChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingStartSleepOffChar), FontStyle::LARGE);
|
||||
break;
|
||||
default:
|
||||
OLED::print(SettingStartNoneChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingStartNoneChar), FontStyle::LARGE);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -682,16 +682,16 @@ static bool settings_displayLockingMode(void) {
|
||||
|
||||
switch (systemSettings.lockingMode) {
|
||||
case 0:
|
||||
OLED::print(SettingLockDisableChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingLockDisableChar), FontStyle::LARGE);
|
||||
break;
|
||||
case 1:
|
||||
OLED::print(SettingLockBoostChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingLockBoostChar), FontStyle::LARGE);
|
||||
break;
|
||||
case 2:
|
||||
OLED::print(SettingLockFullChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingLockFullChar), FontStyle::LARGE);
|
||||
break;
|
||||
default:
|
||||
OLED::print(SettingLockDisableChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingLockDisableChar), FontStyle::LARGE);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -709,9 +709,9 @@ static bool settings_displayCoolingBlinkEnabled(void) {
|
||||
}
|
||||
|
||||
static bool settings_setResetSettings(void) {
|
||||
if (userConfirmation(SettingsResetWarning)) {
|
||||
if (userConfirmation(translatedString(Tr->SettingsResetWarning))) {
|
||||
resetSettings();
|
||||
warnUser(ResetOKMessage, 2 * TICKS_SECOND);
|
||||
warnUser(translatedString(Tr->ResetOKMessage), 2 * TICKS_SECOND);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -754,7 +754,7 @@ static void setTipOffset() {
|
||||
// If not only do single point tuning as per usual
|
||||
static bool settings_setCalibrate(void) {
|
||||
|
||||
if (userConfirmation(SettingsCalibrationWarning)) {
|
||||
if (userConfirmation(translatedString(Tr->SettingsCalibrationWarning))) {
|
||||
// User confirmed
|
||||
// So we now perform the actual calculation
|
||||
setTipOffset();
|
||||
@@ -881,7 +881,7 @@ static bool settings_displayPowerPulse(void) {
|
||||
OLED::print(SymbolDot, FontStyle::LARGE);
|
||||
OLED::printNumber(systemSettings.KeepAwakePulse % 10, 1, FontStyle::LARGE);
|
||||
} else {
|
||||
OLED::print(OffString, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->OffString), FontStyle::LARGE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -907,16 +907,16 @@ static bool settings_displayAnimationSpeed(void) {
|
||||
printShortDescription(SettingsItemIndex::AnimSpeed, 7);
|
||||
switch (systemSettings.animationSpeed) {
|
||||
case settingOffSpeed_t::SLOW:
|
||||
OLED::print(SettingSlowChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingSlowChar), FontStyle::LARGE);
|
||||
break;
|
||||
case settingOffSpeed_t::MEDIUM:
|
||||
OLED::print(SettingMediumChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingMediumChar), FontStyle::LARGE);
|
||||
break;
|
||||
case settingOffSpeed_t::FAST:
|
||||
OLED::print(SettingFastChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingFastChar), FontStyle::LARGE);
|
||||
break;
|
||||
default:
|
||||
OLED::print(SettingOffChar, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingOffChar), FontStyle::LARGE);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -967,17 +967,17 @@ static bool settings_displayHallEffect(void) {
|
||||
printShortDescription(SettingsItemIndex::HallEffSensitivity, 7);
|
||||
switch (systemSettings.hallEffectSensitivity) {
|
||||
case 1:
|
||||
OLED::print(SettingSensitivityLow, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingSensitivityLow), FontStyle::LARGE);
|
||||
break;
|
||||
case 2:
|
||||
OLED::print(SettingSensitivityMedium, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingSensitivityMedium), FontStyle::LARGE);
|
||||
break;
|
||||
case 3:
|
||||
OLED::print(SettingSensitivityHigh, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingSensitivityHigh), FontStyle::LARGE);
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
OLED::print(SettingSensitivityOff, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SettingSensitivityOff), FontStyle::LARGE);
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
@@ -996,7 +996,7 @@ static bool animOpenState = false;
|
||||
static void displayMenu(size_t index) {
|
||||
// Call into the menu
|
||||
// Draw title
|
||||
OLED::printWholeScreen(SettingsMenuEntries[index]);
|
||||
OLED::printWholeScreen(translatedString(Tr->SettingsMenuEntries[index]));
|
||||
// Draw symbol
|
||||
// 16 pixel wide image
|
||||
// 2 pixel wide scrolling indicator
|
||||
@@ -1110,7 +1110,7 @@ void gui_Menu(const menuitem *menu) {
|
||||
OLED::setCursor(0, 0);
|
||||
// If the user has hesitated for >=3 seconds, show the long text
|
||||
// Otherwise "draw" the option
|
||||
if ((xTaskGetTickCount() - lastButtonTime < (TICKS_SECOND * 3)) || menu[currentScreen].description == nullptr) {
|
||||
if ((xTaskGetTickCount() - lastButtonTime < (TICKS_SECOND * 3)) || menu[currentScreen].description == 0) {
|
||||
lcdRefresh = true;
|
||||
OLED::clearScreen();
|
||||
if (menu[currentScreen].draw()) {
|
||||
@@ -1128,7 +1128,7 @@ void gui_Menu(const menuitem *menu) {
|
||||
// Draw description
|
||||
if (descriptionStart == 0)
|
||||
descriptionStart = xTaskGetTickCount();
|
||||
const char *description = menu[currentScreen].description;
|
||||
const char *description = translatedString(Tr->SettingsDescriptions[menu[currentScreen].description - 1]);
|
||||
// lower the value - higher the speed
|
||||
int16_t descriptionWidth = FONT_12_WIDTH * (str_display_len(description) + 7);
|
||||
int16_t descriptionOffset = ((xTaskGetTickCount() - descriptionStart) / (systemSettings.descriptionScrollSpeed == 1 ? (TICKS_100MS / 10) : (TICKS_100MS / 5)));
|
||||
|
||||
@@ -107,13 +107,13 @@ static bool checkVoltageForExit() {
|
||||
OLED::clearScreen();
|
||||
OLED::setCursor(0, 0);
|
||||
if (systemSettings.detailedSoldering) {
|
||||
OLED::print(UndervoltageString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->UndervoltageString), FontStyle::SMALL);
|
||||
OLED::setCursor(0, 8);
|
||||
OLED::print(InputVoltageString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->InputVoltageString), FontStyle::SMALL);
|
||||
printVoltage();
|
||||
OLED::print(SymbolVolts, FontStyle::SMALL);
|
||||
} else {
|
||||
OLED::print(UVLOWarningString, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->UVLOWarningString), FontStyle::LARGE);
|
||||
}
|
||||
|
||||
OLED::refresh();
|
||||
@@ -326,9 +326,9 @@ static int gui_SolderingSleepingMode(bool stayOff, bool autoStarted) {
|
||||
OLED::clearScreen();
|
||||
OLED::setCursor(0, 0);
|
||||
if (systemSettings.detailedSoldering) {
|
||||
OLED::print(SleepingAdvancedString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->SleepingAdvancedString), FontStyle::SMALL);
|
||||
OLED::setCursor(0, 8);
|
||||
OLED::print(SleepingTipAdvancedString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->SleepingTipAdvancedString), FontStyle::SMALL);
|
||||
OLED::printNumber(tipTemp, 3, FontStyle::SMALL);
|
||||
if (systemSettings.temperatureInF)
|
||||
OLED::print(SymbolDegF, FontStyle::SMALL);
|
||||
@@ -340,7 +340,7 @@ static int gui_SolderingSleepingMode(bool stayOff, bool autoStarted) {
|
||||
printVoltage();
|
||||
OLED::print(SymbolVolts, FontStyle::SMALL);
|
||||
} else {
|
||||
OLED::print(SleepingSimpleString, FontStyle::LARGE);
|
||||
OLED::print(translatedString(Tr->SleepingSimpleString), FontStyle::LARGE);
|
||||
OLED::printNumber(tipTemp, 3, FontStyle::LARGE);
|
||||
if (systemSettings.temperatureInF)
|
||||
OLED::drawSymbol(0);
|
||||
@@ -462,7 +462,7 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
case BUTTON_BOTH_LONG:
|
||||
// Unlock buttons
|
||||
buttonsLocked = false;
|
||||
warnUser(UnlockingKeysString, TICKS_SECOND);
|
||||
warnUser(translatedString(Tr->UnlockingKeysString), TICKS_SECOND);
|
||||
break;
|
||||
case BUTTON_F_LONG:
|
||||
// if boost mode is enabled turn it on
|
||||
@@ -476,7 +476,7 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
case BUTTON_F_SHORT:
|
||||
case BUTTON_B_SHORT:
|
||||
// Do nothing and display a lock warming
|
||||
warnUser(WarningKeysLockedString, TICKS_SECOND / 2);
|
||||
warnUser(translatedString(Tr->WarningKeysLockedString), TICKS_SECOND / 2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -511,7 +511,7 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
if (systemSettings.lockingMode != 0) {
|
||||
// Lock buttons
|
||||
buttonsLocked = true;
|
||||
warnUser(LockingKeysString, TICKS_SECOND);
|
||||
warnUser(translatedString(Tr->LockingKeysString), TICKS_SECOND);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -523,7 +523,7 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
OLED::clearScreen();
|
||||
// Draw in the screen details
|
||||
if (systemSettings.detailedSoldering) {
|
||||
OLED::print(SolderingAdvancedPowerPrompt, FontStyle::SMALL); // Power:
|
||||
OLED::print(translatedString(Tr->SolderingAdvancedPowerPrompt), FontStyle::SMALL); // Power:
|
||||
OLED::printNumber(x10WattHistory.average() / 10, 2, FontStyle::SMALL);
|
||||
OLED::print(SymbolDot, FontStyle::SMALL);
|
||||
OLED::printNumber(x10WattHistory.average() % 10, 1, FontStyle::SMALL);
|
||||
@@ -535,7 +535,7 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
}
|
||||
|
||||
OLED::setCursor(0, 8);
|
||||
OLED::print(SleepingTipAdvancedString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->SleepingTipAdvancedString), FontStyle::SMALL);
|
||||
gui_drawTipTemp(true, FontStyle::SMALL);
|
||||
|
||||
if (boostModeOn) {
|
||||
@@ -713,7 +713,7 @@ void showDebugMenu(void) {
|
||||
void showWarnings() {
|
||||
// Display alert if settings were reset
|
||||
if (settingsWereReset) {
|
||||
warnUser(SettingsResetMessage, 10 * TICKS_SECOND);
|
||||
warnUser(translatedString(Tr->SettingsResetMessage), 10 * TICKS_SECOND);
|
||||
}
|
||||
#ifndef NO_WARN_MISSING
|
||||
// We also want to alert if accel or pd is not detected / not responding
|
||||
@@ -727,7 +727,7 @@ void showWarnings() {
|
||||
if (systemSettings.accelMissingWarningCounter < 2) {
|
||||
systemSettings.accelMissingWarningCounter++;
|
||||
saveSettings();
|
||||
warnUser(NoAccelerometerMessage, 10 * TICKS_SECOND);
|
||||
warnUser(translatedString(Tr->NoAccelerometerMessage), 10 * TICKS_SECOND);
|
||||
}
|
||||
}
|
||||
#ifdef POW_PD
|
||||
@@ -736,7 +736,7 @@ void showWarnings() {
|
||||
if (systemSettings.pdMissingWarningCounter < 2) {
|
||||
systemSettings.pdMissingWarningCounter++;
|
||||
saveSettings();
|
||||
warnUser(NoPowerDeliveryMessage, 10 * TICKS_SECOND);
|
||||
warnUser(translatedString(Tr->NoPowerDeliveryMessage), 10 * TICKS_SECOND);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -844,16 +844,16 @@ void startGUITask(void const *argument __unused) {
|
||||
OLED::setCursor(0, 0);
|
||||
if (systemSettings.detailedIDLE) {
|
||||
if (tipTemp > tipDisconnectedThres) {
|
||||
OLED::print(TipDisconnectedString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->TipDisconnectedString), FontStyle::SMALL);
|
||||
} else {
|
||||
OLED::print(IdleTipString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->IdleTipString), FontStyle::SMALL);
|
||||
gui_drawTipTemp(false, FontStyle::SMALL);
|
||||
OLED::print(IdleSetString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->IdleSetString), FontStyle::SMALL);
|
||||
OLED::printNumber(systemSettings.SolderingTemp, 3, FontStyle::SMALL);
|
||||
}
|
||||
OLED::setCursor(0, 8);
|
||||
|
||||
OLED::print(InputVoltageString, FontStyle::SMALL);
|
||||
OLED::print(translatedString(Tr->InputVoltageString), FontStyle::SMALL);
|
||||
printVoltage();
|
||||
|
||||
} else {
|
||||
|
||||
@@ -322,7 +322,7 @@ Core/Gen/Translation.%.cpp: ../Translations/translation_%.json Makefile ../Trans
|
||||
@python3 ../Translations/make_translation.py -o $(PWD)/$@ $*
|
||||
|
||||
clean :
|
||||
rm -Rf $(SOURCE_CORE_DIR)/Translation.cpp Core/Gen
|
||||
rm -Rf Core/Gen
|
||||
rm -Rf $(OUTPUT_DIR_BASE)
|
||||
rm -Rf $(HEXFILE_DIR)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user