diff --git a/inkbox.pro b/inkbox.pro index 0b7c70d..a0c19d7 100644 --- a/inkbox.pro +++ b/inkbox.pro @@ -32,6 +32,9 @@ SOURCES += \ src/apps/calendarapp.cpp \ src/widgets/dialogs/reader/highlightslistdialog.cpp \ src/widgets/dialogs/reader/textdialog.cpp \ + src/widgets/dialogs/wifi/connectiondialog.cpp \ + src/widgets/dialogs/wifi/network.cpp \ + src/widgets/dialogs/wifi/wifilogger.cpp \ src/widgets/reader/dictionarywidget.cpp \ src/encfs/encryptionmanager.cpp \ src/widgets/dialogs/generaldialog.cpp \ @@ -72,6 +75,9 @@ HEADERS += \ src/apps/calendarapp.h \ src/widgets/dialogs/reader/highlightslistdialog.h \ src/widgets/dialogs/reader/textdialog.h \ + src/widgets/dialogs/wifi/connectiondialog.h \ + src/widgets/dialogs/wifi/network.h \ + src/widgets/dialogs/wifi/wifilogger.h \ src/widgets/reader/dictionarywidget.h \ src/encfs/encryptionmanager.h \ src/functions.h \ @@ -112,6 +118,9 @@ FORMS += \ src/apps/calendarapp.ui \ src/widgets/dialogs/reader/highlightslistdialog.ui \ src/widgets/dialogs/reader/textdialog.ui \ + src/widgets/dialogs/wifi/connectiondialog.ui \ + src/widgets/dialogs/wifi/network.ui \ + src/widgets/dialogs/wifi/wifilogger.ui \ src/widgets/reader/dictionarywidget.ui \ src/encfs/encryptionmanager.ui \ src/widgets/dialogs/generaldialog.ui \ diff --git a/src/functions.h b/src/functions.h index 81e7e26..818507e 100644 --- a/src/functions.h +++ b/src/functions.h @@ -1119,6 +1119,23 @@ namespace { } return exitCode; } + bool checkProcessName(QString name) { + QDirIterator appsDir("/proc", QDirIterator::NoIteratorFlags); + while (appsDir.hasNext()) { + QDir dir(appsDir.next()); + QFile process = QFile(dir.path() + "/cmdline"); + if(process.exists() == true) { + process.open(QIODevice::ReadOnly); + QTextStream stream(&process); + if(stream.readLine().contains(name) == true) { + process.close(); + return true; + } + process.close(); + } + } + return false; + } } #endif // FUNCTIONS_H diff --git a/src/widgets/dialogs/generaldialog.cpp b/src/widgets/dialogs/generaldialog.cpp index b60536e..2d01897 100644 --- a/src/widgets/dialogs/generaldialog.cpp +++ b/src/widgets/dialogs/generaldialog.cpp @@ -499,6 +499,9 @@ void generalDialog::on_okBtn_clicked() global::toast::delay = 3000; showToast("Minimum password length is 8 characters"); } + else { + generalDialog::close(); + } } else { global::toast::delay = 3000; @@ -591,6 +594,7 @@ void generalDialog::restartSearchDialog() { } void generalDialog::setupKeyboardDialog() { + adjust_size(); ui->stackedWidget->setCurrentIndex(0); keyboardDialog = true; ui->stackedWidget->setVisible(true); @@ -607,7 +611,7 @@ void generalDialog::setupKeyboardDialog() { } else if(global::keyboard::wifiPassphraseDialog == true) { ui->headerLabel->setText("Enter the network's passphrase"); - ui->okBtn->setText("Connect"); + ui->okBtn->setText("Enter"); ui->cancelBtn->setText("Cancel"); } else if(global::keyboard::encfsDialog == true) { @@ -624,6 +628,7 @@ void generalDialog::setupKeyboardDialog() { connect(keyboardWidget, SIGNAL(adjust_size()), SLOT(adjust_size())); ui->mainStackedWidget->insertWidget(1, keyboardWidget); ui->mainStackedWidget->setCurrentIndex(1); + adjust_size(); QTimer::singleShot(1000, this, SLOT(adjust_size())); } diff --git a/src/widgets/dialogs/wifi/connectiondialog.cpp b/src/widgets/dialogs/wifi/connectiondialog.cpp index d4d990c..0c04018 100644 --- a/src/widgets/dialogs/wifi/connectiondialog.cpp +++ b/src/widgets/dialogs/wifi/connectiondialog.cpp @@ -4,6 +4,7 @@ #include "connectiondialog.h" #include "ui_connectiondialog.h" #include "generaldialog.h" +#include "functions.h" connectiondialog::connectiondialog(QWidget *parent) : QDialog(parent), @@ -34,6 +35,7 @@ connectiondialog::~connectiondialog() } void connectiondialog::applyVariables() { + // Here for some devices it will be propably needed to limit the size. the nia is fine ui->nameLabel->setText(connectedNetworkData.name); ui->macLabel->setText(connectedNetworkData.mac); ui->signalLabel->setText(QString::number(connectedNetworkData.signal) + "%"); @@ -62,11 +64,16 @@ void connectiondialog::applyVariables() { QString password = searchDatabase(connectedNetworkData.name); if(password.isEmpty() == false) { log("found password: " + password, className); - ui->passwordTextEdit->setText(password); + ui->showPasswordBtn->setIcon(QIcon("://resources/show.png")); + showedPasword = false; + savedPassword = password; + + ui->passwordTextEdit->setText("********"); } else { log("No password found", className); - ui->passwordTextEdit->setText("No password found"); + ui->passwordTextEdit->setText("No password was saved"); + ui->showPasswordBtn->hide(); } } } @@ -97,6 +104,10 @@ QString connectiondialog::searchDatabase(QString key) { } void connectiondialog::writeToDatabase(QString name, QString password) { + if(searchDatabase(name).isEmpty() == false) { + removeFromDatabase(name); + } + passwordDatabase.open(QIODevice::ReadOnly | QIODevice::Text); QString fileRead = passwordDatabase.readAll(); passwordDatabase.close(); @@ -126,6 +137,45 @@ void connectiondialog::writeToDatabase(QString name, QString password) { } } +void connectiondialog::removeFromDatabase(QString name) { + passwordDatabase.open(QIODevice::ReadOnly | QIODevice::Text); + QString fileRead = passwordDatabase.readAll(); + passwordDatabase.close(); + QJsonDocument jsonDocument = QJsonDocument::fromJson(fileRead.toUtf8()); + + int counter = 0; + bool remove = false; + if(jsonDocument["list"].isArray() == true) { + QJsonArray jsonArray = jsonDocument["list"].toArray(); + for(QJsonValueRef refJsonObject: jsonArray) { + QJsonObject jsonMainObject = refJsonObject.toObject(); + QString searchedName = jsonMainObject.keys().first().toUtf8(); + log("Found in database: " + searchedName, className); + if(searchedName == name) { + remove = true; + } + if(remove == false) { + counter = counter + 1; + } + } + if(remove == true) { + jsonArray.removeAt(counter); + QJsonDocument newJsonDocument; + QJsonObject root; + root["list"] = jsonArray; + newJsonDocument.setObject(root); + + passwordDatabase.open(QFile::WriteOnly | QFile::Text | QFile::Truncate); + passwordDatabase.write(newJsonDocument.toJson()); + passwordDatabase.flush(); + passwordDatabase.close(); + } + else { + log("ERROR: tryied to remove from database, but couldn't find key", className); + } + } +} + void connectiondialog::on_CancelBtn_clicked() { this->deleteLater(); @@ -137,33 +187,125 @@ void connectiondialog::on_passwordTextEdit_selectionChanged() ui->passwordTextEdit->setSelection(0, 0); } -void connectiondialog::on_passwordTextEdit_cursorPositionChanged(int arg1, int arg2) +void connectiondialog::on_passwordTextEdit_cursorPositionChanged(int oldpos, int newpos) { - log("detected click on textedit"); + log("detected click on text edit", className); if(cursorPositionIgnore == true) { - global::keyboard::keyboardDialog = true; - global::keyboard::wifiPassphraseDialog = true; - global::keyboard::keyboardText = ""; - generalDialog* generalDialogWindow = new generalDialog(); - generalDialogWindow->setAttribute(Qt::WA_DeleteOnClose); - generalDialogWindow->wifiEssid = connectedNetworkData.name; - connect(generalDialogWindow, &generalDialog::showToast, this, &connectiondialog::showToastSlot); - generalDialogWindow->exec(); + if(newpos != 0) { + if(showedPasword == true) { + ui->passwordTextEdit->setCursorPosition(0); + global::keyboard::keyboardDialog = true; + global::keyboard::wifiPassphraseDialog = true; + global::keyboard::keyboardText = ""; + generalDialog* generalDialogWindow = new generalDialog(); + generalDialogWindow->setAttribute(Qt::WA_DeleteOnClose); + generalDialogWindow->wifiEssid = connectedNetworkData.name; + connect(generalDialogWindow, &generalDialog::showToast, this, &connectiondialog::showToastSlot); + connect(generalDialogWindow, &generalDialog::refreshScreen, this, &connectiondialog::refreshScreenSlot); - global::keyboard::keyboardDialog = false; - global::keyboard::wifiPassphraseDialog = false; - if(global::keyboard::keyboardText.isEmpty() == false) { - ui->passwordTextEdit->setText(global::keyboard::keyboardText); + generalDialogWindow->exec(); + + global::keyboard::keyboardDialog = false; + global::keyboard::wifiPassphraseDialog = false; + if(global::keyboard::keyboardText.isEmpty() == false) { + // A bit hacky: avoid summoning the keyboard back when the text is changing ( and the cursor too ) showedPasword shouldnt be used for this, but it works and adding another bool would start being messy + showedPasword = false; + ui->passwordTextEdit->setText(global::keyboard::keyboardText); + ui->showPasswordBtn->setIcon(QIcon("://resources/hide.png")); + ui->showPasswordBtn->show(); + showedPasword = true; + savedPassword = global::keyboard::keyboardText; + } + global::keyboard::keyboardText = ""; + } } - global::keyboard::keyboardText = ""; - } else { + log("Ignoring click on text edit", className); cursorPositionIgnore = true; } - ui->passwordTextEdit->setCursorPosition(0); } void connectiondialog::showToastSlot(QString message) { emit showToastSignal(message); } + +void connectiondialog::on_showPasswordBtn_clicked() +{ + if(showedPasword == false) { + ui->showPasswordBtn->setIcon(QIcon("://resources/hide.png")); + ui->passwordTextEdit->setText(savedPassword); + showedPasword = true; + } + else { + showedPasword = false; + ui->showPasswordBtn->setIcon(QIcon("://resources/show.png")); + ui->passwordTextEdit->setText("********"); + } +} + +void connectiondialog::refreshScreenSlot() { + this->repaint(); + emit refreshScreenSignal(); +} + +void connectiondialog::on_connectBtn_clicked() +{ + QString finalPassword; + if(connectedNetworkData.encryption == false) { + finalPassword = "NONE"; + } + else { + finalPassword = savedPassword; + writeToDatabase(connectedNetworkData.name, savedPassword); + } + + ui->CancelBtn->setEnabled(false); + if(checkWifiState() == global::wifi::WifiState::Configured) { + string_writeconfig("/opt/ibxd", "stop_wifi_operations\n"); + } + string_writeconfig("/run/wifi_network_essid", connectedNetworkData.name.toStdString()); + string_writeconfig("/run/wifi_network_passphrase", finalPassword.toStdString()); + setDefaultWorkDir(); + // this will be deleited later in mainwindow icon updater if it failed + string_writeconfig(".config/17-wifi_connection_information/essid", connectedNetworkData.name.toStdString()); + string_writeconfig(".config/17-wifi_connection_information/passphrase", finalPassword.toStdString()); + finalConnectWait(); + +} + +void connectiondialog::finalConnectWait() { + if(checkIfWifiBussy() == true) { + // To be sure + if(waitTry == 10) { + string_writeconfig("/opt/ibxd", "stop_wifi_operations\n"); + } + // Max 10s to wait for everything to shut down + if(waitTry == 20) { + string_writeconfig("/opt/ibxd", "stop_wifi_operations\n"); + emit showToastSignal("Failed to stop other wifi processes"); + ui->CancelBtn->setEnabled(true); + } + else { + QTimer::singleShot(500, this, SLOT(finalConnectWait())); + waitTry = waitTry + 1; + } + } + else { + string_writeconfig("/opt/ibxd", "connect_to_wifi_network\n"); + ui->CancelBtn->setEnabled(true); + this->deleteLater(); + this->close(); + } +} + +bool connectiondialog::checkIfWifiBussy() { + if(checkProcessName("connect_to_network.sh") == true or + checkProcessName("connection_manager.sh") == true or + checkProcessName("only_connect_to_network.sh") == true) { + return true; + } + else { + return false; + } +} diff --git a/src/widgets/dialogs/wifi/connectiondialog.h b/src/widgets/dialogs/wifi/connectiondialog.h index a5a9ec9..df6cc03 100644 --- a/src/widgets/dialogs/wifi/connectiondialog.h +++ b/src/widgets/dialogs/wifi/connectiondialog.h @@ -22,24 +22,41 @@ public: signals: void showToastSignal(QString message); + void refreshScreenSignal(); public slots: void applyVariables(); void showToastSlot(QString message); + void refreshScreenSlot(); private slots: - void on_CancelBtn_clicked(); + // I know im opening / loading json many times, its maybe not efficient but: + // 1. its modular + // 2. those operations are rare QString searchDatabase(QString key); void writeToDatabase(QString name, QString password); + void removeFromDatabase(QString name); + void finalConnectWait(); + bool checkIfWifiBussy(); + + void on_CancelBtn_clicked(); + void on_passwordTextEdit_selectionChanged(); void on_passwordTextEdit_cursorPositionChanged(int arg1, int arg2); + void on_showPasswordBtn_clicked(); + + void on_connectBtn_clicked(); + private: Ui::connectiondialog *ui; bool cursorPositionIgnore = false; + bool showedPasword; + QString savedPassword; + int waitTry = 0; }; #endif // CONNECTIONDIALOG_H diff --git a/src/widgets/dialogs/wifi/network.cpp b/src/widgets/dialogs/wifi/network.cpp index c2c693f..b3e2f71 100644 --- a/src/widgets/dialogs/wifi/network.cpp +++ b/src/widgets/dialogs/wifi/network.cpp @@ -71,6 +71,7 @@ void network::on_enterButton_clicked() newConnectionDiallog->currentlyConnectedNetworkName = currentlyConnectedNetwork; newConnectionDiallog->applyVariables(); connect(newConnectionDiallog, &connectiondialog::showToastSignal, this, &network::showToastSlot); + connect(newConnectionDiallog, &connectiondialog::refreshScreenSignal, this, &network::refreshScreenSlot); newConnectionDiallog->exec(); } @@ -82,3 +83,7 @@ void network::closeWrapper() { void network::showToastSlot(QString message) { emit showToastSignal(message); } + +void network::refreshScreenSlot() { + emit refreshScreenSignal(); +} diff --git a/src/widgets/dialogs/wifi/network.h b/src/widgets/dialogs/wifi/network.h index 294c307..2649b0d 100644 --- a/src/widgets/dialogs/wifi/network.h +++ b/src/widgets/dialogs/wifi/network.h @@ -22,11 +22,13 @@ public: signals: void showToastSignal(QString message); + void refreshScreenSignal(); public slots: void applyVariables(); void closeWrapper(); void showToastSlot(QString message); + void refreshScreenSlot(); private slots: void on_enterButton_clicked(); diff --git a/src/widgets/dialogs/wifi/wifidialog.cpp b/src/widgets/dialogs/wifi/wifidialog.cpp index 9c3ed32..3d3b9c1 100644 --- a/src/widgets/dialogs/wifi/wifidialog.cpp +++ b/src/widgets/dialogs/wifi/wifidialog.cpp @@ -65,6 +65,7 @@ wifiDialog::wifiDialog(QWidget *parent) : wifiButtonEnabled = true; } + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); } wifiDialog::~wifiDialog() @@ -280,6 +281,7 @@ void wifiDialog::refreshNetworksList() { connectedNetwork->applyVariables(); connect(this, &wifiDialog::killNetworkWidgets, connectedNetwork, &network::closeWrapper); connect(connectedNetwork, &network::showToastSignal, this, &wifiDialog::showToastSlot); + connect(connectedNetwork, &network::refreshScreenSignal, this, &wifiDialog::refreshScreenSlot); ui->scrollBarLayout->addWidget(connectedNetwork, Qt::AlignTop); } countVec = countVec + 1; @@ -330,6 +332,7 @@ void wifiDialog::refreshNetworksList() { connectedNetwork->applyVariables(); connect(this, &wifiDialog::killNetworkWidgets, connectedNetwork, &network::closeWrapper); connect(connectedNetwork, &network::showToastSignal, this, &wifiDialog::showToastSlot); + connect(connectedNetwork, &network::refreshScreenSignal, this, &wifiDialog::refreshScreenSlot); ui->scrollBarLayout->addWidget(connectedNetwork, Qt::AlignTop); } scannedAtLeastOnce = true; @@ -381,3 +384,100 @@ void wifiDialog::on_logBtn_clicked() void wifiDialog::showToastSlot(QString message) { emit showToast(message); } + +void wifiDialog::refreshScreenSlot() { + this->repaint(); +} + +/* +Some documentation used by the watcher +connection_manager.sh - manages all things, launches other processes +connect_to_network.sh - all in one connection manager. manages everything, used by ipd, should be used for recconections after sleeping / booting +get_dhcp.sh - Gets dhcp addresses +prepare_changing_wifi.sh - Kills everything, prepares to changing network +smarter_time_sync.sh - synces time +toggle.sh - turns on / off +list_networks.bin - well lists networks +the watcher first watches at processes that could kill other ones +*/ + +void wifiDialog::theWatcher() { + + bool killing = checkProcessName("toggle.sh"); + bool changing = checkProcessName("prepare_changing_wifi.sh"); + if(killing == true) { + setStatusText("Changing wifi state"); + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); + return void(); + } + + if(changing == true) { + setStatusText("Disconnecting from a network or cleaning"); + forceRefresh = true; + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); + return void(); + } + + bool recconection = checkProcessName("connect_to_network.sh"); + if(recconection == true) { + forceRefresh = true; + QFile recName = QFile(".config/17-wifi_connection_information/essid"); + if(recName.exists() == true) { + setStatusText("Recconecting after suspending to " + readFile(recName.fileName()).replace("\n", "")); + } + else { + // Shouldn't be possible + setStatusText("Recconecting after sleep, but no network found?"); + } + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); + return void(); + } + + bool listing = checkProcessName("list_networks.bin"); + if(listing == true) { + setStatusText("Scanning networks..."); + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); + return void(); + } + + bool time = checkProcessName("smarter_time_sync.sh"); + if(time == true) { + forceRefresh = true; + setStatusText("Syncing time"); + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); + return void(); + } + + bool dhcp = checkProcessName("get_dhcp.sh"); + if(dhcp == true) { + forceRefresh = true; + setStatusText("Getting IP address"); + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); + return void(); + } + + bool connecting = checkProcessName("connect_to_network.sh"); + if(connecting == true) { + forceRefresh = true; + setStatusText("Connecting to wifi..."); + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); + return void(); + } + + setStatusText("Idling"); + if(forceRefresh == true) { + forceRefresh = false; + ui->refreshBtn->click(); + } + QTimer::singleShot(relaunchMs, this, SLOT(theWatcher())); +} + +void wifiDialog::setStatusText(QString message) { + ui->statusLabel->setText(message); +} + +void wifiDialog::on_stopBtn_clicked() +{ + // Maybe limit this, idk + string_writeconfig("/opt/ibxd", "stop_wifi_operations\n"); +} diff --git a/src/widgets/dialogs/wifi/wifidialog.h b/src/widgets/dialogs/wifi/wifidialog.h index 348e8d7..4d21f99 100644 --- a/src/widgets/dialogs/wifi/wifidialog.h +++ b/src/widgets/dialogs/wifi/wifidialog.h @@ -33,10 +33,18 @@ private: QFile fullList = QFile("/external_root/run/wifi_list_full"); QFile formattedList = QFile("/external_root/run/wifi_list_format"); + // Used by watcher + bool forceRefresh = false; + int relaunchMs = 300; + public slots: void launchRefresh(); void refreshNetworksList(); void showToastSlot(QString message); + void refreshScreenSlot(); + + // Shows status of wifi processes, like recconection and others. Also manages refreshing the network list after connection + void theWatcher(); signals: void refreshScreen(); @@ -53,6 +61,8 @@ private slots: void on_logBtn_clicked(); // This function is a more clever sleep(1), non blocking void refreshWait(); + void setStatusText(QString message); + void on_stopBtn_clicked(); }; #endif // WIFIDIALOG_H