diff --git a/selfdrive/ui/qt/text.cc b/selfdrive/ui/qt/text.cc index 4b5f8ee21e..7fdf6f6559 100644 --- a/selfdrive/ui/qt/text.cc +++ b/selfdrive/ui/qt/text.cc @@ -1,9 +1,7 @@ -#include #include #include #include #include -#include #include #include #include @@ -29,50 +27,51 @@ std::string executeCommand(const char* cmd) { return result.str(); } -// The format is intentional! +QLabel *label; + +// The format is intentional, even if on PC doesn't look aligned. Font differences are likely the cause. On device it looks fine. QString text = QString("%1\n%2\n%3\n%4\n%5\n%6\n%7") - .arg(" ________________________________________") - .arg("| |") - .arg("| " + QObject::tr("Update downloaded. Ready to reboot.") + " |") - .arg("| |") - .arg("| " + QObject::tr("Update: Check and Download Update") + " |") - .arg("| " + QObject::tr("Reboot: Reboot Device") + " |") - .arg("|________________________________________|"); + .arg(" ________________________________________________________") + .arg("|\t\t\t\t\t\t|") + .arg("|\t" + QObject::tr("Update downloaded. Ready to reboot.") + "\t|") + .arg("|\t\t\t\t\t\t|") + .arg("|\t" + QObject::tr("Update: Check and Download Update") + "\t\t|") + .arg("|\t" + QObject::tr("Reboot: Reboot Device") + "\t\t\t|") + .arg("| _______________________________________________________\t|"); -int main(int argc, char *argv[]) { - initApp(argc, argv); - QApplication a(argc, argv); - QWidget window; - setMainWindow(&window); - - QGridLayout *main_layout = new QGridLayout(&window); - main_layout->setMargin(50); - - QLabel *label = new QLabel(argv[1]); +void setupErrorMessageLabel(QVBoxLayout *main_layout) { label->setWordWrap(true); label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::MinimumExpanding); label->setAlignment(Qt::AlignTop | Qt::AlignLeft); - ScrollView *scroll = new ScrollView(label); + auto *scroll = new ScrollView(label); scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - main_layout->addWidget(scroll, 0, 0, Qt::AlignTop); + main_layout->addWidget(scroll); // Scroll to the bottom QObject::connect(scroll->verticalScrollBar(), &QAbstractSlider::rangeChanged, [=]() { scroll->verticalScrollBar()->setValue(scroll->verticalScrollBar()->maximum()); }); +} - QPushButton *btn = new QPushButton(); - QPushButton *update_btn = new QPushButton(); +void setupActionButton(QGridLayout *button_grid) { + auto *left_buttons = new QHBoxLayout(); + auto *right_buttons = new QHBoxLayout(); + + auto *btn = new QPushButton(); + auto *update_btn = new QPushButton(); update_btn->setText(QObject::tr("Update")); + auto *reinstall_btn = new QPushButton(); + reinstall_btn->setText(QObject::tr("Launch Setup")); #ifdef __aarch64__ btn->setText(QObject::tr("Reboot")); - QFutureWatcher watcher; + auto *watcher = new QFutureWatcher(); QObject::connect(btn, &QPushButton::clicked, [=]() { Hardware::reboot(); }); - QObject::connect(update_btn, &QPushButton::clicked, [=, &watcher]() { + QObject::connect(update_btn, &QPushButton::clicked, [=]() { btn->setEnabled(false); update_btn->setEnabled(false); + reinstall_btn->setEnabled(false); update_btn->setText(QObject::tr("Updating...")); const std::string git_branch = Params().get("GitBranch"); const std::string git_remote = Params().get("GitRemote"); @@ -90,26 +89,70 @@ int main(int argc, char *argv[]) { const std::string cmd = to_home_dir + "; " + remote_cmd + "; " + fetch_remote + "; " + reset_branch; QFuture future = QtConcurrent::run([=]() { - label->clear(); std::string output = executeCommand(cmd.c_str()); - //LOGW("CHECK OUTPUT PLS\n%s", output.c_str()); - QMetaObject::invokeMethod(label, "setText", Qt::QueuedConnection, - Q_ARG(QString, QString::fromStdString(output) + text)); + auto formatted = QString::fromStdString(output) + text; + QMetaObject::invokeMethod(label, "clear", Qt::QueuedConnection); + QMetaObject::invokeMethod(label, "setText", Qt::QueuedConnection, Q_ARG(QString, formatted)); }); - QObject::connect(&watcher, &QFutureWatcher::finished, [=]() { - btn->setEnabled(true); - update_btn->setEnabled(true); - update_btn->setText(QObject::tr("Update")); - }); - watcher.setFuture(future); + watcher->setFuture(future); }); + QObject::connect(watcher, &QFutureWatcher::finished, [=]() { + btn->setEnabled(true); + update_btn->setEnabled(true); + reinstall_btn->setEnabled(true); + update_btn->setText(QObject::tr("Update")); + }); + + QObject::connect(reinstall_btn, &QPushButton::clicked, [=]() { + btn->setEnabled(false); + update_btn->setEnabled(false); + reinstall_btn->setEnabled(false); + reinstall_btn->setText(QObject::tr("Starting setup...")); + + const std::string delete_continue = "sudo rm /data/continue.sh"; + const std::string restart_op = "sudo systemctl restart comma"; + + const std::string cmd = delete_continue + "; " + restart_op + "; "; + + // Start setup command asynchronously + QtConcurrent::run([=]() { + executeCommand(cmd.c_str()); + }); + QApplication::quit(); + }); + #else update_btn->setEnabled(false); btn->setText(QObject::tr("Exit")); - QObject::connect(btn, &QPushButton::clicked, &a, &QApplication::quit); + QObject::connect(btn, &QPushButton::clicked, &app, &QApplication::quit); #endif - main_layout->addWidget(btn, 0, 0, Qt::AlignRight | Qt::AlignBottom); - main_layout->addWidget(update_btn, 0, 0, Qt::AlignLeft | Qt::AlignBottom); + left_buttons->addWidget(update_btn); + left_buttons->addWidget(reinstall_btn); + right_buttons->addWidget(btn); + + button_grid->addLayout(left_buttons, 0, 0, Qt::AlignLeft | Qt::AlignBottom); + button_grid->addLayout(right_buttons, 0, 1, Qt::AlignRight | Qt::AlignBottom); +} + +int main(int argc, char *argv[]) { + initApp(argc, argv); + QApplication app(argc, argv); + QWidget window; + setMainWindow(&window); + + auto *main_layout = new QVBoxLayout(&window); + main_layout->setMargin(50); + + // Setup the text area layout + auto *text_layout = new QVBoxLayout(); + label = new QLabel(argv[1]); + setupErrorMessageLabel(text_layout); + main_layout->addLayout(text_layout); + + // Setup the button area layout + auto *button_layout = new QGridLayout(); + setupActionButton(button_layout); + main_layout->addLayout(button_layout); window.setStyleSheet(R"( * { @@ -126,11 +169,14 @@ int main(int argc, char *argv[]) { border-radius: 20px; margin-right: 40px; } + QPushButton:pressed { + background-color: #4a4a4a; + } QPushButton:disabled { color: #33FFFFFF; border: 2px solid #33FFFFFF; } )"); - return a.exec(); + return QApplication::exec(); }