openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

373 lines
12 KiB

#include <QDebug>
#include <QHBoxLayout>
#include <QLabel>
#include <QPixmap>
#include <QPushButton>
#include <QLineEdit>
#include <QRandomGenerator>
#include "wifi.hpp"
#include "widgets/toggle.hpp"
void clearLayout(QLayout* layout) {
while (QLayoutItem* item = layout->takeAt(0)) {
if (QWidget* widget = item->widget()) {
widget->deleteLater();
}
if (QLayout* childLayout = item->layout()) {
clearLayout(childLayout);
}
delete item;
}
}
QWidget* layoutToWidget(QLayout* l, QWidget* parent){
QWidget* q = new QWidget(parent);
q->setLayout(l);
return q;
}
// Networking functions
Networking::Networking(QWidget* parent){
try {
wifi = new WifiManager(this);
} catch (std::exception &e) {
QLabel* warning = new QLabel("Network manager is inactive!");
warning->setStyleSheet(R"(font-size: 65px;)");
QVBoxLayout* warning_layout = new QVBoxLayout;
warning_layout->addWidget(warning, 0, Qt::AlignCenter);
setLayout(warning_layout);
return;
}
connect(wifi, SIGNAL(wrongPassword(QString)), this, SLOT(wrongPassword(QString)));
connect(wifi, SIGNAL(successfulConnection(QString)), this, SLOT(successfulConnection(QString)));
s = new QStackedLayout(this);
inputField = new InputField(this, 8);
connect(inputField, SIGNAL(emitText(QString)), this, SLOT(receiveText(QString)));
connect(inputField, SIGNAL(cancel()), this, SLOT(abortTextInput()));
s->addWidget(inputField);
QVBoxLayout* vlayout = new QVBoxLayout(this);
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);
wifiWidget = new WifiUI(0, 5, wifi);
connect(wifiWidget, SIGNAL(connectToNetwork(Network)), this, SLOT(connectToNetwork(Network)));
vlayout->addWidget(wifiWidget, 1);
s->addWidget(layoutToWidget(vlayout, this));
an = new AdvancedNetworking(this, wifi);
connect(an, &AdvancedNetworking::backPress, [=](){s->setCurrentIndex(1);});
s->addWidget(an);
s->setCurrentIndex(1);
// Update network status
QTimer* timer = new QTimer(this);
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh()));
timer->start(5000);
setStyleSheet(R"(
QPushButton {
font-size: 50px;
margin: 0px;
padding: 15px;
border-radius: 25px;
color: #dddddd;
background-color: #444444;
}
QPushButton:disabled {
padding: 20px;
color: #777777;
background-color: #222222;
}
)");
}
void Networking::refresh(){
wifiWidget->refresh();
}
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;
}
}
void Networking::abortTextInput(){
s->setCurrentIndex(1);
}
void Networking::receiveText(QString text) {
wifi->disconnect();
wifi->connect(selectedNetwork, text);
s->setCurrentIndex(1);
}
void Networking::wrongPassword(QString ssid) {
if(s->currentIndex()==0){
qDebug()<<"Wrong password, but we are already trying a new network";
return;
}
for (Network n : wifi->seen_networks) {
if (n.ssid == ssid) {
inputField->setPromptText("Wrong password for \"" + n.ssid +"\"");
s->setCurrentIndex(0);
return;
}
}
}
void Networking::successfulConnection(QString ssid) {
//Maybe we will want to do something here in the future.
}
void Networking::sidebarChange(){
s->setCurrentIndex(1);
an->s->setCurrentIndex(1);
refresh();
}
QFrame* hline(QWidget* parent = 0){
QFrame* line = new QFrame(parent);
line->setFrameShape(QFrame::StyledPanel);
line->setStyleSheet("margin-left: 40px; margin-right: 40px; border-width: 1px; border-bottom-style: solid; border-color: gray;");
line->setFixedHeight(2);
return line;
}
// AdvancedNetworking functions
AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWidget(parent), wifi(wifi){
s = new QStackedLayout(this);// inputField and settings
inputField = new InputField(this, 8);
connect(inputField, SIGNAL(emitText(QString)), this, SLOT(receiveText(QString)));
connect(inputField, SIGNAL(cancel()), this, SLOT(abortTextInput()));
s->addWidget(inputField);
QVBoxLayout* vlayout = new QVBoxLayout(this);
//Back button
QHBoxLayout* backLayout = new QHBoxLayout(this);
QPushButton* back = new QPushButton("BACK");
back->setFixedWidth(500);
connect(back, &QPushButton::released, [=](){emit backPress();});
backLayout->addWidget(back, 0, Qt::AlignLeft);
vlayout->addWidget(layoutToWidget(backLayout, this), 0, Qt::AlignLeft);
//Enable tethering layout
QHBoxLayout* tetheringToggleLayout = new QHBoxLayout(this);
tetheringToggleLayout->addWidget(new QLabel("Enable tethering", this));
Toggle* toggle_switch = new Toggle(this);
toggle_switch->setFixedSize(150, 100);
tetheringToggleLayout->addWidget(toggle_switch);
tetheringToggleLayout->addSpacing(40);
if (wifi->tetheringEnabled()) {
toggle_switch->togglePosition();
}
QObject::connect(toggle_switch, SIGNAL(stateChanged(int)), this, SLOT(toggleTethering(int)));
vlayout->addWidget(layoutToWidget(tetheringToggleLayout, this), 0);
vlayout->addWidget(hline(this), 0);
//Change tethering password
QHBoxLayout *tetheringPassword = new QHBoxLayout(this);
tetheringPassword->addWidget(new QLabel("Edit tethering password", this), 1);
editPasswordButton = new QPushButton("EDIT", this);
editPasswordButton->setFixedWidth(500);
connect(editPasswordButton, &QPushButton::released, [=](){inputField->setPromptText("Enter the new hotspot password"); s->setCurrentIndex(0);});
tetheringPassword->addWidget(editPasswordButton, 1, Qt::AlignRight);
vlayout->addWidget(layoutToWidget(tetheringPassword, this), 0);
vlayout->addWidget(hline(this), 0);
//IP adress
QHBoxLayout* IPlayout = new QHBoxLayout(this);
IPlayout->addWidget(new QLabel("IP address: "), 0);
ipLabel = new QLabel(wifi->ipv4_address);
ipLabel->setStyleSheet("color: #aaaaaa");
IPlayout->addWidget(ipLabel, 0, Qt::AlignRight);
vlayout->addWidget(layoutToWidget(IPlayout, this), 0);
vlayout->addWidget(hline(this), 0);
vlayout->addSpacing(300);
// //Enable SSH
// QHBoxLayout* enableSSHLayout = new QHBoxLayout(this);
// enableSSHLayout->addWidget(new QLabel("Enable SSH", this));
// Toggle* toggle_switch_SSH = new Toggle(this);
// toggle_switch_SSH->setFixedSize(150, 100);
// enableSSHLayout->addWidget(toggle_switch_SSH);
// vlayout->addWidget(layoutToWidget(enableSSHLayout, this));
// //Authorized SSH keys
// QHBoxLayout* authSSHLayout = new QHBoxLayout(this);
// authSSHLayout->addWidget(new QLabel("Authorized SSH keys", this));
// QPushButton* editAuthSSHButton = new QPushButton("EDIT", this);
// authSSHLayout->addWidget(editAuthSSHButton);
// vlayout->addWidget(layoutToWidget(authSSHLayout, this));
// //Disconnect or delete connections
// QHBoxLayout* dangerZone = new QHBoxLayout(this);
// QPushButton* disconnect = new QPushButton("Disconnect from WiFi", this);
// dangerZone->addWidget(disconnect);
// QPushButton* deleteAll = new QPushButton("DELETE ALL NETWORKS", this);
// dangerZone->addWidget(deleteAll);
// vlayout->addWidget(layoutToWidget(dangerZone, this));
//vlayout to widget
QWidget* settingsWidget = layoutToWidget(vlayout, this);
settingsWidget->setStyleSheet("margin-left: 40px; margin-right: 40px;");
s->addWidget(settingsWidget);
s->setCurrentIndex(1);
setLayout(s);
// Update network status
QTimer* timer = new QTimer(this);
QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh()));
timer->start(5000);
}
void AdvancedNetworking::refresh(){
ipLabel->setText(wifi->ipv4_address);
}
void AdvancedNetworking::toggleTethering(int enable) {
if (enable) {
wifi->enableTethering();
} else {
wifi->disableTethering();
}
editPasswordButton->setEnabled(!enable);
}
void AdvancedNetworking::receiveText(QString text){
wifi->changeTetheringPassword(text);
s->setCurrentIndex(1);
}
void AdvancedNetworking::abortTextInput(){
s->setCurrentIndex(1);
}
// WifiUI functions
WifiUI::WifiUI(QWidget *parent, int page_length, WifiManager* wifi) : QWidget(parent), networks_per_page(page_length), wifi(wifi) {
vlayout = new QVBoxLayout;
// Scan on startup
QLabel *scanning = new QLabel("Scanning for networks");
scanning->setStyleSheet(R"(font-size: 65px;)");
vlayout->addWidget(scanning, 0, Qt::AlignCenter);
vlayout->setSpacing(25);
setLayout(vlayout);
page = 0;
}
void WifiUI::refresh() {
wifi->request_scan();
wifi->refreshNetworks();
clearLayout(vlayout);
connectButtons = new QButtonGroup(this); // TODO check if this is a leak
QObject::connect(connectButtons, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(handleButton(QAbstractButton*)));
int i = 0;
int countWidgets = 0;
int button_height = static_cast<int>(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) {
// SSID
hlayout->addSpacing(50);
QString ssid = QString::fromUtf8(network.ssid);
if(ssid.length() > 20){
ssid = ssid.left(20)+"";
}
hlayout->addWidget(new QLabel(ssid));
// 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);
// connect button
QPushButton* btn = new QPushButton(network.connected == ConnectedType::CONNECTED ? "Connected" : (network.connected == ConnectedType::CONNECTING ? "Connecting" : "Connect"));
btn->setFixedWidth(350);
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);
connectButtons->addButton(btn, i);
QWidget * w = new QWidget;
w->setLayout(hlayout);
vlayout->addWidget(w);
// Don't add the last line
if (page * networks_per_page <= i+1 && i+1 < (page + 1) * networks_per_page && i+1 < wifi->seen_networks.size()) {
vlayout->addWidget(hline(this));
}
countWidgets++;
}
i++;
}
// 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;
vlayout->addWidget(w);
}
QHBoxLayout *prev_next_buttons = new QHBoxLayout;//Adding constructor exposes the qt bug
QPushButton* prev = new QPushButton("Previous");
prev->setEnabled(page);
prev->setFixedSize(400, button_height);
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);
}
void WifiUI::handleButton(QAbstractButton* button) {
QPushButton* btn = static_cast<QPushButton*>(button);
Network n = wifi->seen_networks[connectButtons->id(btn)];
emit connectToNetwork(n);
}
void WifiUI::prevPage() {
page--;
refresh();
}
void WifiUI::nextPage() {
page++;
refresh();
}