Qt UI refactoring + improvements (#20033)

old-commit-hash: f9d8652cbd
commatwo_master
Adeeb Shihadeh 4 years ago committed by GitHub
parent 5bc05ad36b
commit 80c3d67a28
  1. 18
      selfdrive/ui/SConscript
  2. 154
      selfdrive/ui/qt/offroad/networking.cc
  3. 17
      selfdrive/ui/qt/offroad/networking.hpp
  4. 13
      selfdrive/ui/qt/offroad/settings.cc
  5. 2
      selfdrive/ui/qt/offroad/settings.hpp
  6. 28
      selfdrive/ui/qt/qt_window.cc
  7. 25
      selfdrive/ui/qt/qt_window.hpp
  8. 17
      selfdrive/ui/qt/setup/installer.cc
  9. 154
      selfdrive/ui/qt/setup/setup.cc
  10. 9
      selfdrive/ui/qt/setup/setup.hpp
  11. 81
      selfdrive/ui/qt/widgets/input_field.cc
  12. 21
      selfdrive/ui/qt/widgets/input_field.hpp
  13. 51
      selfdrive/ui/qt/widgets/keyboard.cc
  14. 3
      selfdrive/ui/qt/widgets/keyboard.hpp
  15. 105
      selfdrive/ui/qt/widgets/ssh_keys.cc
  16. 19
      selfdrive/ui/qt/widgets/ssh_keys.hpp

@ -18,7 +18,7 @@ else:
qt_libs = qt_env["LIBS"] + libs + ["pthread", "ssl", "crypto"] qt_libs = qt_env["LIBS"] + libs + ["pthread", "ssl", "crypto"]
widgets = qt_env.Library("qt_widgets", 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"], "qt/offroad/networking.cc", "qt/offroad/wifiManager.cc", "qt/widgets/toggle.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/setup.cc"],
LIBS=qt_libs) LIBS=qt_libs)
qt_libs.append(widgets) qt_libs.append(widgets)
@ -43,10 +43,16 @@ else:
installers = [ installers = [
("openpilot", "master"), ("openpilot", "master"),
("openpilot_test", "master"), #("openpilot_test", "release3-staging"),
#("dashcam", "dashcam"), #("openpilot_internal", "master"),
#("dashcam_test", "dashcam"), #("dashcam", "dashcam3-staging"),
#("dashcam_test", "dashcam3-staging"),
] ]
for name, branch in installers: for name, branch in installers:
flags = qt_env["CXXFLAGS"] + [f"-D{branch}"] d = {'BRANCH': f"'\"{branch}\"'"}
qt_env.Program(f"qt/setup/installer_{name}", ["qt/setup/installer.cc"], LIBS=qt_libs) 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)

@ -43,7 +43,7 @@ std::string exec(const char* cmd) {
// Networking functions // Networking functions
Networking::Networking(QWidget* parent) : QWidget(parent){ Networking::Networking(QWidget* parent, bool show_advanced) : QWidget(parent){
try { try {
wifi = new WifiManager(this); wifi = new WifiManager(this);
} catch (std::exception &e) { } catch (std::exception &e) {
@ -56,25 +56,20 @@ Networking::Networking(QWidget* parent) : QWidget(parent){
return; return;
} }
connect(wifi, SIGNAL(wrongPassword(QString)), this, SLOT(wrongPassword(QString))); connect(wifi, SIGNAL(wrongPassword(QString)), this, SLOT(wrongPassword(QString)));
connect(wifi, SIGNAL(successfulConnection(QString)), this, SLOT(successfulConnection(QString)));
s = new QStackedLayout; 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; QVBoxLayout* vlayout = new QVBoxLayout;
if (show_advanced) {
QPushButton* advancedSettings = new QPushButton("Advanced"); QPushButton* advancedSettings = new QPushButton("Advanced");
advancedSettings->setStyleSheet(R"(margin-right: 30px)"); advancedSettings->setStyleSheet(R"(margin-right: 30px)");
advancedSettings->setFixedSize(300, 100); advancedSettings->setFixedSize(300, 100);
connect(advancedSettings, &QPushButton::released, [=](){s->setCurrentIndex(2);}); connect(advancedSettings, &QPushButton::released, [=](){s->setCurrentIndex(1);});
vlayout->addSpacing(10); vlayout->addSpacing(10);
vlayout->addWidget(advancedSettings, 0, Qt::AlignRight); vlayout->addWidget(advancedSettings, 0, Qt::AlignRight);
vlayout->addSpacing(10); vlayout->addSpacing(10);
}
wifiWidget = new WifiUI(0, 5, wifi); wifiWidget = new WifiUI(0, 5, wifi);
connect(wifiWidget, SIGNAL(connectToNetwork(Network)), this, SLOT(connectToNetwork(Network))); connect(wifiWidget, SIGNAL(connectToNetwork(Network)), this, SLOT(connectToNetwork(Network)));
@ -83,13 +78,9 @@ Networking::Networking(QWidget* parent) : QWidget(parent){
s->addWidget(layoutToWidget(vlayout, this)); s->addWidget(layoutToWidget(vlayout, this));
an = new AdvancedNetworking(this, wifi); an = new AdvancedNetworking(this, wifi);
connect(an, &AdvancedNetworking::backPress, [=](){s->setCurrentIndex(1);}); connect(an, &AdvancedNetworking::backPress, [=](){s->setCurrentIndex(0);});
connect(an, &AdvancedNetworking::openKeyboard, [=](){emit openKeyboard();});
connect(an, &AdvancedNetworking::closeKeyboard, [=](){emit closeKeyboard();});
s->addWidget(an); s->addWidget(an);
s->setCurrentIndex(1);
// Update network status // Update network status
QTimer* timer = new QTimer(this); QTimer* timer = new QTimer(this);
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh())); QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh()));
@ -100,7 +91,8 @@ Networking::Networking(QWidget* parent) : QWidget(parent){
font-size: 50px; font-size: 50px;
margin: 0px; margin: 0px;
padding: 15px; padding: 15px;
border-radius: 25px; border-width: 0;
border-radius: 7px;
color: #dddddd; color: #dddddd;
background-color: #444444; background-color: #444444;
} }
@ -124,39 +116,14 @@ void Networking::connectToNetwork(Network n) {
if (n.security_type == SecurityType::OPEN) { if (n.security_type == SecurityType::OPEN) {
wifi->connect(n); wifi->connect(n);
} else if (n.security_type == SecurityType::WPA) { } else if (n.security_type == SecurityType::WPA) {
inputField->setPromptText("Enter password for \"" + n.ssid + "\""); QString pass = InputDialog::getText("Enter password for \"" + n.ssid + "\"");
s->setCurrentIndex(0); wifi->connect(n, pass);
selectedNetwork = n;
emit openKeyboard();
}
} }
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) { void Networking::wrongPassword(QString ssid) {
if(s->currentIndex()==0){ return; // TODO: add this back
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;
}
for (Network n : wifi->seen_networks) { for (Network n : wifi->seen_networks) {
if (n.ssid == ssid) { if (n.ssid == ssid) {
inputField->setPromptText("Wrong password for \"" + n.ssid +"\""); inputField->setPromptText("Wrong password for \"" + n.ssid +"\"");
@ -165,20 +132,7 @@ void Networking::wrongPassword(QString ssid) {
return; 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){ QFrame* hline(QWidget* parent = 0){
@ -192,18 +146,13 @@ QFrame* hline(QWidget* parent = 0){
// AdvancedNetworking functions // AdvancedNetworking functions
AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWidget(parent), wifi(wifi){ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWidget(parent), wifi(wifi){
s = new QStackedLayout;// inputField, mainPage, SSH settings s = new QStackedLayout; // 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);
QVBoxLayout* vlayout = new QVBoxLayout; QVBoxLayout* vlayout = new QVBoxLayout;
// Back button // Back button
QHBoxLayout* backLayout = new QHBoxLayout; QHBoxLayout* backLayout = new QHBoxLayout;
QPushButton* back = new QPushButton("BACK"); QPushButton* back = new QPushButton("Back");
back->setFixedSize(500, 100); back->setFixedSize(500, 100);
connect(back, &QPushButton::released, [=](){emit backPress();}); connect(back, &QPushButton::released, [=](){emit backPress();});
backLayout->addWidget(back, 0, Qt::AlignLeft); backLayout->addWidget(back, 0, Qt::AlignLeft);
@ -228,7 +177,12 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
tetheringPassword->addWidget(new QLabel("Edit tethering password"), 1); tetheringPassword->addWidget(new QLabel("Edit tethering password"), 1);
editPasswordButton = new QPushButton("EDIT"); editPasswordButton = new QPushButton("EDIT");
editPasswordButton->setFixedWidth(500); 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); tetheringPassword->addWidget(editPasswordButton, 1, Qt::AlignRight);
vlayout->addWidget(layoutToWidget(tetheringPassword, this), 0); vlayout->addWidget(layoutToWidget(tetheringPassword, this), 0);
vlayout->addWidget(hline(), 0); vlayout->addWidget(hline(), 0);
@ -255,12 +209,12 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
vlayout->addWidget(layoutToWidget(enableSSHLayout, this)); vlayout->addWidget(layoutToWidget(enableSSHLayout, this));
vlayout->addWidget(hline(), 0); vlayout->addWidget(hline(), 0);
//Authorized SSH keys // SSH keys
QHBoxLayout* authSSHLayout = new QHBoxLayout(this); 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); QPushButton* editAuthSSHButton = new QPushButton("EDIT", this);
editAuthSSHButton->setFixedWidth(500); editAuthSSHButton->setFixedWidth(500);
connect(editAuthSSHButton, &QPushButton::released, [=](){s->setCurrentIndex(2);}); connect(editAuthSSHButton, &QPushButton::released, [=](){s->setCurrentWidget(ssh);});
authSSHLayout->addWidget(editAuthSSHButton); authSSHLayout->addWidget(editAuthSSHButton);
vlayout->addWidget(layoutToWidget(authSSHLayout, this)); vlayout->addWidget(layoutToWidget(authSSHLayout, this));
vlayout->addSpacing(50); vlayout->addSpacing(50);
@ -277,10 +231,9 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid
QWidget* settingsWidget = layoutToWidget(vlayout, this); QWidget* settingsWidget = layoutToWidget(vlayout, this);
settingsWidget->setStyleSheet("margin-left: 40px; margin-right: 40px;"); settingsWidget->setStyleSheet("margin-left: 40px; margin-right: 40px;");
s->addWidget(settingsWidget); s->addWidget(settingsWidget);
s->setCurrentIndex(1);
ssh = new SSH; ssh = new SSH;
connect(ssh, &SSH::closeSSHSettings, [=](){s->setCurrentIndex(1);}); connect(ssh, &SSH::closeSSHSettings, [=](){s->setCurrentIndex(0);});
s->addWidget(ssh); s->addWidget(ssh);
setLayout(s); setLayout(s);
@ -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 // WifiUI functions
@ -370,7 +313,6 @@ void WifiUI::refresh() {
int i = 0; int i = 0;
int countWidgets = 0; int countWidgets = 0;
int button_height = static_cast<int>(this->height() / (networks_per_page + 1) * 0.6);
for (Network &network : wifi->seen_networks) { for (Network &network : wifi->seen_networks) {
QHBoxLayout *hlayout = new QHBoxLayout; QHBoxLayout *hlayout = new QHBoxLayout;
if (page * networks_per_page <= i && i < (page + 1) * networks_per_page) { if (page * networks_per_page <= i && i < (page + 1) * networks_per_page) {
@ -380,30 +322,30 @@ void WifiUI::refresh() {
if(ssid.length() > 30){ if(ssid.length() > 30){
ssid = ssid.left(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 // strength indicator
unsigned int strength_scale = network.strength / 17; unsigned int strength_scale = network.strength / 17;
QPixmap pix("../assets/images/network_" + QString::number(strength_scale) + ".png"); QPixmap pix("../assets/images/network_" + QString::number(strength_scale) + ".png");
QLabel *icon = new QLabel(); QLabel *icon = new QLabel();
icon->setPixmap(pix.scaledToWidth(100, Qt::SmoothTransformation)); icon->setPixmap(pix.scaledToWidth(100, Qt::SmoothTransformation));
icon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); icon->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
hlayout->addWidget(icon); hlayout->addWidget(icon, 0, Qt::AlignRight);
hlayout->addSpacing(20);
// connect button // connect button
QPushButton* btn = new QPushButton(network.security_type == SecurityType::UNSUPPORTED ? "Unsupported" : (network.connected == ConnectedType::CONNECTED ? "Connected" : (network.connected == ConnectedType::CONNECTING ? "Connecting" : "Connect"))); 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); btn->setDisabled(network.connected == ConnectedType::CONNECTED || network.connected == ConnectedType::CONNECTING || network.security_type == SecurityType::UNSUPPORTED);
hlayout->addWidget(btn); btn->setFixedWidth(350);
hlayout->addSpacing(20); hlayout->addWidget(btn, 0, Qt::AlignRight);
connectButtons->addButton(btn, i); connectButtons->addButton(btn, i);
QWidget * w = new QWidget; vlayout->addLayout(hlayout, 1);
w->setLayout(hlayout);
vlayout->addWidget(w, 1);
// Don't add the last horizontal line // 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()) { if (page * networks_per_page <= i+1 && i+1 < (page + 1) * networks_per_page && i+1 < wifi->seen_networks.size()) {
vlayout->addWidget(hline(), 0); vlayout->addWidget(hline(), 0);
@ -412,34 +354,23 @@ void WifiUI::refresh() {
} }
i++; 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"); QPushButton* prev = new QPushButton("Previous");
prev->setEnabled(page); 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"); 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); 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())); QObject::connect(next, SIGNAL(released()), this, SLOT(nextPage()));
prev_next_buttons->addWidget(prev);
prev_next_buttons->addWidget(next); prev_next_buttons->addWidget(next);
QWidget *w = new QWidget; vlayout->addLayout(prev_next_buttons, 2);
w->setLayout(prev_next_buttons);
vlayout->addWidget(w, 1, Qt::AlignBottom);
} }
void WifiUI::handleButton(QAbstractButton* button) { void WifiUI::handleButton(QAbstractButton* button) {
@ -452,6 +383,7 @@ void WifiUI::prevPage() {
page--; page--;
refresh(); refresh();
} }
void WifiUI::nextPage() { void WifiUI::nextPage() {
page++; page++;
refresh(); refresh();

@ -47,7 +47,6 @@ public:
QStackedLayout* s; QStackedLayout* s;
private: private:
InputField* inputField;
QLabel* ipLabel; QLabel* ipLabel;
QPushButton* editPasswordButton; QPushButton* editPasswordButton;
SSH* ssh; SSH* ssh;
@ -56,14 +55,11 @@ private:
WifiManager* wifi = nullptr; WifiManager* wifi = nullptr;
bool isSSHEnabled(); bool isSSHEnabled();
signals: signals:
void openKeyboard();
void closeKeyboard();
void backPress(); void backPress();
public slots: public slots:
void receiveText(QString text);
void abortTextInput();
void toggleTethering(int enable); void toggleTethering(int enable);
void toggleSSH(int enable); void toggleSSH(int enable);
void refresh(); void refresh();
@ -73,7 +69,7 @@ class Networking : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
explicit Networking(QWidget* parent = 0); explicit Networking(QWidget* parent = 0, bool show_advanced = true);
private: private:
QStackedLayout* s = nullptr; // keyboard, wifiScreen, advanced QStackedLayout* s = nullptr; // keyboard, wifiScreen, advanced
@ -83,19 +79,10 @@ private:
WifiUI* wifiWidget; WifiUI* wifiWidget;
WifiManager* wifi = nullptr; WifiManager* wifi = nullptr;
InputField* inputField;
signals:
void openKeyboard();
void closeKeyboard();
private slots: private slots:
void connectToNetwork(Network n); void connectToNetwork(Network n);
void refresh(); void refresh();
void receiveText(QString text);
void abortTextInput();
void wrongPassword(QString ssid); void wrongPassword(QString ssid);
void successfulConnection(QString ssid);
void sidebarChange();
}; };

@ -225,9 +225,6 @@ QWidget * developer_panel() {
QWidget * network_panel(QWidget * parent) { QWidget * network_panel(QWidget * parent) {
Networking *w = new Networking(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; return w;
} }
@ -276,7 +273,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) {
border: none; border: none;
background: none; background: none;
font-size: 65px; font-size: 65px;
font-weight: 600; font-weight: 500;
padding-top: 35px; padding-top: 35px;
padding-bottom: 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);
}

@ -48,6 +48,4 @@ private:
public slots: public slots:
void setActivePanel(); void setActivePanel();
void closeSidebar();
void openSidebar();
}; };

@ -1,28 +0,0 @@
#include <string>
#include <QFontDatabase>
#include <QApplication>
#ifdef QCOM2
#include <qpa/qplatformnativeinterface.h>
#include <QPlatformSurfaceEvent>
#include <wayland-client-protocol.h>
#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<wl_surface*>(native->nativeResourceForWindow("surface", w->windowHandle()));
wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270);
wl_surface_commit(s);
w->showFullScreen();
#endif
}

@ -1,4 +1,15 @@
#include <string>
#include <QWidget> #include <QWidget>
#include <QFontDatabase>
#include <QApplication>
#ifdef QCOM2
#include <qpa/qplatformnativeinterface.h>
#include <QPlatformSurfaceEvent>
#include <wayland-client-protocol.h>
#endif
#ifdef QCOM2 #ifdef QCOM2
const int vwp_w = 2160, vwp_h = 1080; const int vwp_w = 2160, vwp_h = 1080;
@ -6,4 +17,16 @@
const int vwp_w = 1920, vwp_h = 1080; const int vwp_w = 1920, vwp_h = 1080;
#endif #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<wl_surface*>(native->nativeResourceForWindow("surface", w->windowHandle()));
wl_surface_set_buffer_transform(s, WL_OUTPUT_TRANSFORM_270);
wl_surface_commit(s);
w->showFullScreen();
#endif
}

@ -1,6 +1,7 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include <cstdlib> #include <cstdlib>
#include <fstream>
#include <iostream> #include <iostream>
#ifndef BRANCH #ifndef BRANCH
@ -24,9 +25,7 @@ int fresh_clone() {
int err; int err;
// Cleanup // Cleanup
err = std::system("rm -rf /tmp/openpilot"); err = std::system("rm -rf /tmp/openpilot /data/openpilot");
if (err) return 1;
err = std::system("rm -rf /data/openpilot");
if (err) return 1; if (err) return 1;
// Clone // Clone
@ -40,14 +39,22 @@ int fresh_clone() {
err = std::system("mv /tmp/openpilot /data"); err = std::system("mv /tmp/openpilot /data");
if (err) return 1; 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; return 0;
} }
int install() { int install() {
int err; int err;
// TODO: Disable SSH after install done
// Wait for valid time // Wait for valid time
while (!time_valid()) { while (!time_valid()) {
usleep(500 * 1000); usleep(500 * 1000);

@ -7,19 +7,20 @@
#include <QApplication> #include <QApplication>
#include "setup.hpp" #include "setup.hpp"
#include "offroad/wifi.hpp" #include "offroad/networking.hpp"
#include "widgets/input_field.hpp" #include "widgets/input_field.hpp"
#include "qt_window.hpp" #include "qt_window.hpp"
#define USER_AGENT "AGNOSSetup-0.1" #define USER_AGENT "AGNOSSetup-0.1"
void Setup::download(QString url) { void Setup::download(QString url) {
setCurrentIndex(count() - 1); setCurrentIndex(count() - 2);
QCoreApplication::processEvents(QEventLoop::AllEvents, 1000);
CURL *curl; CURL *curl = curl_easy_init();
curl = curl_easy_init(); if (!curl) {
// TODO: exit with return code emit downloadFailed();
if (!curl) return; }
char tmpfile[] = "/tmp/installer_XXXXXX"; char tmpfile[] = "/tmp/installer_XXXXXX";
FILE *fp = fdopen(mkstemp(tmpfile), "w"); 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_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_USERAGENT, USER_AGENT); 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); curl_easy_cleanup(curl);
fclose(fp); fclose(fp);
@ -41,64 +46,51 @@ QLabel * title_label(QString text) {
QLabel *l = new QLabel(text); QLabel *l = new QLabel(text);
l->setStyleSheet(R"( l->setStyleSheet(R"(
font-size: 100px; font-size: 100px;
font-weight: bold; font-weight: 500;
)"); )");
return l; return l;
} }
QWidget * Setup::getting_started() { QWidget * Setup::build_page(QString title, QWidget *content, bool next, bool prev) {
QVBoxLayout *main_layout = new QVBoxLayout(); 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."); QHBoxLayout *nav_layout = new QHBoxLayout();
body->setStyleSheet(R"(font-size: 65px;)");
main_layout->addWidget(body, 0, Qt::AlignCenter);
main_layout->addSpacing(100); 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);
QPushButton *btn = new QPushButton("Continue"); QPushButton *continue_btn = new QPushButton("Continue");
main_layout->addWidget(btn); nav_layout->addWidget(continue_btn, 0, Qt::AlignBottom | Qt::AlignRight);
QObject::connect(btn, SIGNAL(released()), this, SLOT(nextPage())); QObject::connect(continue_btn, SIGNAL(released()), this, SLOT(nextPage()));
continue_btn->setVisible(next);
main_layout->addLayout(nav_layout, 0);
QWidget *widget = new QWidget(); QWidget *widget = new QWidget();
widget->setLayout(main_layout); widget->setLayout(main_layout);
return widget; return widget;
} }
QWidget * Setup::network_setup() { QWidget * Setup::getting_started() {
QLabel *body = new QLabel("Before we get on the road, let's finish\ninstallation and cover some details.");
QVBoxLayout *main_layout = new QVBoxLayout(); body->setAlignment(Qt::AlignHCenter);
main_layout->setContentsMargins(50, 50, 50, 50); body->setStyleSheet(R"(font-size: 80px;)");
return build_page("Getting Started", body, true, false);
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 *widget = new QWidget(); QWidget * Setup::network_setup() {
widget->setLayout(main_layout); Networking *wifi = new Networking(this, false);
return widget; return build_page("Connect to WiFi", wifi, true, true);
} }
QWidget * Setup::software_selection() { QWidget * Setup::software_selection() {
QVBoxLayout *main_layout = new QVBoxLayout(); 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"); QPushButton *dashcam_btn = new QPushButton("Dashcam");
main_layout->addWidget(dashcam_btn); main_layout->addWidget(dashcam_btn);
@ -110,40 +102,55 @@ QWidget * Setup::software_selection() {
QPushButton *custom_btn = new QPushButton("Custom"); QPushButton *custom_btn = new QPushButton("Custom");
main_layout->addWidget(custom_btn); main_layout->addWidget(custom_btn);
QObject::connect(custom_btn, SIGNAL(released()), this, SLOT(nextPage())); QObject::connect(custom_btn, &QPushButton::released, this, [=]() {
QString input_url = InputDialog::getText("Enter URL");
main_layout->addSpacing(100); if (input_url.size()) {
this->download(input_url);
QPushButton *prev_btn = new QPushButton("Back"); }
main_layout->addWidget(prev_btn); });
QObject::connect(prev_btn, SIGNAL(released()), this, SLOT(prevPage()));
QWidget *widget = new QWidget(); QWidget *widget = new QWidget();
widget->setLayout(main_layout); 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(); QVBoxLayout *main_layout = new QVBoxLayout();
main_layout->setMargin(50); main_layout->addWidget(title_label("Downloading..."), 0, Qt::AlignCenter);
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)));
QWidget *widget = new QWidget(); QWidget *widget = new QWidget();
widget->setLayout(main_layout); widget->setLayout(main_layout);
return widget; return widget;
} }
QWidget * Setup::downloading() { QWidget * Setup::download_failed() {
QVBoxLayout *main_layout = new QVBoxLayout(); 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(); QWidget *widget = new QWidget();
widget->setLayout(main_layout); widget->setLayout(main_layout);
@ -162,23 +169,24 @@ Setup::Setup(QWidget *parent) {
addWidget(getting_started()); addWidget(getting_started());
addWidget(network_setup()); addWidget(network_setup());
addWidget(software_selection()); addWidget(software_selection());
addWidget(custom_software());
addWidget(downloading()); addWidget(downloading());
addWidget(download_failed());
QObject::connect(this, SIGNAL(downloadFailed()), this, SLOT(nextPage()));
setStyleSheet(R"( setStyleSheet(R"(
* { * {
font-family: Inter; font-family: Inter;
}
QWidget {
color: white; color: white;
background-color: black; background-color: black;
} }
QPushButton { QPushButton {
font-size: 60px; padding: 50px;
padding: 60px; padding-right: 100px;
width: 800px; padding-left: 100px;
color: white; border: 7px solid white;
background-color: blue; border-radius: 20px;
font-size: 50px;
} }
)"); )");
} }

@ -11,14 +11,17 @@ public:
explicit Setup(QWidget *parent = 0); explicit Setup(QWidget *parent = 0);
private: private:
QLineEdit *url_input;
QPushButton *continue_btn;
QWidget *getting_started(); QWidget *getting_started();
QWidget *network_setup(); QWidget *network_setup();
QWidget *software_selection(); QWidget *software_selection();
QWidget *custom_software(); QWidget *custom_software();
QWidget *downloading(); QWidget *downloading();
QWidget *download_failed();
QWidget *build_page(QString title, QWidget *content, bool next, bool prev);
signals:
void downloadFailed();
public slots: public slots:
void nextPage(); void nextPage();

@ -1,61 +1,86 @@
#include <QPushButton> #include <QPushButton>
#include "input_field.hpp" #include "input_field.hpp"
#include "qt_window.hpp"
InputField::InputField(QWidget *parent, int minTextLength): QWidget(parent), minTextLength(minTextLength) { InputDialog::InputDialog(QString prompt_text, QWidget *parent): QDialog(parent) {
layout = new QGridLayout(); layout = new QVBoxLayout();
layout->setSpacing(30); layout->setContentsMargins(50, 50, 50, 50);
layout->setSpacing(20);
label = new QLabel(this); // build header
label->setStyleSheet(R"(font-size: 70px; font-weight: 500;)"); QHBoxLayout *header_layout = new QHBoxLayout();
layout->addWidget(label, 0, 0,Qt::AlignLeft);
layout->setColumnStretch(0, 1);
QPushButton* cancel = new QPushButton("Cancel"); label = new QLabel(prompt_text, this);
cancel->setFixedSize(300, 150); label->setStyleSheet(R"(font-size: 75px; font-weight: 500;)");
cancel->setStyleSheet(R"(padding: 0;)"); header_layout->addWidget(label, 1, Qt::AlignLeft);
layout->addWidget(cancel, 0, 1, Qt::AlignRight);
QObject::connect(cancel, SIGNAL(released()), this, SLOT(emitEmpty())); 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 // text box
layout->addSpacing(20);
line = new QLineEdit(); line = new QLineEdit();
line->setStyleSheet(R"( line->setStyleSheet(R"(
color: white; border: none;
background-color: #444444; background-color: #444444;
font-size: 80px; font-size: 80px;
font-weight: 500; font-weight: 500;
padding: 10px; padding: 10px;
)"); )");
layout->addWidget(line, 1, 0, 1, -1); layout->addWidget(line, 1, Qt::AlignTop);
k = new Keyboard(this); k = new Keyboard(this);
QObject::connect(k, SIGNAL(emitButton(QString)), this, SLOT(getText(QString))); QObject::connect(k, SIGNAL(emitButton(QString)), this, SLOT(handleInput(QString)));
layout->addWidget(k, 2, 0, 1, -1); layout->addWidget(k, 2, Qt::AlignBottom);
setStyleSheet(R"(
* {
color: white;
background-color: black;
}
)");
setLayout(layout); setLayout(layout);
} }
void InputField::setPromptText(QString text) { QString InputDialog::getText(const QString prompt) {
label->setText(text); InputDialog d = InputDialog(prompt);
const int ret = d.exec();
if (ret) {
return d.text();
} else {
return QString();
}
} }
void InputField::emitEmpty() { QString InputDialog::text() {
line->setText(""); return line->text();
emit cancel();
} }
void InputField::getText(QString s) { int InputDialog::exec() {
setMainWindow(this);
return QDialog::exec();
}
void InputDialog::handleInput(QString s) {
if (!QString::compare(s,"")) { if (!QString::compare(s,"")) {
line->backspace(); line->backspace();
} }
if (!QString::compare(s,"")) { if (!QString::compare(s,"")) {
if(line->text().length()<minTextLength){ done(QDialog::Accepted);
setPromptText("Need at least "+QString::number(minTextLength)+" characters!");
return;
}
emitText(line->text());
line->setText("");
} }
QVector<QString> control_buttons {"", "", "ABC", "", "#+=", "", "123"}; QVector<QString> control_buttons {"", "", "ABC", "", "#+=", "", "123"};

@ -3,30 +3,29 @@
#include <QLabel> #include <QLabel>
#include <QString> #include <QString>
#include <QWidget> #include <QWidget>
#include <QDialog>
#include <QLineEdit> #include <QLineEdit>
#include <QGridLayout> #include <QVBoxLayout>
#include "keyboard.hpp" #include "keyboard.hpp"
class InputField : public QWidget { class InputDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit InputField(QWidget* parent = 0, int minTextLength = 0); explicit InputDialog(QString prompt_text, QWidget* parent = 0);
void setPromptText(QString text); static QString getText(QString prompt);
int minTextLength; QString text();
private: private:
QLineEdit *line; QLineEdit *line;
Keyboard *k; Keyboard *k;
QLabel *label; QLabel *label;
QGridLayout *layout; QVBoxLayout *layout;
public slots: public slots:
void getText(QString s); int exec() override;
void emitEmpty();
signals: private slots:
void cancel(); void handleInput(QString s);
void emitText(QString s);
}; };

@ -7,20 +7,22 @@
#include "keyboard.hpp" #include "keyboard.hpp"
const int DEFAULT_WIDTH = 1; const int DEFAULT_STRETCH = 1;
const int SPACEBAR_WIDTH = 3; const int SPACEBAR_STRETCH = 3;
KeyboardLayout::KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> layout) : QWidget(parent) { KeyboardLayout::KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> layout) : QWidget(parent) {
QVBoxLayout* vlayout = new QVBoxLayout; 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*))); QObject::connect(btn_group, SIGNAL(buttonClicked(QAbstractButton*)), parent, SLOT(handleButton(QAbstractButton*)));
int i = 0;
for (const auto &s : layout) { for (const auto &s : layout) {
QHBoxLayout *hlayout = new QHBoxLayout; QHBoxLayout *hlayout = new QHBoxLayout;
hlayout->setSpacing(30);
if (i == 1) { if (vlayout->count() == 1) {
hlayout->addSpacing(90); hlayout->addSpacing(90);
} }
@ -28,28 +30,32 @@ KeyboardLayout::KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> la
QPushButton* btn = new QPushButton(p); QPushButton* btn = new QPushButton(p);
btn->setFixedHeight(120); btn->setFixedHeight(120);
btn_group->addButton(btn); btn_group->addButton(btn);
hlayout->addSpacing(30); hlayout->addWidget(btn, p == QString(" ") ? SPACEBAR_STRETCH : DEFAULT_STRETCH);
if (p == QString(" ")) {
hlayout->addWidget(btn, SPACEBAR_WIDTH);
} else {
hlayout->addWidget(btn, DEFAULT_WIDTH);
}
} }
if (i == 1) { if (vlayout->count() == 1) {
hlayout->addSpacing(90); hlayout->addSpacing(90);
} }
vlayout->addLayout(hlayout); vlayout->addLayout(hlayout);
i++;
} }
setStyleSheet(R"(
QPushButton {
font-size: 65px;
margin: 0px;
padding: 0px;
border-radius: 7px;
color: #dddddd;
background-color: #444444;
}
)");
setLayout(vlayout); setLayout(vlayout);
} }
Keyboard::Keyboard(QWidget *parent) : QWidget(parent) { Keyboard::Keyboard(QWidget *parent) : QFrame(parent) {
main_layout = new QStackedLayout; main_layout = new QStackedLayout;
main_layout->setMargin(0);
// lowercase // lowercase
std::vector<QVector<QString>> lowercase = { std::vector<QVector<QString>> lowercase = {
@ -69,7 +75,7 @@ Keyboard::Keyboard(QWidget *parent) : QWidget(parent) {
}; };
main_layout->addWidget(new KeyboardLayout(this, uppercase)); main_layout->addWidget(new KeyboardLayout(this, uppercase));
// 1234567890 // numbers + specials
std::vector<QVector<QString>> numbers = { std::vector<QVector<QString>> numbers = {
{"1","2","3","4","5","6","7","8","9","0"}, {"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)); main_layout->addWidget(new KeyboardLayout(this, numbers));
// Special characters // extra specials
std::vector<QVector<QString>> specials = { std::vector<QVector<QString>> specials = {
{"[","]","{","}","#","%","^","*","+","="}, {"[","]","{","}","#","%","^","*","+","="},
{"_","\\","|","~","<",">","","£","¥",""}, {"_","\\","|","~","<",">","","£","¥",""},
@ -89,18 +95,7 @@ Keyboard::Keyboard(QWidget *parent) : QWidget(parent) {
setLayout(main_layout); setLayout(main_layout);
main_layout->setCurrentIndex(0); main_layout->setCurrentIndex(0);
setStyleSheet(R"(
QPushButton {
padding: 0;
font-size: 50px;
}
* {
background-color: #99777777;
} }
)");
}
void Keyboard::handleButton(QAbstractButton* m_button) { void Keyboard::handleButton(QAbstractButton* m_button) {
QString id = m_button->text(); QString id = m_button->text();

@ -2,6 +2,7 @@
#include <vector> #include <vector>
#include <QFrame>
#include <QString> #include <QString>
#include <QWidget> #include <QWidget>
#include <QStackedLayout> #include <QStackedLayout>
@ -14,7 +15,7 @@ public:
explicit KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> layout); explicit KeyboardLayout(QWidget *parent, std::vector<QVector<QString>> layout);
}; };
class Keyboard : public QWidget { class Keyboard : public QFrame {
Q_OBJECT Q_OBJECT
public: public:

@ -1,20 +1,12 @@
#include <QDebug>
#include <QHBoxLayout>
#include <QLabel> #include <QLabel>
#include <QPushButton> #include <QPushButton>
#include <QState> #include <QState>
#include <QStateMachine> #include <QStateMachine>
#include <QNetworkReply> #include <QNetworkReply>
#include "common/params.h"
#include "widgets/ssh_keys.hpp" #include "widgets/ssh_keys.hpp"
#include "widgets/input_field.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){ SSH::SSH(QWidget* parent) : QWidget(parent){
// init variables // init variables
@ -24,40 +16,25 @@ SSH::SSH(QWidget* parent) : QWidget(parent){
networkTimer->setInterval(5000); networkTimer->setInterval(5000);
connect(networkTimer, SIGNAL(timeout()), this, SLOT(timeout())); connect(networkTimer, SIGNAL(timeout()), this, SLOT(timeout()));
// Construct the layouts to display
slayout = new QStackedLayout(this); // Initial screen, input, waiting for response
// Layout on entering // Layout on entering
QVBoxLayout* initialLayout = new QVBoxLayout; QVBoxLayout* main_layout = new QVBoxLayout;
initialLayout->setContentsMargins(80, 80, 80, 80); main_layout->setMargin(50);
QHBoxLayout* header = new QHBoxLayout;
QPushButton* exitButton = new QPushButton("BACK", this); QPushButton* exitButton = new QPushButton("BACK", this);
exitButton->setFixedSize(500, 100); exitButton->setFixedSize(500, 100);
header->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop); main_layout->addWidget(exitButton, 0, Qt::AlignLeft | Qt::AlignTop);
initialLayout->addWidget(layout_to_widget(header)); 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->setWordWrap(true);
wallOfText->setStyleSheet(R"(font-size: 60px;)"); wallOfText->setStyleSheet(R"(font-size: 60px;)");
initialLayout->addWidget(wallOfText, 0); main_layout->addWidget(wallOfText, 0);
QPushButton* actionButton = new QPushButton; QPushButton* actionButton = new QPushButton;
actionButton->setFixedHeight(100); actionButton->setFixedHeight(100);
initialLayout->addWidget(actionButton, 0, Qt::AlignBottom); main_layout->addWidget(actionButton, 0, Qt::AlignBottom);
slayout->addWidget(layout_to_widget(initialLayout));
InputField* input = new InputField;
slayout->addWidget(input);
QLabel* loading = new QLabel("Loading SSH keys from GitHub.");
slayout->addWidget(loading);
setStyleSheet(R"( setStyleSheet(R"(
QPushButton { QPushButton {
font-size: 60px; font-size: 60px;
@ -68,59 +45,61 @@ SSH::SSH(QWidget* parent) : QWidget(parent){
background-color: #444444; 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); QStateMachine* state = new QStateMachine(this);
QState* initialState = new QState(); //State when entering the widget QState* initialState = new QState(); //State when entering the widget
QState* initialStateNoGithub = new QState(); //Starting state, key not connected QState* initialStateNoGithub = new QState(); //Starting state, key not connected
QState* initialStateConnected = new QState(); //Starting state, ssh 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* 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* loadingState = new QState(); // State while waiting for the network response QState* loadingState = new QState(); // State while waiting for the network response
// Adding states to the state machine and adding the transitions // Adding states to the state machine and adding the transitions
state->addState(initialState); 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::NoSSHAdded, initialStateNoGithub);
initialState->addTransition(this, &SSH::SSHAdded, initialStateConnected); initialState->addTransition(this, &SSH::SSHAdded, initialStateConnected);
state->addState(quitState);
connect(quitState, &QState::entered, [=](){emit closeSSHSettings();});
quitState->addTransition(quitState, &QState::entered, initialState);
state->addState(initialStateConnected); state->addState(initialStateConnected);
connect(initialStateConnected, &QState::entered, [=](){actionButton->setText("Remove GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #750c0c;)");}); connect(initialStateConnected, &QState::entered, [=](){
initialStateConnected->addTransition(exitButton, &QPushButton::released, quitState); actionButton->setText("Clear SSH keys");
actionButton->setStyleSheet(R"(background-color: #750c0c;)");
});
initialStateConnected->addTransition(actionButton, &QPushButton::released, removeSSH_State); initialStateConnected->addTransition(actionButton, &QPushButton::released, removeSSH_State);
state->addState(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); removeSSH_State->addTransition(removeSSH_State, &QState::entered, initialState);
state->addState(initialStateNoGithub); state->addState(initialStateNoGithub);
connect(initialStateNoGithub, &QState::entered, [=](){actionButton->setText("Link GitHub SSH keys"); actionButton->setStyleSheet(R"(background-color: #444444;)");}); connect(initialStateNoGithub, &QState::entered, [=](){
initialStateNoGithub->addTransition(exitButton, &QPushButton::released, quitState); actionButton->setText("Link GitHub SSH keys");
initialStateNoGithub->addTransition(actionButton, &QPushButton::released, defaultInputFieldState); actionButton->setStyleSheet(R"(background-color: #444444;)");
connect(actionButton, &QPushButton::released, [=](){input->setPromptText("Enter your GitHub username");}); });
initialStateNoGithub->addTransition(actionButton, &QPushButton::released, loadingState);
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);
state->addState(loadingState); state->addState(loadingState);
connect(loadingState, &QState::entered, [=](){slayout->setCurrentIndex(2); getSSHKeys();}); connect(loadingState, &QState::entered, [=](){
connect(this, &SSH::failedResponse, [=](QString message){input->setPromptText(message);}); QString user = InputDialog::getText("Enter your GitHub username");
loadingState->addTransition(this, &SSH::failedResponse, defaultInputFieldState); 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); loadingState->addTransition(this, &SSH::gotSSHKeys, initialState);
state->setInitialState(initialState); state->setInitialState(initialState);
state->start(); state->start();
} }
@ -134,8 +113,8 @@ void SSH::checkForSSHKey(){
} }
} }
void SSH::getSSHKeys(){ void SSH::getSSHKeys(QString username){
QString url = "https://github.com/" + usernameGitHub + ".keys"; QString url = "https://github.com/" + username + ".keys";
aborted = false; aborted = false;
reply = manager->get(QNetworkRequest(QUrl(url))); reply = manager->get(QNetworkRequest(QUrl(url)));
connect(reply, SIGNAL(finished()), this, SLOT(parseResponse())); connect(reply, SIGNAL(finished()), this, SLOT(parseResponse()));
@ -155,7 +134,7 @@ void SSH::parseResponse(){
Params().write_db_value("GithubSshKeys", response.toStdString()); Params().write_db_value("GithubSshKeys", response.toStdString());
emit gotSSHKeys(); emit gotSSHKeys();
} else { } else {
emit failedResponse("Username "+usernameGitHub+" doesn't exist"); emit failedResponse("Username doesn't exist");
} }
} else { } else {
emit failedResponse("Request timed out"); emit failedResponse("Request timed out");

@ -1,15 +1,9 @@
#pragma once #pragma once
#include <QWidget>
#include <QButtonGroup>
#include <QVBoxLayout>
#include <QStackedWidget>
#include <QPushButton>
#include <QTimer> #include <QTimer>
#include <QWidget>
#include <QNetworkAccessManager> #include <QNetworkAccessManager>
#include "widgets/input_field.hpp"
class SSH : public QWidget { class SSH : public QWidget {
Q_OBJECT Q_OBJECT
@ -17,27 +11,22 @@ public:
explicit SSH(QWidget* parent = 0); explicit SSH(QWidget* parent = 0);
private: private:
InputField* inputField;
QStackedLayout* slayout;
QString usernameGitHub;
QNetworkAccessManager* manager; QNetworkAccessManager* manager;
QNetworkReply* reply; QNetworkReply* reply;
QTimer* networkTimer; QTimer* networkTimer;
bool aborted; bool aborted;
void getSSHKeys(QString user);
signals: signals:
void closeSSHSettings();
void openKeyboard();
void closeKeyboard();
void NoSSHAdded(); void NoSSHAdded();
void SSHAdded(); void SSHAdded();
void failedResponse(QString errorString); void failedResponse(QString errorString);
void gotSSHKeys(); void gotSSHKeys();
void closeSSHSettings();
private slots: private slots:
void checkForSSHKey(); void checkForSSHKey();
void getSSHKeys();
void timeout(); void timeout();
void parseResponse(); void parseResponse();
}; };

Loading…
Cancel
Save