mirror of
https://github.com/dragonpilot/dragonpilot.git
synced 2026-10-01 03:43:42 +08:00
dragonpilot v2023.07.05
version: dragonpilot v0.9.4 release date: 2023-07-05T18:59:41 dp-dev(priv) master commit: 7b0489feab40283a422d2201ef95a9cb8c06f6cd
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
moc_*
|
||||
*.moc
|
||||
|
||||
translations/main_test_en.*
|
||||
|
||||
_mui
|
||||
watch3
|
||||
installer/installers/*
|
||||
qt/text
|
||||
qt/spinner
|
||||
qt/setup/setup
|
||||
qt/setup/reset
|
||||
qt/setup/wifi
|
||||
qt/setup/updater
|
||||
translations/alerts_generated.h
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1,47 @@
|
||||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
signal scroll()
|
||||
|
||||
Flickable {
|
||||
id: flickArea
|
||||
objectName: "flickArea"
|
||||
anchors.fill: parent
|
||||
contentHeight: helpText.height
|
||||
contentWidth: width - (leftMargin + rightMargin)
|
||||
bottomMargin: 50
|
||||
topMargin: 50
|
||||
rightMargin: 50
|
||||
leftMargin: 50
|
||||
flickableDirection: Flickable.VerticalFlick
|
||||
flickDeceleration: 7500.0
|
||||
maximumFlickVelocity: 10000.0
|
||||
pixelAligned: true
|
||||
|
||||
onAtYEndChanged: root.scroll()
|
||||
|
||||
Text {
|
||||
id: helpText
|
||||
width: flickArea.contentWidth
|
||||
font.family: "Inter"
|
||||
font.weight: "Light"
|
||||
font.pixelSize: 50
|
||||
textFormat: Text.RichText
|
||||
color: "#C9C9C9"
|
||||
wrapMode: Text.Wrap
|
||||
text: text_view
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: scrollbar
|
||||
anchors.right: flickArea.right
|
||||
anchors.rightMargin: 20
|
||||
y: flickArea.topMargin + flickArea.visibleArea.yPosition * (flickArea.height - flickArea.bottomMargin - flickArea.topMargin)
|
||||
width: 12
|
||||
radius: 6
|
||||
height: flickArea.visibleArea.heightRatio * (flickArea.height - flickArea.bottomMargin - flickArea.topMargin)
|
||||
color: "#808080"
|
||||
}
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
@@ -0,0 +1 @@
|
||||
_soundd
|
||||
Executable
BIN
Binary file not shown.
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
cd "$(dirname "$0")"
|
||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH"
|
||||
export QT_QPA_PLATFORM="offscreen"
|
||||
exec ./_soundd
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f /TICI ] && [ ! -f qt/spinner ]; then
|
||||
cp qt/spinner_larch64 qt/spinner
|
||||
fi
|
||||
|
||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH"
|
||||
exec ./qt/spinner "$1"
|
||||
Executable
+103
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import unittest
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from selfdrive.ui.update_translations import TRANSLATIONS_DIR, LANGUAGES_FILE, update_translations
|
||||
|
||||
TMP_TRANSLATIONS_DIR = os.path.join(TRANSLATIONS_DIR, "tmp")
|
||||
UNFINISHED_TRANSLATION_TAG = "<translation type=\"unfinished\"" # non-empty translations can be marked unfinished
|
||||
LOCATION_TAG = "<location "
|
||||
|
||||
|
||||
class TestTranslations(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
with open(LANGUAGES_FILE, "r") as f:
|
||||
cls.translation_files = json.load(f)
|
||||
|
||||
# Set up temp directory
|
||||
shutil.copytree(TRANSLATIONS_DIR, TMP_TRANSLATIONS_DIR, dirs_exist_ok=True)
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
shutil.rmtree(TMP_TRANSLATIONS_DIR, ignore_errors=True)
|
||||
|
||||
@staticmethod
|
||||
def _read_translation_file(path, file):
|
||||
tr_file = os.path.join(path, f"{file}.ts")
|
||||
with open(tr_file, "r") as f:
|
||||
return f.read()
|
||||
|
||||
def test_missing_translation_files(self):
|
||||
for name, file in self.translation_files.items():
|
||||
with self.subTest(name=name, file=file):
|
||||
self.assertTrue(os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")),
|
||||
f"{name} has no XML translation file, run selfdrive/ui/update_translations.py")
|
||||
|
||||
def test_translations_updated(self):
|
||||
update_translations(plural_only=["main_en"], translations_dir=TMP_TRANSLATIONS_DIR)
|
||||
|
||||
for name, file in self.translation_files.items():
|
||||
with self.subTest(name=name, file=file):
|
||||
# caught by test_missing_translation_files
|
||||
if not os.path.exists(os.path.join(TRANSLATIONS_DIR, f"{file}.ts")):
|
||||
self.skipTest(f"{name} missing translation file")
|
||||
|
||||
cur_translations = self._read_translation_file(TRANSLATIONS_DIR, file)
|
||||
new_translations = self._read_translation_file(TMP_TRANSLATIONS_DIR, file)
|
||||
self.assertEqual(cur_translations, new_translations,
|
||||
f"{file} ({name}) XML translation file out of date. Run selfdrive/ui/update_translations.py to update the translation files")
|
||||
|
||||
@unittest.skip("Only test unfinished translations before going to release")
|
||||
def test_unfinished_translations(self):
|
||||
for name, file in self.translation_files.items():
|
||||
with self.subTest(name=name, file=file):
|
||||
cur_translations = self._read_translation_file(TRANSLATIONS_DIR, file)
|
||||
self.assertTrue(UNFINISHED_TRANSLATION_TAG not in cur_translations,
|
||||
f"{file} ({name}) translation file has unfinished translations. Finish translations or mark them as completed in Qt Linguist")
|
||||
|
||||
def test_vanished_translations(self):
|
||||
for name, file in self.translation_files.items():
|
||||
with self.subTest(name=name, file=file):
|
||||
cur_translations = self._read_translation_file(TRANSLATIONS_DIR, file)
|
||||
self.assertTrue("<translation type=\"vanished\">" not in cur_translations,
|
||||
f"{file} ({name}) translation file has obsolete translations. Run selfdrive/ui/update_translations.py --vanish to remove them")
|
||||
|
||||
def test_plural_translations(self):
|
||||
"""
|
||||
Tests:
|
||||
- that any numerus (plural) translations marked "finished" have all plural forms non-empty
|
||||
- that the correct format specifier is used (%n)
|
||||
"""
|
||||
for name, file in self.translation_files.items():
|
||||
with self.subTest(name=name, file=file):
|
||||
tr_xml = ET.parse(os.path.join(TRANSLATIONS_DIR, f"{file}.ts"))
|
||||
|
||||
for context in tr_xml.getroot():
|
||||
for message in context.iterfind("message"):
|
||||
if message.get("numerus") == "yes":
|
||||
translation = message.find("translation")
|
||||
numerusform = [t.text for t in translation.findall("numerusform")]
|
||||
|
||||
# Do not assert finished translations
|
||||
if translation.get("type") == "unfinished":
|
||||
continue
|
||||
|
||||
self.assertNotIn(None, numerusform, "Ensure all plural translation forms are completed.")
|
||||
self.assertTrue(all([re.search("%[0-9]+", t) is None for t in numerusform]),
|
||||
"Plural translations must use %n, not %1, %2, etc.: {}".format(numerusform))
|
||||
|
||||
def test_no_locations(self):
|
||||
for name, file in self.translation_files.items():
|
||||
with self.subTest(name=name, file=file):
|
||||
for line in self._read_translation_file(TRANSLATIONS_DIR, file).splitlines():
|
||||
self.assertFalse(line.strip().startswith(LOCATION_TAG),
|
||||
f"Line contains location tag: {line.strip()}, remove all line numbers.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -f /TICI ] && [ ! -f qt/text ]; then
|
||||
cp qt/text_larch64 qt/text
|
||||
fi
|
||||
|
||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH"
|
||||
exec ./qt/text "$1"
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"English": "main_en",
|
||||
"Deutsch": "main_de",
|
||||
"Português": "main_pt-BR",
|
||||
"中文(繁體)": "main_zh-CHT",
|
||||
"中文(简体)": "main_zh-CHS",
|
||||
"한국어": "main_ko",
|
||||
"日本語": "main_ja"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>InputDialog</name>
|
||||
<message numerus="yes">
|
||||
<source>Need at least %n character(s)!</source>
|
||||
<translation>
|
||||
<numerusform>Need at least %n character!</numerusform>
|
||||
<numerusform>Need at least %n characters!</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message numerus="yes">
|
||||
<source>%n minute(s) ago</source>
|
||||
<translation>
|
||||
<numerusform>%n minute ago</numerusform>
|
||||
<numerusform>%n minutes ago</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n hour(s) ago</source>
|
||||
<translation>
|
||||
<numerusform>%n hour ago</numerusform>
|
||||
<numerusform>%n hours ago</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
<message numerus="yes">
|
||||
<source>%n day(s) ago</source>
|
||||
<translation>
|
||||
<numerusform>%n day ago</numerusform>
|
||||
<numerusform>%n days ago</numerusform>
|
||||
</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+15
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
cd "$(dirname "$0")"
|
||||
export LD_LIBRARY_PATH="/system/lib64:$LD_LIBRARY_PATH"
|
||||
export QT_DBL_CLICK_DIST=150
|
||||
if [ -f /data/params/d/dp_nav ]; then
|
||||
NAV=`cat /data/params/d/dp_nav`
|
||||
else
|
||||
NAV="0"
|
||||
fi
|
||||
|
||||
if [ $NAV == "0" ] && [ -f /data/openpilot/selfdrive/ui/_ui_nonav ]; then
|
||||
exec ./_ui_nonav
|
||||
else
|
||||
exec ./_ui
|
||||
fi
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
try:
|
||||
from common.basedir import BASEDIR
|
||||
|
||||
UI_DIR = os.path.join(BASEDIR, "selfdrive", "ui")
|
||||
except ModuleNotFoundError:
|
||||
UI_DIR = os.path.join("", "selfdrive", "ui")
|
||||
|
||||
TRANSLATIONS_DIR = os.path.join(UI_DIR, "translations")
|
||||
LANGUAGES_FILE = os.path.join(TRANSLATIONS_DIR, "languages.json")
|
||||
TRANSLATIONS_INCLUDE_FILE = os.path.join(TRANSLATIONS_DIR, "alerts_generated.h")
|
||||
|
||||
|
||||
def generate_translations_include():
|
||||
# offroad alerts
|
||||
# TODO translate events from selfdrive/controls/lib/events.py
|
||||
content = "// THIS IS AN AUTOGENERATED FILE, PLEASE EDIT alerts_offroad.json\n"
|
||||
with open(os.path.join(BASEDIR, "selfdrive/controls/lib/alerts_offroad.json")) as f:
|
||||
for alert in json.load(f).values():
|
||||
content += f'QT_TRANSLATE_NOOP("OffroadAlert", R"({alert["text"]})");\n'
|
||||
|
||||
with open(TRANSLATIONS_INCLUDE_FILE, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
def update_translations(vanish=False, plural_only=None, translations_dir=TRANSLATIONS_DIR):
|
||||
generate_translations_include()
|
||||
|
||||
if plural_only is None:
|
||||
plural_only = []
|
||||
|
||||
with open(LANGUAGES_FILE, "r") as f:
|
||||
translation_files = json.load(f)
|
||||
|
||||
for file in translation_files.values():
|
||||
tr_file = os.path.join(translations_dir, f"{file}.ts")
|
||||
args = f"lupdate -locations none -recursive {UI_DIR} -ts {tr_file} -I {BASEDIR}"
|
||||
if vanish:
|
||||
args += " -no-obsolete"
|
||||
if file in plural_only:
|
||||
args += " -pluralonly"
|
||||
ret = os.system(args)
|
||||
assert ret == 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Update translation files for UI",
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
parser.add_argument("--vanish", action="store_true", help="Remove translations with source text no longer found")
|
||||
parser.add_argument("--plural-only", type=str, nargs="*", default=["main_en"], help="Translation codes to only create plural translations for (ie. the base language)")
|
||||
args = parser.parse_args()
|
||||
|
||||
update_translations(args.vanish, args.plural_only)
|
||||
Reference in New Issue
Block a user