From 80c3d67a2853a5fe6c290439fa5dbccfa44949ae Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sun, 7 Feb 2021 17:33:48 -0800 Subject: [PATCH] Qt UI refactoring + improvements (#20033) old-commit-hash: f9d8652cbda86a4777166b1f970f770fcf65f4f3 --- selfdrive/ui/SConscript | 18 ++- selfdrive/ui/qt/offroad/networking.cc | 200 ++++++++---------------- selfdrive/ui/qt/offroad/networking.hpp | 19 +-- selfdrive/ui/qt/offroad/settings.cc | 13 +- selfdrive/ui/qt/offroad/settings.hpp | 2 - selfdrive/ui/qt/qt_window.cc | 28 ---- selfdrive/ui/qt/qt_window.hpp | 25 ++- selfdrive/ui/qt/setup/installer.cc | 17 +- selfdrive/ui/qt/setup/setup.cc | 156 +++++++++--------- selfdrive/ui/qt/setup/setup.hpp | 9 +- selfdrive/ui/qt/widgets/input_field.cc | 81 ++++++---- selfdrive/ui/qt/widgets/input_field.hpp | 21 ++- selfdrive/ui/qt/widgets/keyboard.cc | 51 +++--- selfdrive/ui/qt/widgets/keyboard.hpp | 3 +- selfdrive/ui/qt/widgets/ssh_keys.cc | 113 ++++++------- selfdrive/ui/qt/widgets/ssh_keys.hpp | 19 +-- 16 files changed, 344 insertions(+), 431 deletions(-) delete mode 100644 selfdrive/ui/qt/qt_window.cc diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 040a61a0df..22b50dfc81 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -18,7 +18,7 @@ else: qt_libs = qt_env["LIBS"] + libs + ["pthread", "ssl", "crypto"] widgets = qt_env.Library("qt_widgets", - ["qt/qt_window.cc", "qt/qt_sound.cc", "qt/widgets/keyboard.cc", "qt/widgets/input_field.cc", "qt/widgets/drive_stats.cc", "qt/widgets/ssh_keys.cc", + ["qt/qt_sound.cc", "qt/widgets/keyboard.cc", "qt/widgets/input_field.cc", "qt/widgets/drive_stats.cc", "qt/widgets/ssh_keys.cc", "qt/offroad/networking.cc", "qt/offroad/wifiManager.cc", "qt/widgets/toggle.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/setup.cc"], LIBS=qt_libs) qt_libs.append(widgets) @@ -43,10 +43,16 @@ else: installers = [ ("openpilot", "master"), - ("openpilot_test", "master"), - #("dashcam", "dashcam"), - #("dashcam_test", "dashcam"), + #("openpilot_test", "release3-staging"), + #("openpilot_internal", "master"), + #("dashcam", "dashcam3-staging"), + #("dashcam_test", "dashcam3-staging"), ] for name, branch in installers: - flags = qt_env["CXXFLAGS"] + [f"-D{branch}"] - qt_env.Program(f"qt/setup/installer_{name}", ["qt/setup/installer.cc"], LIBS=qt_libs) + d = {'BRANCH': f"'\"{branch}\"'"} + if "internal" in name: + import requests + r = requests.get("https://github.com/commaci2.keys") + r.raise_for_status() + d['SSH_KEYS'] = f'\\"{r.text.strip()}\\"' + qt_env.Program(f"qt/setup/installer_{name}", ["qt/setup/installer.cc"], LIBS=qt_libs, CPPDEFINES=d) diff --git a/selfdrive/ui/qt/offroad/networking.cc b/selfdrive/ui/qt/offroad/networking.cc index 7e990b64d2..3bc9f8d870 100644 --- a/selfdrive/ui/qt/offroad/networking.cc +++ b/selfdrive/ui/qt/offroad/networking.cc @@ -29,21 +29,21 @@ QWidget* layoutToWidget(QLayout* l, QWidget* parent){ // https://stackoverflow.com/questions/478898/how-do-i-execute-a-command-and-get-the-output-of-the-command-within-c-using-po std::string exec(const char* cmd) { - std::array buffer; - std::string result; - std::unique_ptr pipe(popen(cmd, "r"), pclose); - if (!pipe) { - throw std::runtime_error("popen() failed!"); - } - while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { - result += buffer.data(); - } - return result; + std::array buffer; + std::string result; + std::unique_ptr pipe(popen(cmd, "r"), pclose); + if (!pipe) { + throw std::runtime_error("popen() failed!"); + } + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; } // Networking functions -Networking::Networking(QWidget* parent) : QWidget(parent){ +Networking::Networking(QWidget* parent, bool show_advanced) : QWidget(parent){ try { wifi = new WifiManager(this); } catch (std::exception &e) { @@ -56,25 +56,20 @@ Networking::Networking(QWidget* parent) : QWidget(parent){ return; } connect(wifi, SIGNAL(wrongPassword(QString)), this, SLOT(wrongPassword(QString))); - connect(wifi, SIGNAL(successfulConnection(QString)), this, SLOT(successfulConnection(QString))); - s = new QStackedLayout; - inputField = new InputField(this, 8); - connect(inputField, SIGNAL(emitText(QString)), this, SLOT(receiveText(QString))); - connect(inputField, SIGNAL(cancel()), this, SLOT(abortTextInput())); - inputField->setContentsMargins(100,0,100,0); - s->addWidget(inputField); - QVBoxLayout* vlayout = new QVBoxLayout; - QPushButton* advancedSettings = new QPushButton("Advanced"); - advancedSettings->setStyleSheet(R"(margin-right: 30px)"); - advancedSettings->setFixedSize(300, 100); - connect(advancedSettings, &QPushButton::released, [=](){s->setCurrentIndex(2);}); - vlayout->addSpacing(10); - vlayout->addWidget(advancedSettings, 0, Qt::AlignRight); - vlayout->addSpacing(10); + + if (show_advanced) { + QPushButton* advancedSettings = new QPushButton("Advanced"); + advancedSettings->setStyleSheet(R"(margin-right: 30px)"); + advancedSettings->setFixedSize(300, 100); + connect(advancedSettings, &QPushButton::released, [=](){s->setCurrentIndex(1);}); + vlayout->addSpacing(10); + vlayout->addWidget(advancedSettings, 0, Qt::AlignRight); + vlayout->addSpacing(10); + } wifiWidget = new WifiUI(0, 5, wifi); connect(wifiWidget, SIGNAL(connectToNetwork(Network)), this, SLOT(connectToNetwork(Network))); @@ -83,13 +78,9 @@ Networking::Networking(QWidget* parent) : QWidget(parent){ s->addWidget(layoutToWidget(vlayout, this)); an = new AdvancedNetworking(this, wifi); - connect(an, &AdvancedNetworking::backPress, [=](){s->setCurrentIndex(1);}); - connect(an, &AdvancedNetworking::openKeyboard, [=](){emit openKeyboard();}); - connect(an, &AdvancedNetworking::closeKeyboard, [=](){emit closeKeyboard();}); + connect(an, &AdvancedNetworking::backPress, [=](){s->setCurrentIndex(0);}); s->addWidget(an); - s->setCurrentIndex(1); - // Update network status QTimer* timer = new QTimer(this); QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh())); @@ -100,7 +91,8 @@ Networking::Networking(QWidget* parent) : QWidget(parent){ font-size: 50px; margin: 0px; padding: 15px; - border-radius: 25px; + border-width: 0; + border-radius: 7px; color: #dddddd; background-color: #444444; } @@ -124,39 +116,14 @@ void Networking::connectToNetwork(Network n) { if (n.security_type == SecurityType::OPEN) { wifi->connect(n); } else if (n.security_type == SecurityType::WPA) { - inputField->setPromptText("Enter password for \"" + n.ssid + "\""); - s->setCurrentIndex(0); - selectedNetwork = n; - emit openKeyboard(); + QString pass = InputDialog::getText("Enter password for \"" + n.ssid + "\""); + wifi->connect(n, pass); } } -void Networking::abortTextInput(){ - s->setCurrentIndex(1); - emit closeKeyboard(); -} - -void Networking::receiveText(QString text) { - wifi->disconnect(); - wifi->connect(selectedNetwork, text); - s->setCurrentIndex(1); - emit closeKeyboard(); -} - void Networking::wrongPassword(QString ssid) { - if(s->currentIndex()==0){ - qDebug()<<"Wrong password, but we are already trying a new network"; - return; - } - if(s->currentIndex()==2){ - qDebug()<<"Wrong password, but we are in advanced settings"; - return; - } - if(!this->isVisible()){ - qDebug()<<"Wrong password, but we are not visible"; - return; - - } + return; // TODO: add this back + /* for (Network n : wifi->seen_networks) { if (n.ssid == ssid) { inputField->setPromptText("Wrong password for \"" + n.ssid +"\""); @@ -165,20 +132,7 @@ void Networking::wrongPassword(QString ssid) { return; } } -} - -void Networking::successfulConnection(QString ssid) { - //Maybe we will want to do something here in the future. -} - -void Networking::sidebarChange(){ - if (s == nullptr || an == nullptr){ - return; - } - - s->setCurrentIndex(1); - an->s->setCurrentIndex(1); - refresh(); + */ } QFrame* hline(QWidget* parent = 0){ @@ -192,24 +146,19 @@ QFrame* hline(QWidget* parent = 0){ // AdvancedNetworking functions AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWidget(parent), wifi(wifi){ - s = new QStackedLayout;// inputField, mainPage, SSH settings - inputField = new InputField(this, 8); - connect(inputField, SIGNAL(emitText(QString)), this, SLOT(receiveText(QString))); - connect(inputField, SIGNAL(cancel()), this, SLOT(abortTextInput())); - inputField->setContentsMargins(100,0,100,0); - s->addWidget(inputField); + s = new QStackedLayout; // mainPage, SSH settings QVBoxLayout* vlayout = new QVBoxLayout; - //Back button + // Back button QHBoxLayout* backLayout = new QHBoxLayout; - QPushButton* back = new QPushButton("BACK"); + QPushButton* back = new QPushButton("Back"); back->setFixedSize(500, 100); connect(back, &QPushButton::released, [=](){emit backPress();}); backLayout->addWidget(back, 0, Qt::AlignLeft); vlayout->addWidget(layoutToWidget(backLayout, this), 0, Qt::AlignLeft); - //Enable tethering layout + // Enable tethering layout QHBoxLayout* tetheringToggleLayout = new QHBoxLayout; tetheringToggleLayout->addWidget(new QLabel("Enable tethering")); Toggle* toggle_switch = new Toggle; @@ -223,17 +172,22 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid vlayout->addWidget(layoutToWidget(tetheringToggleLayout, this), 0); vlayout->addWidget(hline(), 0); - //Change tethering password + // Change tethering password QHBoxLayout *tetheringPassword = new QHBoxLayout; tetheringPassword->addWidget(new QLabel("Edit tethering password"), 1); editPasswordButton = new QPushButton("EDIT"); editPasswordButton->setFixedWidth(500); - connect(editPasswordButton, &QPushButton::released, [=](){inputField->setPromptText("Enter the new hotspot password"); s->setCurrentIndex(0); emit openKeyboard();}); + connect(editPasswordButton, &QPushButton::released, [=](){ + QString pass = InputDialog::getText("Enter new tethering password"); + if (pass.size()) { + wifi->changeTetheringPassword(pass); + } + }); tetheringPassword->addWidget(editPasswordButton, 1, Qt::AlignRight); vlayout->addWidget(layoutToWidget(tetheringPassword, this), 0); vlayout->addWidget(hline(), 0); - //IP adress + // IP adress QHBoxLayout* IPlayout = new QHBoxLayout; IPlayout->addWidget(new QLabel("IP address"), 0); ipLabel = new QLabel(wifi->ipv4_address); @@ -242,7 +196,7 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid vlayout->addWidget(layoutToWidget(IPlayout, this), 0); vlayout->addWidget(hline(), 0); - //Enable SSH + // Enable SSH QHBoxLayout* enableSSHLayout = new QHBoxLayout(this); enableSSHLayout->addWidget(new QLabel("Enable SSH", this)); toggle_switch_SSH = new Toggle(this); @@ -255,12 +209,12 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid vlayout->addWidget(layoutToWidget(enableSSHLayout, this)); vlayout->addWidget(hline(), 0); - //Authorized SSH keys + // SSH keys QHBoxLayout* authSSHLayout = new QHBoxLayout(this); - authSSHLayout->addWidget(new QLabel("Authorized SSH keys", this)); + authSSHLayout->addWidget(new QLabel("SSH keys", this)); QPushButton* editAuthSSHButton = new QPushButton("EDIT", this); editAuthSSHButton->setFixedWidth(500); - connect(editAuthSSHButton, &QPushButton::released, [=](){s->setCurrentIndex(2);}); + connect(editAuthSSHButton, &QPushButton::released, [=](){s->setCurrentWidget(ssh);}); authSSHLayout->addWidget(editAuthSSHButton); vlayout->addWidget(layoutToWidget(authSSHLayout, this)); vlayout->addSpacing(50); @@ -273,14 +227,13 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid // dangerZone->addWidget(deleteAll); // vlayout->addWidget(layoutToWidget(dangerZone, this)); - //vlayout to widget + // vlayout to widget QWidget* settingsWidget = layoutToWidget(vlayout, this); settingsWidget->setStyleSheet("margin-left: 40px; margin-right: 40px;"); s->addWidget(settingsWidget); - s->setCurrentIndex(1); ssh = new SSH; - connect(ssh, &SSH::closeSSHSettings, [=](){s->setCurrentIndex(1);}); + connect(ssh, &SSH::closeSSHSettings, [=](){s->setCurrentIndex(0);}); s->addWidget(ssh); setLayout(s); @@ -300,7 +253,7 @@ void AdvancedNetworking::refresh(){ if (toggle_switch_SSH->on != isSSHEnabled()) { toggle_switch_SSH->togglePosition(); } - //Qt can be lazy + // Qt can be lazy repaint(); } @@ -334,16 +287,6 @@ void AdvancedNetworking::toggleSSH(int enable) { } } -void AdvancedNetworking::receiveText(QString text){ - wifi->changeTetheringPassword(text); - s->setCurrentIndex(1); - emit closeKeyboard(); -} - -void AdvancedNetworking::abortTextInput(){ - s->setCurrentIndex(1); - emit closeKeyboard(); -} // WifiUI functions @@ -370,7 +313,6 @@ void WifiUI::refresh() { int i = 0; int countWidgets = 0; - int button_height = static_cast(this->height() / (networks_per_page + 1) * 0.6); for (Network &network : wifi->seen_networks) { QHBoxLayout *hlayout = new QHBoxLayout; if (page * networks_per_page <= i && i < (page + 1) * networks_per_page) { @@ -380,30 +322,30 @@ void WifiUI::refresh() { if(ssid.length() > 30){ ssid = ssid.left(30)+"…"; } - hlayout->addWidget(new QLabel(ssid)); + QLabel *ssid_label = new QLabel(ssid); + ssid_label->setStyleSheet(R"( + font-size: 55px; + )"); + hlayout->addWidget(ssid_label); + // TODO: don't use images for this // strength indicator unsigned int strength_scale = network.strength / 17; QPixmap pix("../assets/images/network_" + QString::number(strength_scale) + ".png"); QLabel *icon = new QLabel(); icon->setPixmap(pix.scaledToWidth(100, Qt::SmoothTransformation)); icon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - hlayout->addWidget(icon); - hlayout->addSpacing(20); + hlayout->addWidget(icon, 0, Qt::AlignRight); // connect button QPushButton* btn = new QPushButton(network.security_type == SecurityType::UNSUPPORTED ? "Unsupported" : (network.connected == ConnectedType::CONNECTED ? "Connected" : (network.connected == ConnectedType::CONNECTING ? "Connecting" : "Connect"))); - btn->setFixedWidth(400); - btn->setFixedHeight(button_height); btn->setDisabled(network.connected == ConnectedType::CONNECTED || network.connected == ConnectedType::CONNECTING || network.security_type == SecurityType::UNSUPPORTED); - hlayout->addWidget(btn); - hlayout->addSpacing(20); + btn->setFixedWidth(350); + hlayout->addWidget(btn, 0, Qt::AlignRight); connectButtons->addButton(btn, i); - QWidget * w = new QWidget; - w->setLayout(hlayout); - vlayout->addWidget(w, 1); + vlayout->addLayout(hlayout, 1); // Don't add the last horizontal line if (page * networks_per_page <= i+1 && i+1 < (page + 1) * networks_per_page && i+1 < wifi->seen_networks.size()) { vlayout->addWidget(hline(), 0); @@ -412,34 +354,23 @@ void WifiUI::refresh() { } i++; } + vlayout->addStretch(3); - // Pad vlayout to prevert oversized network widgets in case of low visible network count - for (int i = countWidgets; i < networks_per_page; i++) { - QWidget *w = new QWidget; - // That we need to add w twice was determined empiricaly - vlayout->addWidget(w, 1); - vlayout->addWidget(w, 1); - } - QHBoxLayout *prev_next_buttons = new QHBoxLayout;//Adding constructor exposes the qt bug + // Setup buttons for pagination + QHBoxLayout *prev_next_buttons = new QHBoxLayout; + QPushButton* prev = new QPushButton("Previous"); prev->setEnabled(page); - prev->setFixedSize(400, button_height); + QObject::connect(prev, SIGNAL(released()), this, SLOT(prevPage())); + prev_next_buttons->addWidget(prev); QPushButton* next = new QPushButton("Next"); - next->setFixedSize(400, button_height); - - // If there are more visible networks then we can show, enable going to next page next->setEnabled(wifi->seen_networks.size() > (page + 1) * networks_per_page); - - QObject::connect(prev, SIGNAL(released()), this, SLOT(prevPage())); QObject::connect(next, SIGNAL(released()), this, SLOT(nextPage())); - prev_next_buttons->addWidget(prev); prev_next_buttons->addWidget(next); - QWidget *w = new QWidget; - w->setLayout(prev_next_buttons); - vlayout->addWidget(w, 1, Qt::AlignBottom); + vlayout->addLayout(prev_next_buttons, 2); } void WifiUI::handleButton(QAbstractButton* button) { @@ -452,6 +383,7 @@ void WifiUI::prevPage() { page--; refresh(); } + void WifiUI::nextPage() { page++; refresh(); diff --git a/selfdrive/ui/qt/offroad/networking.hpp b/selfdrive/ui/qt/offroad/networking.hpp index 8143fa05fa..b2df3c5bd8 100644 --- a/selfdrive/ui/qt/offroad/networking.hpp +++ b/selfdrive/ui/qt/offroad/networking.hpp @@ -47,7 +47,6 @@ public: QStackedLayout* s; private: - InputField* inputField; QLabel* ipLabel; QPushButton* editPasswordButton; SSH* ssh; @@ -56,14 +55,11 @@ private: WifiManager* wifi = nullptr; bool isSSHEnabled(); + signals: - void openKeyboard(); - void closeKeyboard(); void backPress(); public slots: - void receiveText(QString text); - void abortTextInput(); void toggleTethering(int enable); void toggleSSH(int enable); void refresh(); @@ -73,29 +69,20 @@ class Networking : public QWidget { Q_OBJECT public: - explicit Networking(QWidget* parent = 0); + explicit Networking(QWidget* parent = 0, bool show_advanced = true); private: - QStackedLayout* s = nullptr;// keyboard, wifiScreen, advanced + QStackedLayout* s = nullptr; // keyboard, wifiScreen, advanced AdvancedNetworking* an = nullptr; Network selectedNetwork; WifiUI* wifiWidget; WifiManager* wifi = nullptr; - InputField* inputField; - -signals: - void openKeyboard(); - void closeKeyboard(); private slots: void connectToNetwork(Network n); void refresh(); - void receiveText(QString text); - void abortTextInput(); void wrongPassword(QString ssid); - void successfulConnection(QString ssid); - void sidebarChange(); }; diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 1731fad79b..49b22e1c9d 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -225,9 +225,6 @@ QWidget * developer_panel() { QWidget * network_panel(QWidget * parent) { Networking *w = new Networking(parent); - QObject::connect(parent, SIGNAL(sidebarPressed()), w, SLOT(sidebarChange())); - QObject::connect(w, SIGNAL(openKeyboard()), parent, SLOT(closeSidebar())); - QObject::connect(w, SIGNAL(closeKeyboard()), parent, SLOT(openSidebar())); return w; } @@ -276,7 +273,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { border: none; background: none; font-size: 65px; - font-weight: 600; + font-weight: 500; padding-top: 35px; padding-bottom: 35px; } @@ -327,11 +324,3 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { } )"); } - -void SettingsWindow::closeSidebar() { - sidebar_widget->setFixedWidth(0); -} - -void SettingsWindow::openSidebar() { - sidebar_widget->setFixedWidth(500); -} diff --git a/selfdrive/ui/qt/offroad/settings.hpp b/selfdrive/ui/qt/offroad/settings.hpp index 561c9c966c..e10a2652ca 100644 --- a/selfdrive/ui/qt/offroad/settings.hpp +++ b/selfdrive/ui/qt/offroad/settings.hpp @@ -48,6 +48,4 @@ private: public slots: void setActivePanel(); - void closeSidebar(); - void openSidebar(); }; diff --git a/selfdrive/ui/qt/qt_window.cc b/selfdrive/ui/qt/qt_window.cc deleted file mode 100644 index b394b44c04..0000000000 --- a/selfdrive/ui/qt/qt_window.cc +++ /dev/null @@ -1,28 +0,0 @@ -#include - -#include -#include - -#ifdef QCOM2 -#include -#include -#include -#endif - -#include "qt_window.hpp" - -void setMainWindow(QWidget *w) { - float scale = getenv("SCALE") != NULL ? std::stof(getenv("SCALE")) : 1.0; - w->setFixedSize(vwp_w*scale, vwp_h*scale); - w->show(); - -#ifdef QCOM2 - QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface(); - wl_surface *s = reinterpret_cast(native->nativeResourceForWindow("surface", w->windowHandle())); - wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270); - wl_surface_commit(s); - w->showFullScreen(); -#endif -} - - diff --git a/selfdrive/ui/qt/qt_window.hpp b/selfdrive/ui/qt/qt_window.hpp index a4485959bc..f7d36af8d7 100644 --- a/selfdrive/ui/qt/qt_window.hpp +++ b/selfdrive/ui/qt/qt_window.hpp @@ -1,4 +1,15 @@ +#include + #include +#include +#include + +#ifdef QCOM2 +#include +#include +#include +#endif + #ifdef QCOM2 const int vwp_w = 2160, vwp_h = 1080; @@ -6,4 +17,16 @@ const int vwp_w = 1920, vwp_h = 1080; #endif -void setMainWindow(QWidget *w); +inline void setMainWindow(QWidget *w) { + const float scale = getenv("SCALE") != NULL ? std::stof(getenv("SCALE")) : 1.0; + w->setFixedSize(vwp_w*scale, vwp_h*scale); + w->show(); + +#ifdef QCOM2 + QPlatformNativeInterface *native = QGuiApplication::platformNativeInterface(); + wl_surface *s = reinterpret_cast(native->nativeResourceForWindow("surface", w->windowHandle())); + wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270); + wl_surface_commit(s); + w->showFullScreen(); +#endif +} diff --git a/selfdrive/ui/qt/setup/installer.cc b/selfdrive/ui/qt/setup/installer.cc index abfde8491f..965a35af99 100644 --- a/selfdrive/ui/qt/setup/installer.cc +++ b/selfdrive/ui/qt/setup/installer.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include #ifndef BRANCH @@ -24,9 +25,7 @@ int fresh_clone() { int err; // Cleanup - err = std::system("rm -rf /tmp/openpilot"); - if (err) return 1; - err = std::system("rm -rf /data/openpilot"); + err = std::system("rm -rf /tmp/openpilot /data/openpilot"); if (err) return 1; // Clone @@ -40,14 +39,22 @@ int fresh_clone() { err = std::system("mv /tmp/openpilot /data"); if (err) return 1; +#ifdef SSH_KEYS + err = std::system("mkdir -p /data/params/d/"); + if (err) return 1; + + std::ofstream param; + param.open("/data/params/d/GithubSshKeys"); + param << SSH_KEYS; + param.close(); +#endif + return 0; } int install() { int err; - // TODO: Disable SSH after install done - // Wait for valid time while (!time_valid()) { usleep(500 * 1000); diff --git a/selfdrive/ui/qt/setup/setup.cc b/selfdrive/ui/qt/setup/setup.cc index bc144b1366..5afccb4272 100644 --- a/selfdrive/ui/qt/setup/setup.cc +++ b/selfdrive/ui/qt/setup/setup.cc @@ -7,19 +7,20 @@ #include #include "setup.hpp" -#include "offroad/wifi.hpp" +#include "offroad/networking.hpp" #include "widgets/input_field.hpp" #include "qt_window.hpp" #define USER_AGENT "AGNOSSetup-0.1" void Setup::download(QString url) { - setCurrentIndex(count() - 1); + setCurrentIndex(count() - 2); + QCoreApplication::processEvents(QEventLoop::AllEvents, 1000); - CURL *curl; - curl = curl_easy_init(); - // TODO: exit with return code - if (!curl) return; + CURL *curl = curl_easy_init(); + if (!curl) { + emit downloadFailed(); + } char tmpfile[] = "/tmp/installer_XXXXXX"; FILE *fp = fdopen(mkstemp(tmpfile), "w"); @@ -30,7 +31,11 @@ void Setup::download(QString url) { curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT); - curl_easy_perform(curl); + + int ret = curl_easy_perform(curl); + if (ret != CURLE_OK) { + emit downloadFailed(); + } curl_easy_cleanup(curl); fclose(fp); @@ -41,68 +46,55 @@ QLabel * title_label(QString text) { QLabel *l = new QLabel(text); l->setStyleSheet(R"( font-size: 100px; - font-weight: bold; + font-weight: 500; )"); return l; } -QWidget * Setup::getting_started() { +QWidget * Setup::build_page(QString title, QWidget *content, bool next, bool prev) { QVBoxLayout *main_layout = new QVBoxLayout(); - main_layout->setContentsMargins(200, 100, 200, 100); + main_layout->setContentsMargins(50, 50, 50, 50); + main_layout->addWidget(title_label(title), 0, Qt::AlignLeft | Qt::AlignTop); - main_layout->addWidget(title_label("Getting Started"), 0, Qt::AlignCenter); + main_layout->addWidget(content); - QLabel *body = new QLabel("Before we get on the road, let's finish\ninstallation and cover some details."); - body->setStyleSheet(R"(font-size: 65px;)"); - main_layout->addWidget(body, 0, Qt::AlignCenter); + QHBoxLayout *nav_layout = new QHBoxLayout(); + + QPushButton *back_btn = new QPushButton("Back"); + nav_layout->addWidget(back_btn, 0, Qt::AlignBottom | Qt::AlignLeft); + QObject::connect(back_btn, SIGNAL(released()), this, SLOT(prevPage())); + back_btn->setVisible(prev); - main_layout->addSpacing(100); + QPushButton *continue_btn = new QPushButton("Continue"); + nav_layout->addWidget(continue_btn, 0, Qt::AlignBottom | Qt::AlignRight); + QObject::connect(continue_btn, SIGNAL(released()), this, SLOT(nextPage())); + continue_btn->setVisible(next); - QPushButton *btn = new QPushButton("Continue"); - main_layout->addWidget(btn); - QObject::connect(btn, SIGNAL(released()), this, SLOT(nextPage())); + main_layout->addLayout(nav_layout, 0); QWidget *widget = new QWidget(); widget->setLayout(main_layout); return widget; } -QWidget * Setup::network_setup() { - - QVBoxLayout *main_layout = new QVBoxLayout(); - main_layout->setContentsMargins(50, 50, 50, 50); - - main_layout->addWidget(title_label("Connect to WiFi"), 0, Qt::AlignTop); - - WifiUI *wifi = new WifiUI(this, 6); - main_layout->addWidget(wifi); - QObject::connect(wifi, &WifiUI::openKeyboard, this, [=]() { - this->continue_btn->setVisible(false); - }); - QObject::connect(wifi, &WifiUI::closeKeyboard, this, [=]() { - this->continue_btn->setVisible(true); - }); - - continue_btn = new QPushButton("Continue"); - main_layout->addWidget(continue_btn); - QObject::connect(continue_btn, SIGNAL(released()), this, SLOT(nextPage())); +QWidget * Setup::getting_started() { + QLabel *body = new QLabel("Before we get on the road, let's finish\ninstallation and cover some details."); + body->setAlignment(Qt::AlignHCenter); + body->setStyleSheet(R"(font-size: 80px;)"); + return build_page("Getting Started", body, true, false); +} - QWidget *widget = new QWidget(); - widget->setLayout(main_layout); - return widget; +QWidget * Setup::network_setup() { + Networking *wifi = new Networking(this, false); + return build_page("Connect to WiFi", wifi, true, true); } QWidget * Setup::software_selection() { QVBoxLayout *main_layout = new QVBoxLayout(); - main_layout->setMargin(100); - - main_layout->addWidget(title_label("Choose Software"), 0, Qt::AlignCenter); - - main_layout->addSpacing(50); QPushButton *dashcam_btn = new QPushButton("Dashcam"); main_layout->addWidget(dashcam_btn); - QObject::connect(dashcam_btn, &QPushButton::released, this, [=]() { + QObject::connect(dashcam_btn, &QPushButton::released, this, [=]() { this->download("https://dashcam.comma.ai"); }); @@ -110,40 +102,55 @@ QWidget * Setup::software_selection() { QPushButton *custom_btn = new QPushButton("Custom"); main_layout->addWidget(custom_btn); - QObject::connect(custom_btn, SIGNAL(released()), this, SLOT(nextPage())); - - main_layout->addSpacing(100); - - QPushButton *prev_btn = new QPushButton("Back"); - main_layout->addWidget(prev_btn); - QObject::connect(prev_btn, SIGNAL(released()), this, SLOT(prevPage())); + QObject::connect(custom_btn, &QPushButton::released, this, [=]() { + QString input_url = InputDialog::getText("Enter URL"); + if (input_url.size()) { + this->download(input_url); + } + }); QWidget *widget = new QWidget(); widget->setLayout(main_layout); - return widget; + return build_page("Choose Software", widget, false, true); } -QWidget * Setup::custom_software() { +QWidget * Setup::downloading() { QVBoxLayout *main_layout = new QVBoxLayout(); - main_layout->setMargin(50); - - main_layout->addWidget(title_label("Custom Software"), Qt::AlignTop | Qt::AlignHCenter); - - InputField *input = new InputField(); - input->setPromptText("Enter URL"); - main_layout->addWidget(input); - - QObject::connect(input, SIGNAL(emitText(QString)), this, SLOT(download(QString))); + main_layout->addWidget(title_label("Downloading..."), 0, Qt::AlignCenter); QWidget *widget = new QWidget(); widget->setLayout(main_layout); return widget; } -QWidget * Setup::downloading() { +QWidget * Setup::download_failed() { QVBoxLayout *main_layout = new QVBoxLayout(); + main_layout->setContentsMargins(50, 50, 50, 50); + main_layout->addWidget(title_label("Download Failed"), 0, Qt::AlignLeft | Qt::AlignTop); + + QLabel *body = new QLabel("Ensure the entered URL is valid, and the device's network connection is good."); + body->setWordWrap(true); + body->setAlignment(Qt::AlignHCenter); + body->setStyleSheet(R"(font-size: 80px;)"); + main_layout->addWidget(body); + + QHBoxLayout *nav_layout = new QHBoxLayout(); + + QPushButton *reboot_btn = new QPushButton("Reboot"); + nav_layout->addWidget(reboot_btn, 0, Qt::AlignBottom | Qt::AlignLeft); + QObject::connect(reboot_btn, &QPushButton::released, this, [=]() { +#ifdef QCOM2 + std::system("sudo reboot"); +#endif + }); - main_layout->addWidget(title_label("Downloading..."), 0, Qt::AlignCenter); + QPushButton *restart_btn = new QPushButton("Start over"); + nav_layout->addWidget(restart_btn, 0, Qt::AlignBottom | Qt::AlignRight); + QObject::connect(restart_btn, &QPushButton::released, this, [=]() { + setCurrentIndex(0); + }); + + main_layout->addLayout(nav_layout, 0); QWidget *widget = new QWidget(); widget->setLayout(main_layout); @@ -162,23 +169,24 @@ Setup::Setup(QWidget *parent) { addWidget(getting_started()); addWidget(network_setup()); addWidget(software_selection()); - addWidget(custom_software()); addWidget(downloading()); + addWidget(download_failed()); + + QObject::connect(this, SIGNAL(downloadFailed()), this, SLOT(nextPage())); setStyleSheet(R"( * { font-family: Inter; - } - QWidget { color: white; background-color: black; } QPushButton { - font-size: 60px; - padding: 60px; - width: 800px; - color: white; - background-color: blue; + padding: 50px; + padding-right: 100px; + padding-left: 100px; + border: 7px solid white; + border-radius: 20px; + font-size: 50px; } )"); } diff --git a/selfdrive/ui/qt/setup/setup.hpp b/selfdrive/ui/qt/setup/setup.hpp index 9e5f876172..7ae3dda1b4 100644 --- a/selfdrive/ui/qt/setup/setup.hpp +++ b/selfdrive/ui/qt/setup/setup.hpp @@ -11,14 +11,17 @@ public: explicit Setup(QWidget *parent = 0); private: - QLineEdit *url_input; - QPushButton *continue_btn; - QWidget *getting_started(); QWidget *network_setup(); QWidget *software_selection(); QWidget *custom_software(); QWidget *downloading(); + QWidget *download_failed(); + + QWidget *build_page(QString title, QWidget *content, bool next, bool prev); + +signals: + void downloadFailed(); public slots: void nextPage(); diff --git a/selfdrive/ui/qt/widgets/input_field.cc b/selfdrive/ui/qt/widgets/input_field.cc index d3547eef63..f1f48a4662 100644 --- a/selfdrive/ui/qt/widgets/input_field.cc +++ b/selfdrive/ui/qt/widgets/input_field.cc @@ -1,61 +1,86 @@ #include #include "input_field.hpp" +#include "qt_window.hpp" -InputField::InputField(QWidget *parent, int minTextLength): QWidget(parent), minTextLength(minTextLength) { - layout = new QGridLayout(); - layout->setSpacing(30); +InputDialog::InputDialog(QString prompt_text, QWidget *parent): QDialog(parent) { + layout = new QVBoxLayout(); + layout->setContentsMargins(50, 50, 50, 50); + layout->setSpacing(20); - label = new QLabel(this); - label->setStyleSheet(R"(font-size: 70px; font-weight: 500;)"); - layout->addWidget(label, 0, 0,Qt::AlignLeft); - layout->setColumnStretch(0, 1); + // build header + QHBoxLayout *header_layout = new QHBoxLayout(); - QPushButton* cancel = new QPushButton("Cancel"); - cancel->setFixedSize(300, 150); - cancel->setStyleSheet(R"(padding: 0;)"); - layout->addWidget(cancel, 0, 1, Qt::AlignRight); - QObject::connect(cancel, SIGNAL(released()), this, SLOT(emitEmpty())); + label = new QLabel(prompt_text, this); + label->setStyleSheet(R"(font-size: 75px; font-weight: 500;)"); + header_layout->addWidget(label, 1, Qt::AlignLeft); + + QPushButton* cancel_btn = new QPushButton("Cancel"); + cancel_btn->setStyleSheet(R"( + padding: 30px; + padding-right: 45px; + padding-left: 45px; + border-radius: 7px; + font-size: 45px; + background-color: #444444; + )"); + header_layout->addWidget(cancel_btn, 0, Qt::AlignRight); + QObject::connect(cancel_btn, SIGNAL(released()), this, SLOT(reject())); + + layout->addLayout(header_layout); // text box + layout->addSpacing(20); line = new QLineEdit(); line->setStyleSheet(R"( - color: white; + border: none; background-color: #444444; font-size: 80px; font-weight: 500; padding: 10px; )"); - layout->addWidget(line, 1, 0, 1, -1); + layout->addWidget(line, 1, Qt::AlignTop); k = new Keyboard(this); - QObject::connect(k, SIGNAL(emitButton(QString)), this, SLOT(getText(QString))); - layout->addWidget(k, 2, 0, 1, -1); + QObject::connect(k, SIGNAL(emitButton(QString)), this, SLOT(handleInput(QString))); + layout->addWidget(k, 2, Qt::AlignBottom); + + setStyleSheet(R"( + * { + color: white; + background-color: black; + } + )"); setLayout(layout); } -void InputField::setPromptText(QString text) { - label->setText(text); +QString InputDialog::getText(const QString prompt) { + InputDialog d = InputDialog(prompt); + const int ret = d.exec(); + if (ret) { + return d.text(); + } else { + return QString(); + } +} + +QString InputDialog::text() { + return line->text(); } -void InputField::emitEmpty() { - line->setText(""); - emit cancel(); +int InputDialog::exec() { + setMainWindow(this); + return QDialog::exec(); } -void InputField::getText(QString s) { +void InputDialog::handleInput(QString s) { if (!QString::compare(s,"⌫")) { line->backspace(); } if (!QString::compare(s,"⏎")) { - if(line->text().length()text()); - line->setText(""); + done(QDialog::Accepted); } QVector control_buttons {"⇧", "↑", "ABC", "⏎", "#+=", "⌫", "123"}; diff --git a/selfdrive/ui/qt/widgets/input_field.hpp b/selfdrive/ui/qt/widgets/input_field.hpp index 6f2c69a578..5543eff39d 100644 --- a/selfdrive/ui/qt/widgets/input_field.hpp +++ b/selfdrive/ui/qt/widgets/input_field.hpp @@ -3,30 +3,29 @@ #include #include #include +#include #include -#include +#include #include "keyboard.hpp" -class InputField : public QWidget { +class InputDialog : public QDialog { Q_OBJECT public: - explicit InputField(QWidget* parent = 0, int minTextLength = 0); - void setPromptText(QString text); - int minTextLength; + explicit InputDialog(QString prompt_text, QWidget* parent = 0); + static QString getText(QString prompt); + QString text(); private: QLineEdit *line; Keyboard *k; QLabel *label; - QGridLayout *layout; + QVBoxLayout *layout; public slots: - void getText(QString s); - void emitEmpty(); + int exec() override; -signals: - void cancel(); - void emitText(QString s); +private slots: + void handleInput(QString s); }; diff --git a/selfdrive/ui/qt/widgets/keyboard.cc b/selfdrive/ui/qt/widgets/keyboard.cc index 7be45945e6..a00395c22b 100644 --- a/selfdrive/ui/qt/widgets/keyboard.cc +++ b/selfdrive/ui/qt/widgets/keyboard.cc @@ -7,20 +7,22 @@ #include "keyboard.hpp" -const int DEFAULT_WIDTH = 1; -const int SPACEBAR_WIDTH = 3; +const int DEFAULT_STRETCH = 1; +const int SPACEBAR_STRETCH = 3; KeyboardLayout::KeyboardLayout(QWidget *parent, std::vector> layout) : QWidget(parent) { QVBoxLayout* vlayout = new QVBoxLayout; - QButtonGroup* btn_group = new QButtonGroup(this); + vlayout->setMargin(0); + vlayout->setSpacing(15); + QButtonGroup* btn_group = new QButtonGroup(this); QObject::connect(btn_group, SIGNAL(buttonClicked(QAbstractButton*)), parent, SLOT(handleButton(QAbstractButton*))); - int i = 0; for (const auto &s : layout) { QHBoxLayout *hlayout = new QHBoxLayout; + hlayout->setSpacing(30); - if (i == 1) { + if (vlayout->count() == 1) { hlayout->addSpacing(90); } @@ -28,28 +30,32 @@ KeyboardLayout::KeyboardLayout(QWidget *parent, std::vector> la QPushButton* btn = new QPushButton(p); btn->setFixedHeight(120); btn_group->addButton(btn); - hlayout->addSpacing(30); - if (p == QString(" ")) { - hlayout->addWidget(btn, SPACEBAR_WIDTH); - } else { - hlayout->addWidget(btn, DEFAULT_WIDTH); - } - + hlayout->addWidget(btn, p == QString(" ") ? SPACEBAR_STRETCH : DEFAULT_STRETCH); } - if (i == 1) { + if (vlayout->count() == 1) { hlayout->addSpacing(90); } vlayout->addLayout(hlayout); - i++; } + setStyleSheet(R"( + QPushButton { + font-size: 65px; + margin: 0px; + padding: 0px; + border-radius: 7px; + color: #dddddd; + background-color: #444444; + } + )"); setLayout(vlayout); } -Keyboard::Keyboard(QWidget *parent) : QWidget(parent) { +Keyboard::Keyboard(QWidget *parent) : QFrame(parent) { main_layout = new QStackedLayout; + main_layout->setMargin(0); // lowercase std::vector> lowercase = { @@ -69,7 +75,7 @@ Keyboard::Keyboard(QWidget *parent) : QWidget(parent) { }; main_layout->addWidget(new KeyboardLayout(this, uppercase)); - // 1234567890 + // numbers + specials std::vector> numbers = { {"1","2","3","4","5","6","7","8","9","0"}, {"-","/",":",";","(",")","$","&&","@","\""}, @@ -78,7 +84,7 @@ Keyboard::Keyboard(QWidget *parent) : QWidget(parent) { }; main_layout->addWidget(new KeyboardLayout(this, numbers)); - // Special characters + // extra specials std::vector> specials = { {"[","]","{","}","#","%","^","*","+","="}, {"_","\\","|","~","<",">","€","£","¥","•"}, @@ -89,19 +95,8 @@ Keyboard::Keyboard(QWidget *parent) : QWidget(parent) { setLayout(main_layout); main_layout->setCurrentIndex(0); - - setStyleSheet(R"( - QPushButton { - padding: 0; - font-size: 50px; - } - * { - background-color: #99777777; - } - )"); } - void Keyboard::handleButton(QAbstractButton* m_button) { QString id = m_button->text(); if (!QString::compare(m_button->text(), "↑") || !QString::compare(m_button->text(), "ABC")) { diff --git a/selfdrive/ui/qt/widgets/keyboard.hpp b/selfdrive/ui/qt/widgets/keyboard.hpp index f21d48700c..2204973f71 100644 --- a/selfdrive/ui/qt/widgets/keyboard.hpp +++ b/selfdrive/ui/qt/widgets/keyboard.hpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -14,7 +15,7 @@ public: explicit KeyboardLayout(QWidget *parent, std::vector> layout); }; -class Keyboard : public QWidget { +class Keyboard : public QFrame { Q_OBJECT public: diff --git a/selfdrive/ui/qt/widgets/ssh_keys.cc b/selfdrive/ui/qt/widgets/ssh_keys.cc index f4b58d645f..64c1a67b02 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.cc +++ b/selfdrive/ui/qt/widgets/ssh_keys.cc @@ -1,20 +1,12 @@ -#include -#include #include #include #include #include #include +#include "common/params.h" #include "widgets/ssh_keys.hpp" #include "widgets/input_field.hpp" -#include "common/params.h" - -QWidget* layout_to_widget(QLayout* l){ - QWidget* q = new QWidget; - q->setLayout(l); - return q; -} SSH::SSH(QWidget* parent) : QWidget(parent){ // init variables @@ -24,40 +16,25 @@ SSH::SSH(QWidget* parent) : QWidget(parent){ networkTimer->setInterval(5000); connect(networkTimer, SIGNAL(timeout()), this, SLOT(timeout())); + // Layout on entering + QVBoxLayout* main_layout = new QVBoxLayout; + main_layout->setMargin(50); - // Construct the layouts to display - slayout = new QStackedLayout(this); // Initial screen, input, waiting for response - - //Layout on entering - QVBoxLayout* initialLayout = new QVBoxLayout; - initialLayout->setContentsMargins(80, 80, 80, 80); - - QHBoxLayout* header = new QHBoxLayout; QPushButton* exitButton = new QPushButton("BACK", this); exitButton->setFixedSize(500, 100); - header->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop); - initialLayout->addWidget(layout_to_widget(header)); + main_layout->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop); + connect(exitButton, SIGNAL(released()), this, SIGNAL(closeSSHSettings())); - QLabel* title = new QLabel("Authorize SSH keys"); - title->setStyleSheet(R"(font-size: 75px;)"); - header->addWidget(title, 0, Qt::AlignRight | Qt::AlignTop); - - QLabel* wallOfText = new QLabel("Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A Comma employee will NEVER ask you to add their GitHub username."); + QLabel* wallOfText = new QLabel("Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own."); + wallOfText->setAlignment(Qt::AlignHCenter); wallOfText->setWordWrap(true); wallOfText->setStyleSheet(R"(font-size: 60px;)"); - initialLayout->addWidget(wallOfText, 0); + main_layout->addWidget(wallOfText, 0); QPushButton* actionButton = new QPushButton; actionButton->setFixedHeight(100); - initialLayout->addWidget(actionButton, 0, Qt::AlignBottom); - - slayout->addWidget(layout_to_widget(initialLayout)); + main_layout->addWidget(actionButton, 0, Qt::AlignBottom); - InputField* input = new InputField; - slayout->addWidget(input); - - QLabel* loading = new QLabel("Loading SSH keys from GitHub."); - slayout->addWidget(loading); setStyleSheet(R"( QPushButton { font-size: 60px; @@ -68,59 +45,61 @@ SSH::SSH(QWidget* parent) : QWidget(parent){ background-color: #444444; } )"); - setLayout(slayout); - + setLayout(main_layout); - //Initialize the state machine and states + // Initialize the state machine and states QStateMachine* state = new QStateMachine(this); QState* initialState = new QState(); //State when entering the widget QState* initialStateNoGithub = new QState(); //Starting state, key not connected QState* initialStateConnected = new QState(); //Starting state, ssh connected - QState* quitState = new QState(); // State when exiting the widget - QState* removeSSH_State = new QState(); // State when user wants to remove the SSH keys - QState* defaultInputFieldState = new QState(); // State when we want the user to give us the username + QState* removeSSH_State = new QState(); // State when user wants to remove the SSH keys QState* loadingState = new QState(); // State while waiting for the network response - // Adding states to the state machine and adding the transitions state->addState(initialState); - connect(initialState, &QState::entered, [=](){checkForSSHKey(); slayout->setCurrentIndex(0);}); + connect(initialState, &QState::entered, [=](){ + checkForSSHKey(); + }); initialState->addTransition(this, &SSH::NoSSHAdded, initialStateNoGithub); initialState->addTransition(this, &SSH::SSHAdded, initialStateConnected); - - - state->addState(quitState); - connect(quitState, &QState::entered, [=](){emit closeSSHSettings();}); - quitState->addTransition(quitState, &QState::entered, initialState); state->addState(initialStateConnected); - connect(initialStateConnected, &QState::entered, [=](){actionButton->setText("Remove GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #750c0c;)");}); - initialStateConnected->addTransition(exitButton, &QPushButton::released, quitState); + connect(initialStateConnected, &QState::entered, [=](){ + actionButton->setText("Clear SSH keys"); + actionButton->setStyleSheet(R"(background-color: #750c0c;)"); + }); initialStateConnected->addTransition(actionButton, &QPushButton::released, removeSSH_State); state->addState(removeSSH_State); - connect(removeSSH_State, &QState::entered, [=](){Params().delete_db_value("GithubSshKeys");}); + connect(removeSSH_State, &QState::entered, [=](){ + Params().delete_db_value("GithubSshKeys"); + }); removeSSH_State->addTransition(removeSSH_State, &QState::entered, initialState); state->addState(initialStateNoGithub); - connect(initialStateNoGithub, &QState::entered, [=](){actionButton->setText("Link GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #444444;)");}); - initialStateNoGithub->addTransition(exitButton, &QPushButton::released, quitState); - initialStateNoGithub->addTransition(actionButton, &QPushButton::released, defaultInputFieldState); - connect(actionButton, &QPushButton::released, [=](){input->setPromptText("Enter your GitHub username");}); - - state->addState(defaultInputFieldState); - connect(defaultInputFieldState, &QState::entered, [=](){slayout->setCurrentIndex(1);}); - connect(input, &InputField::emitText, [=](QString a){usernameGitHub = a;}); // Store the string the user provided - defaultInputFieldState->addTransition(input, &InputField::cancel, initialState); - defaultInputFieldState->addTransition(input, &InputField::emitText, loadingState); + connect(initialStateNoGithub, &QState::entered, [=](){ + actionButton->setText("Link GitHub SSH keys"); + actionButton->setStyleSheet(R"(background-color: #444444;)"); + }); + initialStateNoGithub->addTransition(actionButton, &QPushButton::released, loadingState); state->addState(loadingState); - connect(loadingState, &QState::entered, [=](){slayout->setCurrentIndex(2); getSSHKeys();}); - connect(this, &SSH::failedResponse, [=](QString message){input->setPromptText(message);}); - loadingState->addTransition(this, &SSH::failedResponse, defaultInputFieldState); + connect(loadingState, &QState::entered, [=](){ + QString user = InputDialog::getText("Enter your GitHub username"); + if (user.size()) { + getSSHKeys(user); + } + }); + connect(this, &SSH::failedResponse, [=](QString message){ + QString user = InputDialog::getText(message); + if (user.size()) { + getSSHKeys(user); + } + }); + loadingState->addTransition(loadingState, &QState::entered, initialState); + loadingState->addTransition(this, &SSH::failedResponse, initialState); loadingState->addTransition(this, &SSH::gotSSHKeys, initialState); - state->setInitialState(initialState); state->start(); } @@ -134,8 +113,8 @@ void SSH::checkForSSHKey(){ } } -void SSH::getSSHKeys(){ - QString url = "https://github.com/" + usernameGitHub + ".keys"; +void SSH::getSSHKeys(QString username){ + QString url = "https://github.com/" + username + ".keys"; aborted = false; reply = manager->get(QNetworkRequest(QUrl(url))); connect(reply, SIGNAL(finished()), this, SLOT(parseResponse())); @@ -155,9 +134,9 @@ void SSH::parseResponse(){ Params().write_db_value("GithubSshKeys", response.toStdString()); emit gotSSHKeys(); } else { - emit failedResponse("Username "+usernameGitHub+" doesn't exist"); + emit failedResponse("Username doesn't exist"); } - }else{ + } else { emit failedResponse("Request timed out"); } reply->deleteLater(); diff --git a/selfdrive/ui/qt/widgets/ssh_keys.hpp b/selfdrive/ui/qt/widgets/ssh_keys.hpp index 96d6a5d156..3082a43d6c 100644 --- a/selfdrive/ui/qt/widgets/ssh_keys.hpp +++ b/selfdrive/ui/qt/widgets/ssh_keys.hpp @@ -1,15 +1,9 @@ #pragma once -#include -#include -#include -#include -#include #include +#include #include -#include "widgets/input_field.hpp" - class SSH : public QWidget { Q_OBJECT @@ -17,27 +11,22 @@ public: explicit SSH(QWidget* parent = 0); private: - InputField* inputField; - QStackedLayout* slayout; - QString usernameGitHub; QNetworkAccessManager* manager; QNetworkReply* reply; QTimer* networkTimer; bool aborted; + void getSSHKeys(QString user); + signals: - void closeSSHSettings(); - void openKeyboard(); - void closeKeyboard(); void NoSSHAdded(); void SSHAdded(); void failedResponse(QString errorString); void gotSSHKeys(); + void closeSSHSettings(); private slots: void checkForSSHKey(); - void getSSHKeys(); void timeout(); void parseResponse(); }; -