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.
		
		
		
		
		
			
		
			
				
					
					
						
							258 lines
						
					
					
						
							7.0 KiB
						
					
					
				
			
		
		
	
	
							258 lines
						
					
					
						
							7.0 KiB
						
					
					
				#include <QDebug>
 | 
						|
#include <QHBoxLayout>
 | 
						|
#include <QLabel>
 | 
						|
#include <QPixmap>
 | 
						|
#include <QPushButton>
 | 
						|
#include <QLineEdit>
 | 
						|
 | 
						|
#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;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
WifiUI::WifiUI(QWidget *parent, int page_length) : QWidget(parent), networks_per_page(page_length) {
 | 
						|
  try {
 | 
						|
    wifi = new WifiManager;
 | 
						|
  } catch (std::exception &e) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  QObject::connect(wifi, SIGNAL(wrongPassword(QString)), this, SLOT(wrongPassword(QString)));
 | 
						|
 | 
						|
  QVBoxLayout * top_layout = new QVBoxLayout;
 | 
						|
  top_layout->setSpacing(0);
 | 
						|
  swidget = new QStackedWidget;
 | 
						|
 | 
						|
  // Networks page
 | 
						|
  wifi_widget = new QWidget;
 | 
						|
  QVBoxLayout* networkLayout = new QVBoxLayout;
 | 
						|
  QHBoxLayout *tethering_field = new QHBoxLayout;
 | 
						|
  tethering_field->addWidget(new QLabel("Enable Tethering"));
 | 
						|
 | 
						|
  Toggle* toggle_switch = new Toggle(this);
 | 
						|
  toggle_switch->setFixedSize(150, 100);
 | 
						|
  tethering_field->addWidget(toggle_switch);
 | 
						|
  if (wifi->tetheringEnabled()) {
 | 
						|
    toggle_switch->togglePosition();
 | 
						|
  }
 | 
						|
  QObject::connect(toggle_switch, SIGNAL(stateChanged(int)), this, SLOT(toggleTethering(int)));
 | 
						|
 | 
						|
  QWidget* tetheringWidget = new QWidget;
 | 
						|
  tetheringWidget->setLayout(tethering_field);
 | 
						|
  tetheringWidget->setFixedHeight(150);
 | 
						|
  networkLayout->addWidget(tetheringWidget);
 | 
						|
 | 
						|
 | 
						|
  vlayout = new QVBoxLayout;
 | 
						|
  wifi_widget->setLayout(vlayout);
 | 
						|
  networkLayout->addWidget(wifi_widget);
 | 
						|
 | 
						|
  QWidget* networkWidget = new QWidget;
 | 
						|
  networkWidget->setLayout(networkLayout);
 | 
						|
  swidget->addWidget(networkWidget);
 | 
						|
 | 
						|
  // Keyboard page
 | 
						|
  input_field = new InputField();
 | 
						|
  QObject::connect(input_field, SIGNAL(emitText(QString)), this, SLOT(receiveText(QString)));
 | 
						|
  swidget->addWidget(input_field);
 | 
						|
  swidget->setCurrentIndex(0);
 | 
						|
 | 
						|
  top_layout->addWidget(swidget);
 | 
						|
  setLayout(top_layout);
 | 
						|
 | 
						|
  // Update network list
 | 
						|
  timer = new QTimer(this);
 | 
						|
  QObject::connect(timer, SIGNAL(timeout()), this, SLOT(refresh()));
 | 
						|
  timer->start(2000);
 | 
						|
 | 
						|
  // 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);
 | 
						|
 | 
						|
  wifi->request_scan();
 | 
						|
  refresh();
 | 
						|
  page = 0;
 | 
						|
}
 | 
						|
 | 
						|
void WifiUI::refresh() {
 | 
						|
  if (!this->isVisible()) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  wifi->request_scan();
 | 
						|
  wifi->refreshNetworks();
 | 
						|
 | 
						|
  clearLayout(vlayout);
 | 
						|
 | 
						|
  connectButtons = new QButtonGroup(this);
 | 
						|
  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);
 | 
						|
      hlayout->addWidget(new QLabel(QString::fromUtf8(network.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(300);
 | 
						|
      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);
 | 
						|
      w->setStyleSheet(R"(
 | 
						|
        QLabel {
 | 
						|
          font-size: 50px;
 | 
						|
        }
 | 
						|
        QPushButton {
 | 
						|
          padding: 0;
 | 
						|
          font-size: 50px;
 | 
						|
          background-color: #114265;
 | 
						|
        }
 | 
						|
        QPushButton:disabled {
 | 
						|
          background-color: #323C43;
 | 
						|
        }
 | 
						|
        * {
 | 
						|
          background-color: #114265;
 | 
						|
        }
 | 
						|
      )");
 | 
						|
      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;
 | 
						|
  QPushButton* prev = new QPushButton("Previous");
 | 
						|
  prev->setEnabled(page);
 | 
						|
  prev->setFixedHeight(button_height);
 | 
						|
  QPushButton* next = new QPushButton("Next");
 | 
						|
  next->setFixedHeight(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);
 | 
						|
  w->setStyleSheet(R"(
 | 
						|
    QPushButton {
 | 
						|
      padding: 0;
 | 
						|
      background-color: #114265;
 | 
						|
    }
 | 
						|
    QPushButton:disabled {
 | 
						|
      background-color: #323C43;
 | 
						|
    }
 | 
						|
    * {
 | 
						|
      background-color: #114265;
 | 
						|
    }
 | 
						|
  )");
 | 
						|
  vlayout->addWidget(w);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
void WifiUI::toggleTethering(int enable) {
 | 
						|
  if (enable) {
 | 
						|
    wifi->enableTethering();
 | 
						|
  } else {
 | 
						|
    wifi->disableTethering();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void WifiUI::handleButton(QAbstractButton* button) {
 | 
						|
  QPushButton* btn = static_cast<QPushButton*>(button);
 | 
						|
  Network n = wifi->seen_networks[connectButtons->id(btn)];
 | 
						|
  connectToNetwork(n);
 | 
						|
}
 | 
						|
 | 
						|
void WifiUI::connectToNetwork(Network n) {
 | 
						|
  timer->stop();
 | 
						|
  if (n.security_type == SecurityType::OPEN) {
 | 
						|
    wifi->connect(n);
 | 
						|
  } else if (n.security_type == SecurityType::WPA) {
 | 
						|
    input_field->setPromptText("Enter password for \"" + n.ssid + "\"");
 | 
						|
    QString password = getStringFromUser();
 | 
						|
    if (password.size()) {
 | 
						|
      wifi->connect(n, password);
 | 
						|
    }
 | 
						|
  }
 | 
						|
  refresh();
 | 
						|
  timer->start();
 | 
						|
}
 | 
						|
 | 
						|
QString WifiUI::getStringFromUser() {
 | 
						|
  emit openKeyboard();
 | 
						|
  swidget->setCurrentIndex(1);
 | 
						|
  loop.exec();
 | 
						|
  emit closeKeyboard();
 | 
						|
  swidget->setCurrentIndex(0);
 | 
						|
  return text;
 | 
						|
}
 | 
						|
 | 
						|
void WifiUI::receiveText(QString t) {
 | 
						|
  loop.quit();
 | 
						|
  text = t;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void WifiUI::wrongPassword(QString ssid) {
 | 
						|
  if (loop.isRunning()) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
  for (Network n : wifi->seen_networks) {
 | 
						|
    if (n.ssid == ssid) {
 | 
						|
      input_field->setPromptText("Wrong password for \"" + n.ssid +"\"");
 | 
						|
      connectToNetwork(n);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
void WifiUI::prevPage() {
 | 
						|
  page--;
 | 
						|
  refresh();
 | 
						|
}
 | 
						|
void WifiUI::nextPage() {
 | 
						|
  page++;
 | 
						|
  refresh();
 | 
						|
}
 | 
						|
 |