From 441811e277f3f8e1c157ee19b69c0d7a61e624d8 Mon Sep 17 00:00:00 2001 From: pokamest Date: Sat, 9 Jan 2021 19:55:16 +0300 Subject: [PATCH] Refactoring Ui improvements Bug fixes --- client/core/errorstrings.h | 2 +- client/core/servercontroller.cpp | 4 +- client/localclient.cpp | 2 +- client/main.cpp | 2 + client/protocols/openvpnprotocol.cpp | 9 +- client/protocols/vpnprotocol.cpp | 12 +- client/settings.h | 2 +- client/ui/mainwindow.cpp | 399 +++++++++++++++++++++------ client/ui/mainwindow.h | 52 +++- client/ui/mainwindow.ui | 387 +++++++++++++++++++++++++- client/vpnconnection.cpp | 11 +- client/vpnconnection.h | 2 +- service/server/localserver.cpp | 12 +- 13 files changed, 773 insertions(+), 123 deletions(-) diff --git a/client/core/errorstrings.h b/client/core/errorstrings.h index 0e965912..a19420a5 100644 --- a/client/core/errorstrings.h +++ b/client/core/errorstrings.h @@ -4,7 +4,7 @@ #include "defs.h" using namespace amnezia; -QString errorString(ErrorCode code){ +static QString errorString(ErrorCode code){ switch (code) { // General error codes diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index 78828597..8498ac7b 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -55,7 +55,7 @@ ErrorCode ServerController::runScript(const SshConnectionParameters &sshParams, // QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardOutput, [proc](){ // QString s = proc->readAllStandardOutput(); // if (s != "." && !s.isEmpty()) { -// qDebug().noquote() << s << s.size(); +// qDebug().noquote() << s; // } // }); @@ -239,7 +239,7 @@ ErrorCode ServerController::removeServer(const ServerCredentials &credentials, P { QString scriptFileName; - if (proto == Protocol::OpenVpn) { + if (proto == Protocol::OpenVpn || proto == Protocol::Any) { scriptFileName = ":/server_scripts/remove_openvpn_server.sh"; } diff --git a/client/localclient.cpp b/client/localclient.cpp index e960be73..280f7702 100644 --- a/client/localclient.cpp +++ b/client/localclient.cpp @@ -49,7 +49,7 @@ void LocalClient::onReadyRead() if (lineLength != -1) { QString line = buf; line = line.simplified(); - qDebug().noquote() << QString("Readed line: '%1'").arg(line); + qDebug().noquote() << QString("Read line: '%1'").arg(line); emit lineAvailable(line); } } diff --git a/client/main.cpp b/client/main.cpp index ee6bb3f7..4a66359c 100644 --- a/client/main.cpp +++ b/client/main.cpp @@ -60,6 +60,8 @@ int main(int argc, char *argv[]) f.setStyleStrategy(QFont::PreferAntialias); app.setFont(f); + app.setQuitOnLastWindowClosed(false); + MainWindow mainWindow; mainWindow.show(); diff --git a/client/protocols/openvpnprotocol.cpp b/client/protocols/openvpnprotocol.cpp index 19d25a75..38f8aba5 100644 --- a/client/protocols/openvpnprotocol.cpp +++ b/client/protocols/openvpnprotocol.cpp @@ -45,9 +45,12 @@ void OpenVpnProtocol::onMessageReceived(const Message& message) void OpenVpnProtocol::stop() { + // TODO: need refactoring + // sendTermSignal() will evet return true while server connected if ((m_connectionState == VpnProtocol::ConnectionState::Preparing) || (m_connectionState == VpnProtocol::ConnectionState::Connecting) || - (m_connectionState == VpnProtocol::ConnectionState::Connected)) { + (m_connectionState == VpnProtocol::ConnectionState::Connected) || + (m_connectionState == VpnProtocol::ConnectionState::TunnelReconnecting)) { if (!sendTermSignal()) { killOpenVpnProcess(); } @@ -210,6 +213,9 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer() } else if (line.contains("EXITING,SIGTER")) { openVpnStateSigTermHandler(); continue; + } else if (line.contains("RECONNECTING")) { + setConnectionState(VpnProtocol::ConnectionState::TunnelReconnecting); + continue; } } @@ -222,7 +228,6 @@ void OpenVpnProtocol::onReadyReadDataFromManagementServer() } } - QByteArray data(line.toStdString().c_str()); if (data.contains(">BYTECOUNT:")) { int beg = data.lastIndexOf(">BYTECOUNT:"); diff --git a/client/protocols/vpnprotocol.cpp b/client/protocols/vpnprotocol.cpp index eb81e02f..fc9cbc79 100644 --- a/client/protocols/vpnprotocol.cpp +++ b/client/protocols/vpnprotocol.cpp @@ -3,6 +3,7 @@ #include "communicator.h" #include "vpnprotocol.h" +#include "core/errorstrings.h" Communicator* VpnProtocol::m_communicator = nullptr; @@ -34,7 +35,10 @@ Communicator* VpnProtocol::communicator() void VpnProtocol::setLastError(ErrorCode lastError) { m_lastError = lastError; - qCritical().noquote() << m_lastError; + if (lastError){ + setConnectionState(ConnectionState::Disconnected); + } + qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError); } ErrorCode VpnProtocol::lastError() const @@ -96,10 +100,10 @@ QString VpnProtocol::textConnectionState(ConnectionState connectionState) case ConnectionState::Unknown: return tr("Unknown"); case ConnectionState::Disconnected: return tr("Disconnected"); case ConnectionState::Preparing: return tr("Preparing"); - case ConnectionState::Connecting: return tr("Connecting"); + case ConnectionState::Connecting: return tr("Connecting..."); case ConnectionState::Connected: return tr("Connected"); - case ConnectionState::Disconnecting: return tr("Disconnecting"); - case ConnectionState::TunnelReconnecting: return tr("TunnelReconnecting"); + case ConnectionState::Disconnecting: return tr("Disconnecting..."); + case ConnectionState::TunnelReconnecting: return tr("Reconnecting..."); case ConnectionState::Error: return tr("Error"); default: ; diff --git a/client/settings.h b/client/settings.h index 14a7aa6a..13177e30 100644 --- a/client/settings.h +++ b/client/settings.h @@ -23,7 +23,7 @@ public: void setUserName(const QString& login); void setPassword(const QString& password); void setServerName(const QString& serverName); - void setServerPort(int serverPort); + void setServerPort(int serverPort = 22); void setServerCredentials(const ServerCredentials &credentials); QString userName() const { return m_userName; } diff --git a/client/ui/mainwindow.cpp b/client/ui/mainwindow.cpp index a4deede9..6e8b4599 100644 --- a/client/ui/mainwindow.cpp +++ b/client/ui/mainwindow.cpp @@ -1,5 +1,9 @@ +#include +#include #include +#include #include +#include #include #include #include @@ -38,10 +42,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->stackedWidget_main->setSpeed(200); ui->stackedWidget_main->setAnimation(QEasingCurve::Linear); - ui->label_new_server_wait_info->setVisible(false); - ui->progressBar_new_server_connection->setMinimum(0); - ui->progressBar_new_server_connection->setMaximum(300); - + ui->pushButton_blocked_list->setEnabled(false); + ui->pushButton_share_connection->setEnabled(false); #ifdef Q_OS_MAC ui->widget_tittlebar->hide(); ui->stackedWidget_main->move(0,0); @@ -51,20 +53,13 @@ MainWindow::MainWindow(QWidget *parent) : // Post initialization if (m_settings->haveAuthData()) { - ui->stackedWidget_main->setCurrentWidget(ui->page_amnezia); + goToPage(Page::Vpn, true, false); } else { - ui->stackedWidget_main->setCurrentWidget(ui->page_new_server); + goToPage(Page::Start, true, false); } - connect(ui->pushButton_blocked_list, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBlockedListClicked(bool))); - connect(ui->pushButton_connect, SIGNAL(toggled(bool)), this, SLOT(onPushButtonConnectToggled(bool))); - connect(ui->pushButton_settings, SIGNAL(clicked(bool)), this, SLOT(onPushButtonSettingsClicked(bool))); - - connect(ui->pushButton_back_from_sites, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBackFromSitesClicked(bool))); - connect(ui->pushButton_back_from_settings, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBackFromSettingsClicked(bool))); - connect(ui->pushButton_new_server_setup, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerSetup(bool))); - connect(ui->pushButton_back_from_new_server, SIGNAL(clicked(bool)), this, SLOT(onPushButtonBackFromNewServerClicked(bool))); - connect(ui->pushButton_new_server_connect_with_new_data, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnectWithNewData(bool))); + setupTray(); + setupUiConnections(); setFixedSize(width(),height()); @@ -102,11 +97,48 @@ MainWindow::~MainWindow() qDebug() << "Application closed"; } -void MainWindow::goToPage(Page page) +void MainWindow::goToPage(Page page, bool reset, bool slide) { - ui->stackedWidget_main->slideInIdx(static_cast(page)); + if (reset) { + if (page == Page::NewServer) { + ui->label_new_server_wait_info->hide(); + ui->label_new_server_wait_info->clear(); + + ui->progressBar_new_server_connection->setMinimum(0); + ui->progressBar_new_server_connection->setMaximum(300); + } + if (page == Page::ServerSettings) { + ui->label_server_settings_wait_info->hide(); + ui->label_server_settings_wait_info->clear(); + ui->label_server_settings_server->setText(QString("%1@%2:%3") + .arg(m_settings->userName()) + .arg(m_settings->serverName()) + .arg(m_settings->serverPort())); + } + + } + + if (slide) + ui->stackedWidget_main->slideInWidget(getPageWidget(page)); + else + ui->stackedWidget_main->setCurrentWidget(getPageWidget(page)); } +QWidget *MainWindow::getPageWidget(MainWindow::Page page) +{ + switch (page) { + case(Page::Start): return ui->page_start; + case(Page::NewServer): return ui->page_new_server; + case(Page::Vpn): return ui->page_vpn; + case(Page::GeneralSettings): return ui->page_general_settings; + case(Page::ServerSettings): return ui->page_server_settings; + case(Page::ShareConnection): return ui->page_share_connection; + case(Page::Sites): return ui->page_sites; + } + return nullptr; +} + + bool MainWindow::eventFilter(QObject *obj, QEvent *event) { if (obj == ui->widget_tittlebar) { @@ -150,7 +182,13 @@ void MainWindow::keyPressEvent(QKeyEvent *event) } } -void MainWindow::onPushButtonNewServerConnectWithNewData(bool clicked) +void MainWindow::closeEvent(QCloseEvent *event) +{ + event->ignore(); + hide(); +} + +void MainWindow::onPushButtonNewServerConnectWithNewData(bool) { if (ui->lineEdit_new_server_ip->text().isEmpty() || ui->lineEdit_new_server_login->text().isEmpty() || @@ -170,48 +208,67 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool clicked) serverCredentials.userName = ui->lineEdit_new_server_login->text(); serverCredentials.password = ui->lineEdit_new_server_password->text(); - m_settings->setServerCredentials(serverCredentials); - m_settings->save(); + bool ok = installServer(serverCredentials, + ui->page_new_server, + ui->progressBar_new_server_connection, + ui->pushButton_new_server_connect_with_new_data, + ui->label_new_server_wait_info); - ui->page_new_server->setEnabled(false); - ui->pushButton_new_server_connect_with_new_data->setVisible(false); - ui->label_new_server_wait_info->setVisible(true); + if (ok) { + m_settings->setServerCredentials(serverCredentials); + m_settings->save(); + + goToPage(Page::Vpn); + qApp->processEvents(); + + onConnect(); + } +} + +bool MainWindow::installServer(ServerCredentials credentials, + QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info) +{ + page->setEnabled(false); + button->setVisible(false); + + info->setVisible(true); + info->setText(tr("Please wait, configuring process may take up to 5 minutes")); QTimer timer; - connect(&timer, &QTimer::timeout, [&](){ - ui->progressBar_new_server_connection->setValue(ui->progressBar_new_server_connection->value() + 1); + connect(&timer, &QTimer::timeout, [progress](){ + progress->setValue(progress->value() + 1); }); - ui->progressBar_new_server_connection->setValue(0); + progress->setValue(0); timer.start(1000); - ErrorCode e = ServerController::setupServer(serverCredentials, Protocol::Any); + ErrorCode e = ServerController::setupServer(credentials, Protocol::Any); if (e) { - ui->page_new_server->setEnabled(true); - ui->pushButton_new_server_connect_with_new_data->setVisible(true); - ui->label_new_server_wait_info->setVisible(false); + page->setEnabled(true); + button->setVisible(true); + info->setVisible(false); QMessageBox::warning(this, APPLICATION_NAME, tr("Error occurred while configuring server.") + "\n" + errorString(e) + "\n" + tr("See logs for details.")); - return; + return false; } // just ui progressbar tweak timer.stop(); - int remaining_val = ui->progressBar_new_server_connection->maximum() - ui->progressBar_new_server_connection->value(); + int remaining_val = progress->maximum() - progress->value(); if (remaining_val > 0) { QTimer timer1; QEventLoop loop1; connect(&timer1, &QTimer::timeout, [&](){ - ui->progressBar_new_server_connection->setValue(ui->progressBar_new_server_connection->value() + 1); - if (ui->progressBar_new_server_connection->value() >= ui->progressBar_new_server_connection->maximum()) { + progress->setValue(progress->value() + 1); + if (progress->value() >= progress->maximum()) { loop1.quit(); } }); @@ -220,44 +277,61 @@ void MainWindow::onPushButtonNewServerConnectWithNewData(bool clicked) loop1.exec(); } - goToPage(Page::Vpn); - ui->pushButton_connect->setChecked(true); + button->show(); + page->setEnabled(true); + info->setText(tr("Amnezia server installed")); + + return true; +} + +void MainWindow::onPushButtonReinstallServer(bool) +{ + onDisconnect(); + installServer(m_settings->serverCredentials(), + ui->page_server_settings, + ui->progressBar_server_settings_reinstall, + ui->pushButton_server_settings_reinstall, + ui->label_server_settings_wait_info); +} + +void MainWindow::onPushButtonClearServer(bool) +{ + onDisconnect(); + + ErrorCode e = ServerController::removeServer(m_settings->serverCredentials(), Protocol::Any); + if (e) { + QMessageBox::warning(this, APPLICATION_NAME, + tr("Error occurred while configuring server.") + "\n" + + errorString(e) + "\n" + + tr("See logs for details.")); + + return; + } + else { + ui->label_server_settings_wait_info->show(); + ui->label_server_settings_wait_info->setText(tr("Amnezia server successfully uninstalled")); + } +} + +void MainWindow::onPushButtonForgetServer(bool) +{ + onDisconnect(); + + m_settings->setUserName(""); + m_settings->setPassword(""); + m_settings->setServerName(""); + m_settings->setServerPort(); + + m_settings->save(); + + goToPage(Page::Start); } void MainWindow::onBytesChanged(quint64 receivedData, quint64 sentData) { - ui->label_speed_received->setText(VpnConnection::bytesToText(receivedData)); - ui->label_speed_sent->setText(VpnConnection::bytesToText(sentData)); -} - -void MainWindow::onPushButtonBackFromNewServerClicked(bool) -{ - goToPage(Page::Initialization); -} - -void MainWindow::onPushButtonNewServerSetup(bool) -{ - goToPage(Page::NewServer); -} - -void MainWindow::onPushButtonBackFromSettingsClicked(bool) -{ - goToPage(Page::Vpn); -} - -void MainWindow::onPushButtonBackFromSitesClicked(bool) -{ - goToPage(Page::Vpn); -} - -void MainWindow::onPushButtonBlockedListClicked(bool) -{ - goToPage(Page::Sites); -} - -void MainWindow::onPushButtonSettingsClicked(bool) -{ - goToPage(Page::SomeSettings); + qDebug() << "MainWindow::onBytesChanged" << receivedData << sentData; + ui->label_speed_received->setText(VpnConnection::bytesPerSecToText(receivedData)); + ui->label_speed_sent->setText(VpnConnection::bytesPerSecToText(sentData)); } void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state) @@ -265,6 +339,8 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state) bool pushButtonConnectEnabled = false; ui->label_state->setText(VpnProtocol::textConnectionState(state)); + setTrayState(state); + switch (state) { case VpnProtocol::ConnectionState::Disconnected: onBytesChanged(0,0); @@ -284,7 +360,7 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state) pushButtonConnectEnabled = false; break; case VpnProtocol::ConnectionState::TunnelReconnecting: - pushButtonConnectEnabled = false; + pushButtonConnectEnabled = true; break; case VpnProtocol::ConnectionState::Error: pushButtonConnectEnabled = true; @@ -300,28 +376,183 @@ void MainWindow::onConnectionStateChanged(VpnProtocol::ConnectionState state) void MainWindow::onVpnProtocolError(ErrorCode errorCode) { - QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode)); + // TODO fix crash on Windows when starting vpn and another vpn already connected + //QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode)); } -void MainWindow::onPushButtonConnectToggled(bool checked) +void MainWindow::onPushButtonConnectClicked(bool checked) { if (checked) { - // TODO: Call connectToVpn with restricted server account - ServerCredentials credentials = m_settings->serverCredentials(); - - ErrorCode errorCode = m_vpnConnection->connectToVpn(credentials); - if (errorCode) { - ui->pushButton_connect->setChecked(false); - QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode)); - return; - } - ui->pushButton_connect->setEnabled(false); + onConnect(); } else { - m_vpnConnection->disconnectFromVpn(); + onDisconnect(); } } -void MainWindow::on_pushButton_close_clicked() +void MainWindow::setupTray() { - qApp->exit(); + m_menu = new QMenu(); + //m_menu->setStyleSheet(styleSheet()); + + m_menu->addAction(QIcon(":/images/tray/application.png"), tr("Show") + " " + APPLICATION_NAME, this, SLOT(show())); + m_menu->addSeparator(); + m_trayActionConnect = m_menu->addAction(tr("Connect"), this, SLOT(onConnect())); + m_trayActionDisconnect = m_menu->addAction(tr("Disconnect"), this, SLOT(onDisconnect())); + + m_menu->addSeparator(); + + m_menu->addAction(QIcon(":/images/tray/link.png"), tr("Visit Website"), [&](){ + QDesktopServices::openUrl(QUrl("https://amnezia.org")); + }); + + m_menu->addAction(QIcon(":/images/tray/cancel.png"), tr("Quit") + " " + APPLICATION_NAME, this, [&](){ + QMessageBox msgBox(QMessageBox::Question, tr("Exit"), tr("Do you really want to quit?"), + QMessageBox::Yes | QMessageBox::No, Q_NULLPTR, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint); + msgBox.setDefaultButton(QMessageBox::No); + msgBox.raise(); + if (msgBox.exec() == QMessageBox::Yes) { + qApp->quit(); + } + }); + + m_tray.setContextMenu(m_menu); + setTrayState(VpnProtocol::ConnectionState::Disconnected); + + m_tray.show(); + + connect(&m_tray, &QSystemTrayIcon::activated, this, &MainWindow::onTrayActivated); } + +void MainWindow::setTrayIcon(const QString &iconPath) +{ + m_tray.setIcon(QIcon(QPixmap(iconPath).scaled(128,128))); +} + +MainWindow::Page MainWindow::currentPage() +{ + QWidget *currentPage = ui->stackedWidget_main->currentWidget(); + QMetaEnum e = QMetaEnum::fromType(); + + for (int k = 0; k < e.keyCount(); k++) { + Page p = static_cast(e.value(k)); + if (currentPage == getPageWidget(p)) return p; + } + + return Page::Start; +} + +void MainWindow::setupUiConnections() +{ + connect(ui->pushButton_close, &QPushButton::clicked, this, [this](){ + if (currentPage() == Page::Start || currentPage() == Page::NewServer) qApp->quit(); + else hide(); + }); + connect(ui->pushButton_general_settings_exit, &QPushButton::clicked, this, [&](){ qApp->quit(); }); + + connect(ui->pushButton_connect, SIGNAL(clicked(bool)), this, SLOT(onPushButtonConnectClicked(bool))); + connect(ui->pushButton_new_server_setup, &QPushButton::clicked, this, [this](){ goToPage(Page::NewServer); }); + connect(ui->pushButton_new_server_connect_with_new_data, SIGNAL(clicked(bool)), this, SLOT(onPushButtonNewServerConnectWithNewData(bool))); + + connect(ui->pushButton_server_settings_reinstall, SIGNAL(clicked(bool)), this, SLOT(onPushButtonReinstallServer(bool))); + connect(ui->pushButton_server_settings_clear, SIGNAL(clicked(bool)), this, SLOT(onPushButtonClearServer(bool))); + connect(ui->pushButton_server_settings_forget, SIGNAL(clicked(bool)), this, SLOT(onPushButtonForgetServer(bool))); + + connect(ui->pushButton_blocked_list, &QPushButton::clicked, this, [this](){ goToPage(Page::Sites); }); + connect(ui->pushButton_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); }); + connect(ui->pushButton_server_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::ServerSettings); }); + connect(ui->pushButton_share_connection, &QPushButton::clicked, this, [this](){ goToPage(Page::ShareConnection); }); + + + connect(ui->pushButton_back_from_sites, &QPushButton::clicked, this, [this](){ goToPage(Page::Vpn); }); + connect(ui->pushButton_back_from_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::Vpn); }); + connect(ui->pushButton_back_from_new_server, &QPushButton::clicked, this, [this](){ goToPage(Page::Start); }); + connect(ui->pushButton_back_from_server_settings, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); }); + connect(ui->pushButton_back_from_share, &QPushButton::clicked, this, [this](){ goToPage(Page::GeneralSettings); }); + +} + +void MainWindow::setTrayState(VpnProtocol::ConnectionState state) +{ + QString resourcesPath = ":/images/tray/%1"; + + m_trayActionDisconnect->setEnabled(state == VpnProtocol::ConnectionState::Connected); + m_trayActionConnect->setEnabled(state == VpnProtocol::ConnectionState::Disconnected); + + switch (state) { + case VpnProtocol::ConnectionState::Disconnected: + setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); + break; + case VpnProtocol::ConnectionState::Preparing: + setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); + break; + case VpnProtocol::ConnectionState::Connecting: + setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); + break; + case VpnProtocol::ConnectionState::Connected: + setTrayIcon(QString(resourcesPath).arg(ConnectedTrayIconName)); + break; + case VpnProtocol::ConnectionState::Disconnecting: + setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); + break; + case VpnProtocol::ConnectionState::TunnelReconnecting: + setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); + break; + case VpnProtocol::ConnectionState::Error: + setTrayIcon(QString(resourcesPath).arg(ErrorTrayIconName)); + break; + case VpnProtocol::ConnectionState::Unknown: + default: + setTrayIcon(QString(resourcesPath).arg(DisconnectedTrayIconName)); + } + +//#ifdef Q_OS_MAC +// // Get theme from current user (note, this app can be launched as root application and in this case this theme can be different from theme of real current user ) +// bool darkTaskBar = MacOSFunctions::instance().isMenuBarUseDarkTheme(); +// darkTaskBar = forceUseBrightIcons ? true : darkTaskBar; +// resourcesPath = ":/images_mac/tray_icon/%1"; +// useIconName = useIconName.replace(".png", darkTaskBar ? "@2x.png" : " dark@2x.png"); +//#endif + +} + +void MainWindow::onTrayActivated(QSystemTrayIcon::ActivationReason reason) +{ + if(reason == QSystemTrayIcon::DoubleClick || reason == QSystemTrayIcon::Trigger) { + show(); + raise(); + setWindowState(Qt::WindowActive); + } +} + +void MainWindow::onConnect() +{ + ui->pushButton_connect->setChecked(true); + qApp->processEvents(); + + // TODO: Call connectToVpn with restricted server account + ServerCredentials credentials = m_settings->serverCredentials(); + + ErrorCode errorCode = m_vpnConnection->connectToVpn(credentials); + if (errorCode) { + //ui->pushButton_connect->setChecked(false); + QMessageBox::critical(this, APPLICATION_NAME, errorString(errorCode)); + return; + } + ui->pushButton_connect->setEnabled(false); +} + +void MainWindow::onDisconnect() +{ + ui->pushButton_connect->setChecked(false); + m_vpnConnection->disconnectFromVpn(); +} + +void MainWindow::onTrayActionConnect() +{ + if(m_trayActionConnect->text() == tr("Connect")) { + onConnect(); + } else if(m_trayActionConnect->text() == tr("Disconnect")) { + onDisconnect(); + } +} + diff --git a/client/ui/mainwindow.h b/client/ui/mainwindow.h index de5889ee..db3cae1a 100644 --- a/client/ui/mainwindow.h +++ b/client/ui/mainwindow.h @@ -1,7 +1,11 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include #include +#include +#include +#include #include "framelesswindow.h" #include "protocols/vpnprotocol.h" @@ -29,35 +33,61 @@ public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); - enum class Page {Initialization = 0, NewServer = 1, Vpn = 2, Sites = 3, SomeSettings = 4, Share = 5}; + enum Page {Start, NewServer, Vpn, GeneralSettings, ServerSettings, ShareConnection, Sites}; + Q_ENUM(Page) private slots: void onBytesChanged(quint64 receivedBytes, quint64 sentBytes); void onConnectionStateChanged(VpnProtocol::ConnectionState state); void onVpnProtocolError(amnezia::ErrorCode errorCode); - void onPushButtonBackFromNewServerClicked(bool clicked); - void onPushButtonBackFromSettingsClicked(bool clicked); - void onPushButtonBackFromSitesClicked(bool clicked); - void onPushButtonBlockedListClicked(bool clicked); - void onPushButtonConnectToggled(bool checked); - void onPushButtonNewServerConnectWithNewData(bool clicked); - void onPushButtonNewServerSetup(bool clicked); - void onPushButtonSettingsClicked(bool clicked); + void onPushButtonConnectClicked(bool checked); + void onPushButtonNewServerConnectWithNewData(bool); + + void onPushButtonReinstallServer(bool); + void onPushButtonClearServer(bool); + void onPushButtonForgetServer(bool); + + void onTrayActionConnect(); // connect from context menu + void setTrayState(VpnProtocol::ConnectionState state); + + void onTrayActivated(QSystemTrayIcon::ActivationReason reason); + + void onConnect(); + void onDisconnect(); - void on_pushButton_close_clicked(); private: - void goToPage(Page page); + void goToPage(Page page, bool reset = true, bool slide = true); + QWidget *getPageWidget(Page page); + Page currentPage(); + + bool installServer(ServerCredentials credentials, QWidget *page, QProgressBar *progress, QPushButton *button, QLabel *info); + + void setupTray(); + void setTrayIcon(const QString &iconPath); + + void setupUiConnections(); Ui::MainWindow *ui; VpnConnection* m_vpnConnection; Settings* m_settings; + QAction* m_trayActionConnect; + QAction* m_trayActionDisconnect; + + QSystemTrayIcon m_tray; + QMenu* m_menu; + bool canMove = false; QPoint offset; bool eventFilter(QObject *obj, QEvent *event) override; void keyPressEvent(QKeyEvent* event) override; + void closeEvent(QCloseEvent *event) override; + + const QString ConnectedTrayIconName = "active.png"; + const QString DisconnectedTrayIconName = "default.png"; + const QString ErrorTrayIconName = "error.png"; }; #endif // MAINWINDOW_H diff --git a/client/ui/mainwindow.ui b/client/ui/mainwindow.ui index d74f6356..03baeea1 100644 --- a/client/ui/mainwindow.ui +++ b/client/ui/mainwindow.ui @@ -269,7 +269,7 @@ QStackedWidget QWidget { 2 - + @@ -671,7 +671,7 @@ border-radius: 4px; Connect - + 50 @@ -815,12 +815,12 @@ QPushButton:hover { lineEdit_new_server_login lineEdit_new_server_password pushButton_new_server_connect_with_new_data - pushButton + pushButton_new_server_get_info pushButton_back_from_new_server label_7 label_new_server_wait_info - + @@ -1008,6 +1008,9 @@ line-height: 21px; 40 + + PointingHandCursor + QPushButton:!checked { image: url(:/images/connect_button_disconnected.png); @@ -1392,7 +1395,7 @@ color: #333333; - + @@ -1441,7 +1444,7 @@ QPushButton:hover { - + 30 @@ -1450,6 +1453,9 @@ QPushButton:hover { 30 + + PointingHandCursor + font-family: Lato; font-style: normal; @@ -1487,7 +1493,10 @@ background-repeat: no-repeat; - + + + true + 30 @@ -1496,6 +1505,9 @@ background-repeat: no-repeat; 30 + + PointingHandCursor + font-family: Lato; font-style: normal; @@ -1533,8 +1545,367 @@ background-repeat: no-repeat; + + + + 10 + 620 + 360 + 1 + + + + image: url(:/images/line.png); + + + + + + + + true + + + + 30 + 570 + 330 + 30 + + + + PointingHandCursor + + + font-family: Lato; +font-style: normal; +font-weight: bold; +font-size: 20px; +line-height: 25px; +Text-align:left; +padding-left: 30px; + + +/* black */ +color: #100A44; + +background-repeat: no-repeat; + background-position: left center; + + + Exit + + + + + + 10 + 550 + 360 + 1 + + + + image: url(:/images/line.png); + + + + + - + + + + true + + + + 40 + 490 + 301 + 41 + + + + Please wait, configuring process may take up to 5 minutes + + + true + + + + + + 40 + 100 + 171 + 21 + + + + font-family: Lato; +font-style: normal; +font-weight: normal; +font-size: 16px; +line-height: 150%; + +/* or 24px */ + +/* text */ +color: #333333; + + + You connected to + + + + + + 40 + 220 + 301 + 40 + + + + PointingHandCursor + + + QPushButton { +color:rgb(212, 212, 212); +border-radius: 4px; + +font-family: Lato; +font-style: normal; +font-weight: normal; +font-size: 16px; +line-height: 21px; + +background: #100A44; +border-radius: 4px; +} + + + + Reinstall Amnezia server + + + + + + 10 + 10 + 26 + 20 + + + + PointingHandCursor + + + QPushButton { + image: url(:/images/arrow_right.png); + image-position: left; + text-align: left; + /*font: 17pt "Ancient";*/ + + padding: 1px; + image: url(:/images/arrow_left.png); +} +QPushButton:hover { + padding: 0px; +} + + + + + + + + + + + 10 + 40 + 361 + 71 + + + + font-family: Lato; +font-style: normal; +font-weight: bold; +font-size: 24px; +line-height: 25px; +color: #100A44; + + + + Your configured server + + + Qt::AlignCenter + + + true + + + + + + 40 + 220 + 301 + 41 + + + + QProgressBar{ +color:rgb(212, 212, 212); +border-radius: 4px; + +font-family: Lato; +font-style: normal; +font-weight: normal; +font-size: 16px; +line-height: 21px; + +background: #100A44; +border-radius: 4px; +} + +QProgressBar::chunk { +background: rgba(255, 255, 255, 0.15); +border-radius: 4px 0px 0px 4px; + +} + + + + 24 + + + Qt::AlignCenter + + + true + + + Configuring... + + + + + + 110 + 590 + 150 + 22 + + + + image: url(:/images/AmneziaVPN.png); + + + + + + + + + 40 + 280 + 301 + 40 + + + + PointingHandCursor + + + QPushButton { +color:rgb(212, 212, 212); +border-radius: 4px; + +font-family: Lato; +font-style: normal; +font-weight: normal; +font-size: 16px; +line-height: 21px; + +background: #100A44; +border-radius: 4px; +} + + + + Clear server from Amnezia software + + + + + + 40 + 340 + 301 + 40 + + + + PointingHandCursor + + + QPushButton { +color:rgb(212, 212, 212); +border-radius: 4px; + +font-family: Lato; +font-style: normal; +font-weight: normal; +font-size: 16px; +line-height: 21px; + +background: #100A44; +border-radius: 4px; +} + + + + Forget this server + + + + + + 40 + 130 + 321 + 41 + + + + font-family: Lato; +font-style: normal; +font-weight: normal; +font-size: 24px; +color: #333333; + + + root@yourserver.org + + + label_server_settings_wait_info + label_13 + pushButton_back_from_server_settings + label_16 + progressBar_server_settings_reinstall + label_17 + pushButton_server_settings_reinstall + pushButton_server_settings_clear + pushButton_server_settings_forget + label_server_settings_server + + diff --git a/client/vpnconnection.cpp b/client/vpnconnection.cpp index ef75f4e9..ce2cb0fa 100644 --- a/client/vpnconnection.cpp +++ b/client/vpnconnection.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -64,9 +65,13 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Prot // TODO: Implement some behavior in case if connection not stable qDebug() << "Connect to VPN"; + emit connectionStateChanged(VpnProtocol::ConnectionState::Connecting); + qApp->processEvents(); + if (protocol == Protocol::Any || protocol == Protocol::OpenVpn) { ErrorCode e = requestVpnConfig(credentials, Protocol::OpenVpn); if (e) { + emit connectionStateChanged(VpnProtocol::ConnectionState::Error); return e; } if (m_vpnProtocol) { @@ -76,6 +81,7 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Prot connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError); } else if (protocol == Protocol::ShadowSocks) { + emit connectionStateChanged(VpnProtocol::ConnectionState::Error); return ErrorCode::NotImplementedError; } @@ -85,9 +91,10 @@ ErrorCode VpnConnection::connectToVpn(const ServerCredentials &credentials, Prot return m_vpnProtocol.data()->start(); } -QString VpnConnection::bytesToText(quint64 bytes) +QString VpnConnection::bytesPerSecToText(quint64 bytes) { - return QString("%1 %2").arg(bytes / 1000000).arg(tr("Mbps")); + double mbps = bytes * 8 / 1e6; + return QString("%1 %2").arg(QString::number(mbps, 'f', 2)).arg(tr("Mbps")); // Mbit/s } void VpnConnection::disconnectFromVpn() diff --git a/client/vpnconnection.h b/client/vpnconnection.h index 9eb58ab3..d4f13d65 100644 --- a/client/vpnconnection.h +++ b/client/vpnconnection.h @@ -18,7 +18,7 @@ public: explicit VpnConnection(QObject* parent = nullptr); ~VpnConnection() override = default; - static QString bytesToText(quint64 bytes); + static QString bytesPerSecToText(quint64 bytes); ErrorCode lastError() const; ErrorCode requestVpnConfig(const ServerCredentials &credentials, Protocol protocol); diff --git a/service/server/localserver.cpp b/service/server/localserver.cpp index e956fd3a..b98a04d8 100644 --- a/service/server/localserver.cpp +++ b/service/server/localserver.cpp @@ -62,22 +62,22 @@ void LocalServer::onNewConnection() if (lineLength != -1) { QString line = buf; line = line.simplified(); - qDebug().noquote() << QString("Readed line: '%1'").arg(line); - Message icomingMessage(line); - if (!icomingMessage.isValid()) { + qDebug().noquote() << QString("Read line: '%1'").arg(line); + Message incomingMessage(line); + if (!incomingMessage.isValid()) { qWarning().noquote() << "Message is not valid!"; continue; } - switch (icomingMessage.state()) { + switch (incomingMessage.state()) { case Message::State::Initialize: sendMessage(Message(Message::State::Initialize, QStringList({"Server"}))); break; case Message::State::StartRequest: - startProcess(icomingMessage.args()); + startProcess(incomingMessage.args()); break; case Message::State::FinishRequest: - finishProcess(icomingMessage.args()); + finishProcess(incomingMessage.args()); break; default: ;