From 95c7f91fe9d993f13e3fa96ee935e4665d1541b8 Mon Sep 17 00:00:00 2001
From: "A. Wilcox" <AWilcox@Wilcox-Tech.com>
Date: Sat, 23 May 2020 17:22:22 -0500
Subject: Qt UI: Implement custom Wi-Fi network support

---
 ui/qt5/CMakeLists.txt       |  1 +
 ui/qt5/customwifidialog.cc  | 89 +++++++++++++++++++++++++++++++++++++++++++++
 ui/qt5/customwifidialog.hh  | 40 ++++++++++++++++++++
 ui/qt5/netsimplewifipage.cc | 29 +++++++++++++--
 4 files changed, 156 insertions(+), 3 deletions(-)
 create mode 100644 ui/qt5/customwifidialog.cc
 create mode 100644 ui/qt5/customwifidialog.hh

(limited to 'ui')

diff --git a/ui/qt5/CMakeLists.txt b/ui/qt5/CMakeLists.txt
index 934cd70..d277a7a 100644
--- a/ui/qt5/CMakeLists.txt
+++ b/ui/qt5/CMakeLists.txt
@@ -9,6 +9,7 @@ set(UI_SOURCES
     ${CMAKE_SOURCE_DIR}/3rdparty/Section.cpp
     stepprogresswidget.cc
     subnetbox.cc
+    customwifidialog.cc
     mountdialog.cc
     useraccountwidget.cc
     avatardialog.cc
diff --git a/ui/qt5/customwifidialog.cc b/ui/qt5/customwifidialog.cc
new file mode 100644
index 0000000..1d50eeb
--- /dev/null
+++ b/ui/qt5/customwifidialog.cc
@@ -0,0 +1,89 @@
+/*
+ * customwifidialog.cc - Implementation of a dialog for entering a custom AP
+ * horizon-qt5, the Qt 5 user interface for
+ * Project Horizon
+ *
+ * Copyright (c) 2020 Adélie Linux and contributors.  All rights reserved.
+ * This code is licensed under the AGPL 3.0 license, as noted in the
+ * LICENSE-code file in the root directory of this repository.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+#include "customwifidialog.hh"
+
+#include <QFormLayout>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QVBoxLayout>
+
+CustomWiFiDialog::CustomWiFiDialog(QWidget *parent)
+    : QDialog(parent, Qt::WindowTitleHint | Qt::WindowCloseButtonHint) {
+    setWindowTitle(tr("Add Wireless Network"));
+
+    ok = new QPushButton(tr("Confirm"));
+    ok->setEnabled(false);
+    connect(ok, &QPushButton::clicked, this, &QDialog::accept);
+    QPushButton *cancel = new QPushButton(tr("Cancel"));
+    connect(cancel, &QPushButton::clicked, this, &QDialog::reject);
+
+    QHBoxLayout *buttonLayout = new QHBoxLayout;
+    buttonLayout->addWidget(ok, 0, Qt::AlignCenter);
+    buttonLayout->addWidget(cancel, 0, Qt::AlignCenter);
+
+    networkInput = new QLineEdit;
+    networkInput->setWhatsThis(tr("The SSID of the network."));
+    connect(networkInput, &QLineEdit::textChanged,
+            this, &CustomWiFiDialog::ensureButton);
+
+    /*: No security; open network */
+    securityNone = new QRadioButton(tr("None"));
+    securityWEP = new QRadioButton(tr("WEP"));
+    securityWPA = new QRadioButton(tr("WPA/WPA2 Personal"));
+    securityGroup = new QButtonGroup;
+    securityGroup->setExclusive(true);
+    securityGroup->addButton(securityNone, 0);
+    securityGroup->addButton(securityWEP, 1);
+    securityGroup->addButton(securityWPA, 2);
+    connect(securityGroup,
+            QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
+            this, &CustomWiFiDialog::ensureButton);
+
+    QHBoxLayout *radioLayout = new QHBoxLayout;
+    radioLayout->addWidget(securityNone, 0, Qt::AlignCenter);
+    radioLayout->addWidget(securityWEP,  0, Qt::AlignCenter);
+    radioLayout->addWidget(securityWPA,  0, Qt::AlignCenter);
+
+    QFormLayout *controlLayout = new QFormLayout;
+    controlLayout->addRow(new QLabel(tr("Network Name:")), networkInput);
+    controlLayout->addRow(new QLabel(tr("Security Type:")), radioLayout);
+
+    QVBoxLayout *mainBox = new QVBoxLayout;
+    mainBox->addLayout(controlLayout);
+    mainBox->addLayout(buttonLayout);
+
+    setLayout(mainBox);
+}
+
+QString CustomWiFiDialog::networkName() const {
+    return networkInput->text();
+}
+
+void CustomWiFiDialog::setNetworkName(const QString &network) {
+    networkInput->setText(network);
+}
+
+QStringList CustomWiFiDialog::flags() const {
+    switch(securityGroup->checkedId()) {
+    default:
+        return {};
+    case 1:
+        return {"WEP"};
+    case 2:
+        return {"WPA-PSK"};
+    }
+}
+
+void CustomWiFiDialog::ensureButton() {
+    ok->setEnabled(!networkInput->text().isEmpty() && securityGroup->checkedId() != -1);
+}
diff --git a/ui/qt5/customwifidialog.hh b/ui/qt5/customwifidialog.hh
new file mode 100644
index 0000000..8b2c2d3
--- /dev/null
+++ b/ui/qt5/customwifidialog.hh
@@ -0,0 +1,40 @@
+/*
+ * customwifidialog.hh - Definition of a dialog for entering a custom AP
+ * horizon-qt5, the Qt 5 user interface for
+ * Project Horizon
+ *
+ * Copyright (c) 2019 Adélie Linux and contributors.  All rights reserved.
+ * This code is licensed under the AGPL 3.0 license, as noted in the
+ * LICENSE-code file in the root directory of this repository.
+ *
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+#ifndef CUSTOMWIFIDIALOG_HH
+#define CUSTOMWIFIDIALOG_HH
+
+#include "horizonwizard.hh"
+
+#include <QButtonGroup>
+#include <QDialog>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QRadioButton>
+
+class CustomWiFiDialog : public QDialog {
+public:
+    explicit CustomWiFiDialog(QWidget *parent = nullptr);
+
+    void ensureButton();
+
+    QString networkName() const;
+    void setNetworkName(const QString &network);
+    QStringList flags() const;
+private:
+    QPushButton *ok;
+    QLineEdit *networkInput;
+    QButtonGroup *securityGroup;
+    QRadioButton *securityNone, *securityWEP, *securityWPA;
+};
+
+#endif  /* !CUSTOMWIFIDIALOG_HH */
diff --git a/ui/qt5/netsimplewifipage.cc b/ui/qt5/netsimplewifipage.cc
index 097d893..6d0a1bd 100644
--- a/ui/qt5/netsimplewifipage.cc
+++ b/ui/qt5/netsimplewifipage.cc
@@ -3,7 +3,7 @@
  * horizon-qt5, the Qt 5 user interface for
  * Project Horizon
  *
- * Copyright (c) 2019 Adélie Linux and contributors.  All rights reserved.
+ * Copyright (c) 2019-2020 Adélie Linux and contributors.  All rights reserved.
  * This code is licensed under the AGPL 3.0 license, as noted in the
  * LICENSE-code file in the root directory of this repository.
  *
@@ -11,10 +11,12 @@
  */
 
 #include "netsimplewifipage.hh"
+#include "customwifidialog.hh"
 #include "netdhcppage.hh"
 
 #include <assert.h>
 #include <sstream>
+#include <QHBoxLayout>
 #include <QVBoxLayout>
 
 #ifdef HAS_INSTALL_ENV
@@ -34,6 +36,7 @@ NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent)
 #endif  /* HAS_INSTALL_ENV */
     {
     QVBoxLayout *layout = new QVBoxLayout;
+    QHBoxLayout *buttonLayout = new QHBoxLayout;
 
     loadWatermark("network");
     setTitle(tr("Select Your Network"));
@@ -41,7 +44,24 @@ NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent)
     statusLabel = new QLabel(tr("Scanning for networks..."));
     statusLabel->setWordWrap(true);
 
-    addNetButton = new QPushButton;
+    addNetButton = new QPushButton(tr("&Add Network..."));
+    addNetButton->setIcon(QIcon::fromTheme("list-add"));
+    connect(addNetButton, &QPushButton::clicked, [=] {
+        CustomWiFiDialog d;
+        if(d.exec() == QDialog::Accepted) {
+            QListWidgetItem *netitem = new QListWidgetItem;
+            netitem->setText(d.networkName());
+            netitem->setIcon(QIcon::fromTheme("network-wireless-signal-none"));
+            netitem->setToolTip(tr("Frequency: Unknown"));
+            netitem->setData(Qt::UserRole, d.flags());
+            netitem->setData(Qt::UserRole + 1, 2);
+
+            ssidListView->insertItem(0, netitem);
+        }
+    });
+
+    buttonLayout->addSpacing(10);
+    buttonLayout->addWidget(addNetButton, 0, Qt::AlignCenter);
 
     ssidListView = new QListWidget;
     connect(ssidListView, &QListWidget::currentItemChanged,
@@ -51,6 +71,8 @@ NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent)
     rescanButton = new QPushButton(tr("&Rescan Networks"));
     connect(rescanButton, &QPushButton::clicked, [=](void) { doScan(); });
 
+    buttonLayout->addWidget(rescanButton, 0, Qt::AlignCenter);
+
     exchange_item.filter = "CTRL-EVENT-SCAN-RESULTS";
     exchange_item.cb = &scanResults;
     notify = nullptr;
@@ -58,6 +80,7 @@ NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent)
     dialog = nullptr;
 #endif  /* HAS_INSTALL_ENV */
 
+    buttonLayout->addSpacing(10);
     passphrase = new QLineEdit(this);
     connect(passphrase, &QLineEdit::textChanged,
             this, &NetworkSimpleWirelessPage::completeChanged);
@@ -68,7 +91,7 @@ NetworkSimpleWirelessPage::NetworkSimpleWirelessPage(QWidget *parent)
     layout->addWidget(statusLabel, 0, Qt::AlignCenter);
     layout->addSpacing(10);
     layout->addWidget(ssidListView, 0, Qt::AlignCenter);
-    layout->addWidget(rescanButton, 0, Qt::AlignCenter);
+    layout->addLayout(buttonLayout);
     layout->addSpacing(10);
     layout->addWidget(passphrase, 0, Qt::AlignCenter);
     setLayout(layout);
-- 
cgit v1.2.3-70-g09d2