Compare commits

...

4 Commits

Author SHA1 Message Date
Jason Wen
d71965c6d1 Revert "ui: new design for Device panel buttons (#557)"
This reverts commit 4a60eb50e5.
2025-01-17 15:05:24 -05:00
Jason Wen
2f5f708c2b more 2025-01-17 14:59:06 -05:00
Jason Wen
bd8a93af8b try this 2025-01-17 14:52:42 -05:00
Jason Wen
c08b18936d ui: driver view window should use uiStateSP 2025-01-17 14:37:23 -05:00
23 changed files with 25 additions and 590 deletions

View File

@@ -4,6 +4,10 @@
#include "selfdrive/ui/qt/onroad/driver_monitoring.h"
#include "selfdrive/ui/qt/widgets/input.h"
#ifdef SUNNYPILOT
#define Device DeviceSP
#endif
class DriverViewWindow : public CameraWidget {
Q_OBJECT
public:

View File

@@ -203,11 +203,6 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
});
addItem(pair_device);
QObject::connect(uiState()->prime_state, &PrimeState::changed, [this] (PrimeState::Type type) {
pair_device->setVisible(type == PrimeState::PRIME_TYPE_UNPAIRED);
});
#ifndef SUNNYPILOT
// offroad-only buttons
auto dcamBtn = new ButtonControl(tr("Driver Camera"), tr("PREVIEW"),
@@ -219,7 +214,6 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
dcamBtn->setEnabled(true);
});
addItem(dcamBtn);
#endif
auto resetCalibBtn = new ButtonControl(tr("Reset Calibration"), tr("RESET"), "");
connect(resetCalibBtn, &ButtonControl::showDescriptionEvent, this, &DevicePanel::updateCalibDescription);
@@ -231,7 +225,6 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
});
addItem(resetCalibBtn);
#ifndef SUNNYPILOT
auto retrainingBtn = new ButtonControl(tr("Review Training Guide"), tr("REVIEW"), tr("Review the rules, features, and limitations of openpilot"));
connect(retrainingBtn, &ButtonControl::clicked, [=]() {
if (ConfirmationDialog::confirm(tr("Are you sure you want to review the training guide?"), tr("Review"), this)) {
@@ -262,6 +255,9 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
});
addItem(translateBtn);
QObject::connect(uiState()->prime_state, &PrimeState::changed, [this] (PrimeState::Type type) {
pair_device->setVisible(type == PrimeState::PRIME_TYPE_UNPAIRED);
});
QObject::connect(uiState(), &UIState::offroadTransition, [=](bool offroad) {
for (auto btn : findChildren<ButtonControl *>()) {
if (btn != pair_device) {
@@ -295,7 +291,6 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
#poweroff_btn:pressed { background-color: #FF2424; }
)");
addItem(power_layout);
#endif
}
void DevicePanel::updateCalibDescription() {

View File

@@ -2,7 +2,13 @@
#include <vector>
#include <QPainter>
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/ui.h"
#define UIState UIStateSP
#else
#include "selfdrive/ui/ui.h"
#endif
class DriverMonitorRenderer {
public:

View File

@@ -16,7 +16,6 @@ qt_src = [
"sunnypilot/qt/window.cc",
"sunnypilot/qt/home.cc",
"sunnypilot/qt/offroad/offroad_home.cc",
"sunnypilot/qt/offroad/settings/device_panel.cc",
"sunnypilot/qt/offroad/settings/settings.cc",
"sunnypilot/qt/offroad/settings/software_panel.cc",
"sunnypilot/qt/offroad/settings/sunnylink_panel.cc",

View File

@@ -1,88 +0,0 @@
/**
* Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
*
* This file is part of sunnypilot and is licensed under the MIT License.
* See the LICENSE.md file in the root directory for more details.
*/
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h"
#include "common/watchdog.h"
#include "selfdrive/ui/qt/offroad/driverview.h"
#include "selfdrive/ui/qt/qt_window.h"
DevicePanelSP::DevicePanelSP(SettingsWindowSP *parent) : DevicePanel(parent) {
QGridLayout *device_grid_layout = new QGridLayout();
device_grid_layout->setSpacing(30);
device_grid_layout->setHorizontalSpacing(5);
device_grid_layout->setVerticalSpacing(25);
std::vector<std::pair<QString, QString>> device_btns = {
{"dcamBtn", tr("Driver Camera Preview")},
{"retrainingBtn", tr("Training Guide")},
{"regulatoryBtn", tr("Regulatory")},
{"translateBtn", tr("Language")},
};
for (int i = 0; i < device_btns.size(); i++) {
auto *btn = new PushButtonSP(device_btns[i].second, 720, this);
device_grid_layout->addWidget(btn, i / 2, i % 2);
buttons[device_btns[i].first] = btn;
}
connect(buttons["dcamBtn"], &PushButtonSP::clicked, [this]() {
buttons["dcamBtn"]->setEnabled(false);
DriverViewDialog driver_view(this);
driver_view.exec();
buttons["dcamBtn"]->setEnabled(true);
});
connect(buttons["retrainingBtn"], &PushButtonSP::clicked, [=]() {
if (ConfirmationDialog::confirm(tr("Are you sure you want to review the training guide?"), tr("Review"), this)) {
emit reviewTrainingGuide();
}
});
if (Hardware::TICI()) {
connect(buttons["regulatoryBtn"], &PushButtonSP::clicked, [=]() {
const std::string txt = util::read_file("../assets/offroad/fcc.html");
ConfirmationDialog::rich(QString::fromStdString(txt), this);
});
} else {
buttons["regulatoryBtn"]->setEnabled(false);
}
connect(buttons["translateBtn"], &PushButtonSP::clicked, [=]() {
QMap<QString, QString> langs = getSupportedLanguages();
QString selection = MultiOptionDialog::getSelection(tr("Select a language"), langs.keys(), langs.key(uiState()->language), this);
if (!selection.isEmpty()) {
// put language setting, exit Qt UI, and trigger fast restart
params.put("LanguageSetting", langs[selection].toStdString());
qApp->exit(18);
watchdog_kick(0);
}
});
addItem(device_grid_layout);
// offroad mode and power buttons
QHBoxLayout *power_layout = new QHBoxLayout();
power_layout->setSpacing(5);
QPushButton *rebootBtn = new PushButtonSP(tr("Reboot"), 720, this);
rebootBtn->setStyleSheet(rebootButtonStyle);
power_layout->addWidget(rebootBtn);
QObject::connect(rebootBtn, &PushButtonSP::clicked, this, &DevicePanelSP::reboot);
QPushButton *poweroffBtn = new PushButtonSP(tr("Power Off"), 720, this);
poweroffBtn->setStyleSheet(powerOffButtonStyle);
power_layout->addWidget(poweroffBtn);
QObject::connect(poweroffBtn, &PushButtonSP::clicked, this, &DevicePanelSP::poweroff);
if (!Hardware::PC()) {
connect(uiState(), &UIState::offroadTransition, poweroffBtn, &PushButtonSP::setVisible);
}
addItem(power_layout);
}

View File

@@ -1,51 +0,0 @@
/**
* Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
*
* This file is part of sunnypilot and is licensed under the MIT License.
* See the LICENSE.md file in the root directory for more details.
*/
#pragma once
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/settings.h"
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
class DevicePanelSP : public DevicePanel {
Q_OBJECT
public:
explicit DevicePanelSP(SettingsWindowSP *parent = 0);
private:
std::map<QString, PushButtonSP*> buttons;
const QString rebootButtonStyle = R"(
PushButtonSP {
border-radius: 20px;
font-size: 50px;
font-weight: 450;
height: 150px;
padding: 0 25px 0 25px;
color: #FFFFFF;
background-color: #393939;
}
PushButtonSP:pressed {
background-color: #4A4A4A;
}
)";
const QString powerOffButtonStyle = R"(
PushButtonSP {
border-radius: 20px;
font-size: 50px;
font-weight: 450;
height: 150px;
padding: 0 25px 0 25px;
color: #FFFFFF;
background-color: #E22C2C;
}
PushButtonSP:pressed {
background-color: #FF2424;
}
)";
};

View File

@@ -11,13 +11,12 @@
#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h"
#include "selfdrive/ui/qt/offroad/developer_panel.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/device_panel.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/software_panel.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_panel.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot_panel.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/trips_panel.h"
TogglesPanelSP::TogglesPanelSP(SettingsWindowSP *parent) : TogglesPanel(parent) {
TogglesPanelSP::TogglesPanelSP(SettingsWindow *parent) : TogglesPanel(parent) {
QObject::connect(uiStateSP(), &UIStateSP::uiUpdate, this, &TogglesPanelSP::updateState);
}
@@ -51,7 +50,7 @@ SettingsWindowSP::SettingsWindowSP(QWidget *parent) : SettingsWindow(parent) {
)");
close_btn->setFixedSize(152, 152);
close_btn_layout->addWidget(close_btn, 0, Qt::AlignLeft);
QObject::connect(close_btn, &QPushButton::clicked, this, &SettingsWindowSP::closeSettings);
QObject::connect(close_btn, &QPushButton::clicked, this, &SettingsWindow::closeSettings);
// setup buttons widget
QWidget *buttons_widget = new QWidget;
@@ -60,11 +59,11 @@ SettingsWindowSP::SettingsWindowSP(QWidget *parent) : SettingsWindow(parent) {
buttons_layout->addSpacing(10);
// setup panels
DevicePanelSP *device = new DevicePanelSP(this);
QObject::connect(device, &DevicePanelSP::reviewTrainingGuide, this, &SettingsWindowSP::reviewTrainingGuide);
DevicePanel *device = new DevicePanel(this);
QObject::connect(device, &DevicePanel::reviewTrainingGuide, this, &SettingsWindow::reviewTrainingGuide);
TogglesPanelSP *toggles = new TogglesPanelSP(this);
QObject::connect(this, &SettingsWindowSP::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription);
QObject::connect(this, &SettingsWindow::expandToggleDescription, toggles, &TogglesPanel::expandToggleDescription);
auto networking = new Networking(this);
QObject::connect(uiState()->prime_state, &PrimeState::changed, networking, &Networking::setPrimeType);

View File

@@ -32,7 +32,7 @@ class TogglesPanelSP : public TogglesPanel {
Q_OBJECT
public:
explicit TogglesPanelSP(SettingsWindowSP *parent);
explicit TogglesPanelSP(SettingsWindow *parent);
private slots:
void updateState(const UIStateSP &s);

View File

@@ -27,13 +27,13 @@ SunnypilotPanel::SunnypilotPanel(SettingsWindowSP *parent) : QFrame(parent) {
madsToggle->setConfirmation(true, false);
list->addItem(madsToggle);
madsSettingsButton = new PushButtonSP(tr("Customize MADS"));
madsSettingsButton = new SubPanelButton(tr("Customize MADS"));
madsSettingsButton->setObjectName("mads_btn");
connect(madsSettingsButton, &QPushButton::clicked, [=]() {
sunnypilotScroller->setLastScrollPosition();
main_layout->setCurrentWidget(madsWidget);
});
QObject::connect(madsToggle, &ToggleControl::toggleFlipped, madsSettingsButton, &PushButtonSP::setEnabled);
QObject::connect(madsToggle, &ToggleControl::toggleFlipped, madsSettingsButton, &SubPanelButton::setEnabled);
madsWidget = new MadsSettings(this);
connect(madsWidget, &MadsSettings::backPress, [=]() {

View File

@@ -35,6 +35,6 @@ private:
bool offroad;
ParamControl *madsToggle;
PushButtonSP *madsSettingsButton;
SubPanelButton *madsSettingsButton;
MadsSettings *madsWidget = nullptr;
};

View File

@@ -546,11 +546,11 @@ private:
bool button_enabled = true;
};
class PushButtonSP : public QPushButton {
class SubPanelButton : public QPushButton {
Q_OBJECT
public:
PushButtonSP(const QString &text, const int minimum_button_width = 800, QWidget *parent = nullptr) : QPushButton(text, parent) {
SubPanelButton(const QString &text, const int minimum_button_width = 800, QWidget *parent = nullptr) : QPushButton(text, parent) {
const QString buttonStyle = R"(
QPushButton {
border-radius: 20px;

View File

@@ -133,7 +133,7 @@ def setup_keyboard_uppercase(click, pm: PubMaster, scroll=None):
def setup_driver_camera(click, pm: PubMaster, scroll=None):
setup_settings_device(click, pm)
click(950, 620)
click(1950, 435)
DATA['deviceState'].deviceState.started = False
setup_onroad(click, pm)
DATA['deviceState'].deviceState.started = True

View File

@@ -283,45 +283,6 @@
<translation>إقران</translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished">إعادة التشغيل</translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished">التنظيمية</translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">هل أنت متأكد أنك تريد مراجعة دليل التدريب؟</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished">مراجعة</translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished">اختر لغة</translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished">إيقاف التشغيل</translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished">Neustart</translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished">Rechtliche Hinweise</translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">Bist du sicher, dass du die Trainingsanleitung wiederholen möchtest?</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished">Überprüfen</translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished">Sprache wählen</translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished">Ausschalten</translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation>Desactivar para apagar</translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished">Reiniciar</translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished">Regulador</translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">¿Seguro que quiere revisar la guía de entrenamiento?</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished">Revisar</translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished">Apagar</translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished">Redémarrer</translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished">Réglementaire</translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">Êtes-vous sûr de vouloir revoir le guide de formation ?</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished">Revoir</translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished">Choisir une langue</translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished">Éteindre</translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">使</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished"> ?</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished"> </translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished"> </translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation>PAREAR</translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished">Reiniciar</translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished">Regulatório</translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">Tem certeza que quer rever o treinamento?</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished">Revisar</translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished">Selecione o Idioma</translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished">Desligar</translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">?</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished">Yeniden başlat</translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished">Mevzuat</translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">Eğitim kılavuzunu incelemek istediğinizden emin misiniz?</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished">Dil seçin</translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished">Sistemi kapat</translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>

View File

@@ -283,45 +283,6 @@
<translation></translation>
</message>
</context>
<context>
<name>DevicePanelSP</name>
<message>
<source>Driver Camera Preview</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Training Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Reboot</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Regulatory</source>
<translation type="unfinished">/</translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
<translation type="unfinished">使</translation>
</message>
<message>
<source>Review</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a language</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Power Off</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>DriveStats</name>
<message>