From ce4ca5c4d5ceb3a465e3c3038f1c7692b215f603 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 28 Dec 2022 06:50:46 +0300 Subject: [PATCH 01/12] Added display of a notification about the inclusion of logging on the main screen --- client/settings.h | 5 ++++- client/ui/pages_logic/VpnLogic.cpp | 4 ++++ client/ui/pages_logic/VpnLogic.h | 2 ++ client/ui/qml/Pages/PageVPN.qml | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/client/settings.h b/client/settings.h index c78b9a79..25f03773 100644 --- a/client/settings.h +++ b/client/settings.h @@ -68,7 +68,7 @@ public: void setStartMinimized(bool enabled) { m_settings.setValue("Conf/startMinimized", enabled); } bool isSaveLogs() const { return m_settings.value("Conf/saveLogs", false).toBool(); } - void setSaveLogs(bool enabled) { m_settings.setValue("Conf/saveLogs", enabled); } + void setSaveLogs(bool enabled); enum RouteMode { VpnAllSites, @@ -113,6 +113,9 @@ public: QByteArray backupAppConfig() const { return m_settings.backupAppConfig(); } bool restoreAppConfig(const QByteArray &cfg) { return m_settings.restoreAppConfig(cfg); } +signals: + void updateVpnPage(); + private: SecureQSettings m_settings; diff --git a/client/ui/pages_logic/VpnLogic.cpp b/client/ui/pages_logic/VpnLogic.cpp index 44a37a5c..1fd69c6b 100644 --- a/client/ui/pages_logic/VpnLogic.cpp +++ b/client/ui/pages_logic/VpnLogic.cpp @@ -33,6 +33,8 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent): connect(this, &VpnLogic::connectToVpn, uiLogic()->m_vpnConnection, &VpnConnection::connectToVpn, Qt::QueuedConnection); connect(this, &VpnLogic::disconnectFromVpn, uiLogic()->m_vpnConnection, &VpnConnection::disconnectFromVpn, Qt::QueuedConnection); + connect(m_settings.get(), &Settings::updateVpnPage, this, &VpnLogic::onUpdatePage); + if (m_settings->isAutoConnect() && m_settings->defaultServerIndex() >= 0) { QTimer::singleShot(1000, this, [this](){ set_pushButtonConnectEnabled(false); @@ -88,6 +90,8 @@ void VpnLogic::onUpdatePage() } QString ver = QString("v. %2").arg(QString(APP_MAJOR_VERSION)); set_labelVersionText(ver); + + set_labelLogEnabledVisible(m_settings->isSaveLogs()); } diff --git a/client/ui/pages_logic/VpnLogic.h b/client/ui/pages_logic/VpnLogic.h index 5d6ef2d9..f7b21be2 100644 --- a/client/ui/pages_logic/VpnLogic.h +++ b/client/ui/pages_logic/VpnLogic.h @@ -34,6 +34,8 @@ class VpnLogic : public PageLogicBase AUTO_PROPERTY(bool, radioButtonVpnModeForwardSitesChecked) AUTO_PROPERTY(bool, radioButtonVpnModeExceptSitesChecked) + AUTO_PROPERTY(bool, labelLogEnabledVisible) + public: Q_INVOKABLE void onUpdatePage() override; diff --git a/client/ui/qml/Pages/PageVPN.qml b/client/ui/qml/Pages/PageVPN.qml index 6bf375a5..847742e9 100644 --- a/client/ui/qml/Pages/PageVPN.qml +++ b/client/ui/qml/Pages/PageVPN.qml @@ -31,6 +31,7 @@ PageBase { } BasicButtonType { + id: button_donate y: 10 anchors.horizontalCenter: parent.horizontalCenter height: 21 @@ -70,6 +71,21 @@ PageBase { } } + LabelType { + id: lb_log_enabled + anchors.top: button_donate.bottom + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width + height: 21 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + text: "Logging enabled!" + color: "#D4D4D4" + + visible: VpnLogic.labelLogEnabledVisible + } + AnimatedImage { id: connect_anim source: "qrc:/images/animation.gif" From 195663c6e36e7ea86586a8a5bced6246d75015ae Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 28 Dec 2022 06:52:02 +0300 Subject: [PATCH 02/12] Added activation and deactivation of logging without restarting the application --- client/debug.cpp | 8 ++++++++ client/debug.h | 1 + client/settings.cpp | 14 ++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/client/debug.cpp b/client/debug.cpp index f4d6e5e5..ebc27968 100644 --- a/client/debug.cpp +++ b/client/debug.cpp @@ -80,6 +80,14 @@ bool Debug::init() return true; } +void Debug::deInit() +{ + qInstallMessageHandler(0); + qSetMessagePattern("%{message}"); + m_textStream.setDevice(nullptr); + m_file.close(); +} + QString Debug::userLogsDir() { return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log"; diff --git a/client/debug.h b/client/debug.h index e58a42ca..5664b486 100644 --- a/client/debug.h +++ b/client/debug.h @@ -23,6 +23,7 @@ public: static bool init(); + static void deInit(); static bool openLogsFolder(); static bool openServiceLogsFolder(); static QString appLogFileNamePath(); diff --git a/client/settings.cpp b/client/settings.cpp index 9fea6b68..08127ad1 100644 --- a/client/settings.cpp +++ b/client/settings.cpp @@ -3,6 +3,7 @@ #include "utilities.h" #include "containers/containers_defs.h" +#include "debug.h" const char Settings::cloudFlareNs1[] = "1.1.1.1"; const char Settings::cloudFlareNs2[] = "1.0.0.1"; @@ -206,6 +207,19 @@ QString Settings::nextAvailableServerName() const return tr("Server") + " " + QString::number(i); } +void Settings::setSaveLogs(bool enabled) +{ + m_settings.setValue("Conf/saveLogs", enabled); + if (!isSaveLogs()) { + Debug::deInit(); + } else { + if (!Debug::init()) { + qWarning() << "Initialization of debug subsystem failed"; + } + } + emit updateVpnPage(); +} + QString Settings::routeModeString(RouteMode mode) const { switch (mode) { From 77e51b40b8f01b8866234687fbfe9ad02a60bd15 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 28 Dec 2022 13:09:33 +0300 Subject: [PATCH 03/12] removed unused logger --- client/client.pro | 5 - client/logger.cpp | 59 -------- client/logger.h | 90 ----------- client/loghandler.cpp | 345 ------------------------------------------ client/loghandler.h | 102 ------------- client/loglevel.h | 15 -- 6 files changed, 616 deletions(-) delete mode 100644 client/logger.cpp delete mode 100644 client/logger.h delete mode 100644 client/loghandler.cpp delete mode 100644 client/loghandler.h delete mode 100644 client/loglevel.h diff --git a/client/client.pro b/client/client.pro index f365cbec..85f70c68 100644 --- a/client/client.pro +++ b/client/client.pro @@ -84,9 +84,6 @@ HEADERS += \ utilities.h \ vpnconnection.h \ protocols/vpnprotocol.h \ - logger.h \ - loghandler.h \ - loglevel.h \ constants.h \ platforms/ios/QRCodeReaderBase.h @@ -144,8 +141,6 @@ SOURCES += \ utilities.cpp \ vpnconnection.cpp \ protocols/vpnprotocol.cpp \ - logger.cpp \ - loghandler.cpp \ platforms/ios/QRCodeReaderBase.cpp RESOURCES += \ diff --git a/client/logger.cpp b/client/logger.cpp deleted file mode 100644 index 06a7c6c8..00000000 --- a/client/logger.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "logger.h" -#include "loghandler.h" - -Logger::Logger(const QString& module, const QString& className) - : Logger(QStringList({module}), className) {} - -Logger::Logger(const QStringList& modules, const QString& className) - : m_modules(modules), m_className(className) {} - -Logger::Log Logger::error() { return Log(this, LogLevel::Error); } -Logger::Log Logger::warning() { return Log(this, LogLevel::Warning); } -Logger::Log Logger::info() { return Log(this, LogLevel::Info); } -Logger::Log Logger::debug() { return Log(this, LogLevel::Debug); } - -Logger::Log::Log(Logger* logger, LogLevel logLevel) - : m_logger(logger), m_logLevel(logLevel), m_data(new Data()) {} - -Logger::Log::~Log() { - LogHandler::messageHandler(m_logLevel, m_logger->modules(), - m_logger->className(), m_data->m_buffer.trimmed()); - delete m_data; -} - -#define CREATE_LOG_OP_REF(x) \ - Logger::Log& Logger::Log::operator<<(x t) { \ - m_data->m_ts << t << ' '; \ - return *this; \ - } - -CREATE_LOG_OP_REF(uint64_t); -CREATE_LOG_OP_REF(const char*); -CREATE_LOG_OP_REF(const QString&); -CREATE_LOG_OP_REF(const QByteArray&); -CREATE_LOG_OP_REF(void*); - -#undef CREATE_LOG_OP_REF - -Logger::Log& Logger::Log::operator<<(const QStringList& t) { - m_data->m_ts << '[' << t.join(",") << ']' << ' '; - return *this; -} - -Logger::Log& Logger::Log::operator<<(QTextStreamFunction t) { - m_data->m_ts << t; - return *this; -} - -// static -QString Logger::sensitive(const QString& input) { -#ifdef QT_DEBUG - return input; -#else - return QString(input.length(), 'X'); -#endif -} diff --git a/client/logger.h b/client/logger.h deleted file mode 100644 index 19aeb6f3..00000000 --- a/client/logger.h +++ /dev/null @@ -1,90 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef LOGGER_H -#define LOGGER_H - -#include "loglevel.h" - -#include -#include -#include -#include - -constexpr const char* LOG_CAPTIVEPORTAL = "captiveportal"; -constexpr const char* LOG_CONTROLLER = "controller"; -constexpr const char* LOG_IAP = "iap"; -constexpr const char* LOG_INSPECTOR = "inspector"; -constexpr const char* LOG_MAIN = "main"; -constexpr const char* LOG_MODEL = "model"; -constexpr const char* LOG_NETWORKING = "networking"; -constexpr const char* LOG_SERVER = "server"; - -#if defined(MVPN_LINUX) || defined(MVPN_ANDROID) -constexpr const char* LOG_LINUX = "linux"; -#endif - -#ifdef MVPN_WINDOWS -constexpr const char* LOG_WINDOWS = "windows"; -#endif - -#if __APPLE__ || defined(MVPN_WASM) -constexpr const char* LOG_MACOS = "macos"; -constexpr const char* LOG_IOS = "ios"; -#endif - -#if defined(MVPN_ANDROID) || defined(UNIT_TEST) -constexpr const char* LOG_ANDROID = "android"; -#endif - -class Logger { - public: - Logger(const QString& module, const QString& className); - Logger(const QStringList& modules, const QString& className); - - const QStringList& modules() const { return m_modules; } - const QString& className() const { return m_className; } - - class Log { - public: - Log(Logger* logger, LogLevel level); - ~Log(); - - Log& operator<<(uint64_t t); - Log& operator<<(const char* t); - Log& operator<<(const QString& t); - Log& operator<<(const QStringList& t); - Log& operator<<(const QByteArray& t); - Log& operator<<(QTextStreamFunction t); - Log& operator<<(void* t); - - private: - Logger* m_logger; - LogLevel m_logLevel; - - struct Data { - Data() : m_ts(&m_buffer, QIODevice::WriteOnly) {} - - QString m_buffer; - QTextStream m_ts; - }; - - Data* m_data; - }; - - Log error(); - Log warning(); - Log info(); - Log debug(); - - // Use this to log sensitive data such as IP address, session tokens, and so - // on. - QString sensitive(const QString& input); - - private: - QStringList m_modules; - QString m_className; -}; - -#endif // LOGGER_H diff --git a/client/loghandler.cpp b/client/loghandler.cpp deleted file mode 100644 index 1302f1ca..00000000 --- a/client/loghandler.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "loghandler.h" -#include "constants.h" -#include "logger.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef MVPN_ANDROID -# include -#endif - -constexpr qint64 LOG_MAX_FILE_SIZE = 204800; -constexpr const char* LOG_FILENAME = "mozillavpn.txt"; - -namespace { -QMutex s_mutex; -QString s_location = - QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); -LogHandler* s_instance = nullptr; - -LogLevel qtTypeToLogLevel(QtMsgType type) { - switch (type) { - case QtDebugMsg: - return Debug; - case QtInfoMsg: - return Info; - case QtWarningMsg: - return Warning; - case QtCriticalMsg: - [[fallthrough]]; - case QtFatalMsg: - return Error; - default: - return Debug; - } -} - -} // namespace - -// static -LogHandler* LogHandler::instance() { - QMutexLocker lock(&s_mutex); - return maybeCreate(lock); -} - -// static -void LogHandler::messageQTHandler(QtMsgType type, - const QMessageLogContext& context, - const QString& message) { - QMutexLocker lock(&s_mutex); - maybeCreate(lock)->addLog(Log(qtTypeToLogLevel(type), context.file, - context.function, context.line, message), - lock); -} - -// static -void LogHandler::messageHandler(LogLevel logLevel, const QStringList& modules, - const QString& className, - const QString& message) { - QMutexLocker lock(&s_mutex); - maybeCreate(lock)->addLog(Log(logLevel, modules, className, message), lock); -} - -// static -LogHandler* LogHandler::maybeCreate(const QMutexLocker& proofOfLock) { - if (!s_instance) { - LogLevel minLogLevel = Debug; // TODO: in prod, we should log >= warning - QStringList modules; - QProcessEnvironment pe = QProcessEnvironment::systemEnvironment(); - if (pe.contains("MOZVPN_LEVEL")) { - QString level = pe.value("MOZVPN_LEVEL"); - if (level == "info") - minLogLevel = Info; - else if (level == "warning") - minLogLevel = Warning; - else if (level == "error") - minLogLevel = Error; - } - - if (pe.contains("MOZVPN_LOG")) { - QStringList parts = pe.value("MOZVPN_LOG").split(","); - for (const QString& part : parts) { - modules.append(part.trimmed()); - } - } - - s_instance = new LogHandler(minLogLevel, modules, proofOfLock); - } - - return s_instance; -} - -// static -void LogHandler::prettyOutput(QTextStream& out, const LogHandler::Log& log) { - out << "[" << log.m_dateTime.toString("dd.MM.yyyy hh:mm:ss.zzz") << "] "; - - switch (log.m_logLevel) { - case Debug: - out << "Debug: "; - break; - case Info: - out << "Info: "; - break; - case Warning: - out << "Warning: "; - break; - case Error: - out << "Error: "; - break; - default: - out << "?!?: "; - break; - } - - if (log.m_fromQT) { - out << log.m_message; - - if (!log.m_file.isEmpty() || !log.m_function.isEmpty()) { - out << " ("; - - if (!log.m_file.isEmpty()) { - int pos = log.m_file.lastIndexOf("/"); - out << log.m_file.right(log.m_file.length() - pos - 1); - - if (log.m_line >= 0) { - out << ":" << log.m_line; - } - - if (!log.m_function.isEmpty()) { - out << ", "; - } - } - - if (!log.m_function.isEmpty()) { - out << log.m_function; - } - - out << ")"; - } - } else { - out << "(" << log.m_modules.join("|") << " - " << log.m_className << ") " - << log.m_message; - } - - out << Qt::endl; -} - -// static -void LogHandler::enableDebug() { - QMutexLocker lock(&s_mutex); - maybeCreate(lock)->m_showDebug = true; -} - -LogHandler::LogHandler(LogLevel minLogLevel, const QStringList& modules, - const QMutexLocker& proofOfLock) - : m_minLogLevel(minLogLevel), m_modules(modules) { - Q_UNUSED(proofOfLock); - -#if defined(QT_DEBUG) || defined(MVPN_WASM) - m_showDebug = true; -#endif - - if (!s_location.isEmpty()) { - openLogFile(proofOfLock); - } -} - -void LogHandler::addLog(const Log& log, const QMutexLocker& proofOfLock) { - if (!matchLogLevel(log, proofOfLock)) { - return; - } - - if (!matchModule(log, proofOfLock)) { - return; - } - - if (m_output) { - prettyOutput(*m_output, log); - } - - if ((log.m_logLevel != LogLevel::Debug) || m_showDebug) { - QTextStream out(stderr); - prettyOutput(out, log); - } - - QByteArray buffer; - { - QTextStream out(&buffer); - prettyOutput(out, log); - } - - emit logEntryAdded(buffer); - -#if defined(MVPN_ANDROID) && defined(QT_DEBUG) - const char* str = buffer.constData(); - if (str) { - __android_log_write(ANDROID_LOG_DEBUG, "mozillavpn", str); - } -#endif -} - -bool LogHandler::matchModule(const Log& log, - const QMutexLocker& proofOfLock) const { - Q_UNUSED(proofOfLock); - - // Let's include QT logs always. - if (log.m_fromQT) { - return true; - } - - // If no modules has been specified, let's include all. - if (m_modules.isEmpty()) { - return true; - } - - for (const QString& module : log.m_modules) { - if (m_modules.contains(module)) { - return true; - } - } - - return false; -} - -bool LogHandler::matchLogLevel(const Log& log, - const QMutexLocker& proofOfLock) const { - Q_UNUSED(proofOfLock); - return log.m_logLevel >= m_minLogLevel; -} - -// static -void LogHandler::writeLogs(QTextStream& out) { - QMutexLocker lock(&s_mutex); - - if (!s_instance || !s_instance->m_logFile) { - return; - } - - QString logFileName = s_instance->m_logFile->fileName(); - s_instance->closeLogFile(lock); - - { - QFile file(logFileName); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { - return; - } - - out << file.readAll(); - } - - s_instance->openLogFile(lock); -} - -// static -void LogHandler::cleanupLogs() { - QMutexLocker lock(&s_mutex); - cleanupLogFile(lock); -} - -// static -void LogHandler::cleanupLogFile(const QMutexLocker& proofOfLock) { - if (!s_instance || !s_instance->m_logFile) { - return; - } - - QString logFileName = s_instance->m_logFile->fileName(); - s_instance->closeLogFile(proofOfLock); - - { - QFile file(logFileName); - file.remove(); - } - - s_instance->openLogFile(proofOfLock); -} - -// static -void LogHandler::setLocation(const QString& path) { - QMutexLocker lock(&s_mutex); - s_location = path; - - if (s_instance && s_instance->m_logFile) { - cleanupLogFile(lock); - } -} - -void LogHandler::openLogFile(const QMutexLocker& proofOfLock) { - Q_UNUSED(proofOfLock); - Q_ASSERT(!m_logFile); - Q_ASSERT(!m_output); - - QDir appDataLocation(s_location); - if (!appDataLocation.exists()) { - QDir tmp(s_location); - tmp.cdUp(); - if (!tmp.exists()) { - return; - } - if (!tmp.mkdir(appDataLocation.dirName())) { - return; - } - } - - QString logFileName = appDataLocation.filePath(LOG_FILENAME); - m_logFile = new QFile(logFileName); - if (m_logFile->size() > LOG_MAX_FILE_SIZE) { - m_logFile->remove(); - } - - if (!m_logFile->open(QIODevice::WriteOnly | QIODevice::Append | - QIODevice::Text)) { - delete m_logFile; - m_logFile = nullptr; - return; - } - - m_output = new QTextStream(m_logFile); - - addLog(Log(Debug, QStringList{LOG_MAIN}, "LogHandler", - QString("Log file: %1").arg(logFileName)), - proofOfLock); -} - -void LogHandler::closeLogFile(const QMutexLocker& proofOfLock) { - Q_UNUSED(proofOfLock); - - if (m_logFile) { - delete m_output; - m_output = nullptr; - - delete m_logFile; - m_logFile = nullptr; - } -} diff --git a/client/loghandler.h b/client/loghandler.h deleted file mode 100644 index d853a808..00000000 --- a/client/loghandler.h +++ /dev/null @@ -1,102 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef LOGHANDLER_H -#define LOGHANDLER_H - -#include "loglevel.h" - -#include -#include -#include -#include - -class QFile; -class QTextStream; - -class LogHandler final : public QObject { - Q_OBJECT - - public: - struct Log { - Log() = default; - - Log(LogLevel logLevel, const QStringList& modules, const QString& className, - const QString& message) - : m_logLevel(logLevel), - m_dateTime(QDateTime::currentDateTime()), - m_modules(modules), - m_className(className), - m_message(message), - m_fromQT(false) {} - - Log(LogLevel logLevel, const QString& file, const QString& function, - uint32_t line, const QString& message) - : m_logLevel(logLevel), - m_dateTime(QDateTime::currentDateTime()), - m_file(file), - m_function(function), - m_message(message), - m_line(line), - m_fromQT(true) {} - - LogLevel m_logLevel = LogLevel::Debug; - QDateTime m_dateTime; - QString m_file; - QString m_function; - QStringList m_modules; - QString m_className; - QString m_message; - int32_t m_line = -1; - bool m_fromQT = false; - }; - - static LogHandler* instance(); - - static void messageQTHandler(QtMsgType type, - const QMessageLogContext& context, - const QString& message); - - static void messageHandler(LogLevel logLevel, const QStringList& modules, - const QString& className, const QString& message); - - static void prettyOutput(QTextStream& out, const LogHandler::Log& log); - - static void writeLogs(QTextStream& out); - - static void cleanupLogs(); - - static void setLocation(const QString& path); - - static void enableDebug(); - - signals: - void logEntryAdded(const QByteArray& log); - - private: - LogHandler(LogLevel m_minLogLevel, const QStringList& modules, - const QMutexLocker& proofOfLock); - - static LogHandler* maybeCreate(const QMutexLocker& proofOfLock); - - void addLog(const Log& log, const QMutexLocker& proofOfLock); - - bool matchLogLevel(const Log& log, const QMutexLocker& proofOfLock) const; - bool matchModule(const Log& log, const QMutexLocker& proofOfLock) const; - - void openLogFile(const QMutexLocker& proofOfLock); - - void closeLogFile(const QMutexLocker& proofOfLock); - - static void cleanupLogFile(const QMutexLocker& proofOfLock); - - const LogLevel m_minLogLevel; - const QStringList m_modules; - bool m_showDebug = false; - - QFile* m_logFile = nullptr; - QTextStream* m_output = nullptr; -}; - -#endif // LOGHANDLER_H diff --git a/client/loglevel.h b/client/loglevel.h deleted file mode 100644 index 0bdec85b..00000000 --- a/client/loglevel.h +++ /dev/null @@ -1,15 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef LOGLEVEL_H -#define LOGLEVEL_H - -enum LogLevel { - Debug, - Info, - Warning, - Error, -}; - -#endif // LOGLEVEL_H From 3b2948d4dde81ee8fcb9946fda55fdb308690f76 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 28 Dec 2022 13:41:45 +0300 Subject: [PATCH 04/12] renamed debug class to logger --- client/amnezia_application.cpp | 8 ++-- client/client.pro | 4 +- client/core/servercontroller.cpp | 8 ++-- client/core/servercontroller.h | 2 +- client/{debug.cpp => logger.cpp} | 43 ++++++++++--------- client/{debug.h => logger.h} | 16 +++---- .../protocols/ikev2_vpn_protocol_windows.cpp | 2 +- client/protocols/openvpnprotocol.cpp | 2 +- client/protocols/shadowsocksvpnprotocol.cpp | 2 +- client/protocols/wireguardprotocol.cpp | 2 +- client/settings.cpp | 6 +-- client/ui/pages_logic/AppSettingsLogic.cpp | 10 ++--- client/ui/uilogic.cpp | 6 +-- 13 files changed, 56 insertions(+), 55 deletions(-) rename client/{debug.cpp => logger.cpp} (81%) rename client/{debug.h => logger.h} (80%) diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 1ea2900c..588854d3 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -7,7 +7,7 @@ #include "core/servercontroller.h" -#include "debug.h" +#include "logger.h" #include "defines.h" #include @@ -99,7 +99,7 @@ void AmneziaApplication::init() QCoreApplication::exit(-1); }, Qt::QueuedConnection); - m_engine->rootContext()->setContextProperty("Debug", &Debug::Instance()); + m_engine->rootContext()->setContextProperty("Debug", &Logger::Instance()); m_uiLogic->registerPagesLogic(); #if defined(Q_OS_IOS) @@ -113,7 +113,7 @@ void AmneziaApplication::init() } if (m_settings->isSaveLogs()) { - if (!Debug::init()) { + if (!Logger::init()) { qWarning() << "Initialization of debug subsystem failed"; } } @@ -206,7 +206,7 @@ bool AmneziaApplication::parseCommands() m_parser.process(*this); if (m_parser.isSet(c_cleanup)) { - Debug::cleanUp(); + Logger::cleanUp(); QTimer::singleShot(100, this, [this]{ quit(); }); diff --git a/client/client.pro b/client/client.pro index 85f70c68..47b39c99 100644 --- a/client/client.pro +++ b/client/client.pro @@ -43,8 +43,8 @@ HEADERS += \ core/scripts_registry.h \ core/server_defs.h \ core/servercontroller.h \ - debug.h \ defines.h \ + logger.h \ managementserver.h \ platforms/ios/MobileUtils.h \ platforms/linux/leakdetector.h \ @@ -102,7 +102,7 @@ SOURCES += \ core/scripts_registry.cpp \ core/server_defs.cpp \ core/servercontroller.cpp \ - debug.cpp \ + logger.cpp \ main.cpp \ managementserver.cpp \ platforms/ios/MobileUtils.cpp \ diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index c7336b62..1b2d7f94 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -79,7 +79,7 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr } qDebug().noquote() << "EXEC" << lineToExec; - Debug::appendSshLog("Run command:" + lineToExec); + Logger::appendSshLog("Run command:" + lineToExec); QSharedPointer proc = client->createRemoteProcess(lineToExec.toUtf8()); @@ -105,7 +105,7 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr QString s = proc->readAllStandardOutput(); if (s != "." && !s.isEmpty()) { - Debug::appendSshLog("Output: " + s); + Logger::appendSshLog("Output: " + s); qDebug().noquote() << "stdout" << s; } if (cbReadStdOut) cbReadStdOut(s, proc); @@ -114,7 +114,7 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr QObject::connect(proc.data(), &SshRemoteProcess::readyReadStandardError, &wait, [proc, cbReadStdErr](){ QString s = proc->readAllStandardError(); if (s != "." && !s.isEmpty()) { - Debug::appendSshLog("Output: " + s); + Logger::appendSshLog("Output: " + s); qDebug().noquote() << "stderr" << s; } if (cbReadStdErr) cbReadStdErr(s, proc); @@ -140,7 +140,7 @@ ErrorCode ServerController::runContainerScript(const ServerCredentials &credenti const std::function)> &cbReadStdErr) { QString fileName = "/opt/amnezia/" + Utils::getRandomString(16) + ".sh"; - Debug::appendSshLog("Run container script for " + ContainerProps::containerToString(container) + ":\n" + script); + Logger::appendSshLog("Run container script for " + ContainerProps::containerToString(container) + ":\n" + script); ErrorCode e = uploadTextFileToContainer(container, credentials, script, fileName); if (e) return e; diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 091eaa52..9e8f4e40 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -5,7 +5,7 @@ #include #include "sshconnection.h" #include "sshremoteprocess.h" -#include "debug.h" +#include "logger.h" #include "defs.h" #include "containers/containers_defs.h" diff --git a/client/debug.cpp b/client/logger.cpp similarity index 81% rename from client/debug.cpp rename to client/logger.cpp index ebc27968..9b217218 100644 --- a/client/debug.cpp +++ b/client/logger.cpp @@ -1,3 +1,5 @@ +#include "logger.h" + #include #include #include @@ -7,7 +9,6 @@ #include -#include "debug.h" #include "defines.h" #include "utilities.h" @@ -15,9 +16,9 @@ #include #endif -QFile Debug::m_file; -QTextStream Debug::m_textStream; -QString Debug::m_logFileName = QString("%1.log").arg(APPLICATION_NAME); +QFile Logger::m_file; +QTextStream Logger::m_textStream; +QString Logger::m_logFileName = QString("%1.log").arg(APPLICATION_NAME); void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) { @@ -30,32 +31,32 @@ void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons return; } - Debug::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush; - Debug::appendAllLog(qFormatLogMessage(type, context, msg)); + Logger::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush; + Logger::appendAllLog(qFormatLogMessage(type, context, msg)); std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl << std::flush; } -Debug &Debug::Instance() +Logger &Logger::Instance() { - static Debug s; + static Logger s; return s; } -void Debug::appendSshLog(const QString &log) +void Logger::appendSshLog(const QString &log) { QString dt = QDateTime::currentDateTime().toString(); Instance().m_sshLog.append(dt + ": " + log + "\n"); emit Instance().sshLogChanged(Instance().sshLog()); } -void Debug::appendAllLog(const QString &log) +void Logger::appendAllLog(const QString &log) { Instance().m_allLog.append(log + "\n"); emit Instance().allLogChanged(Instance().allLog()); } -bool Debug::init() +bool Logger::init() { qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} %{type} %{message}"); @@ -80,7 +81,7 @@ bool Debug::init() return true; } -void Debug::deInit() +void Logger::deInit() { qInstallMessageHandler(0); qSetMessagePattern("%{message}"); @@ -88,17 +89,17 @@ void Debug::deInit() m_file.close(); } -QString Debug::userLogsDir() +QString Logger::userLogsDir() { return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log"; } -QString Debug::userLogsFilePath() +QString Logger::userLogsFilePath() { return userLogsDir() + QDir::separator() + m_logFileName; } -QString Debug::getLogFile() +QString Logger::getLogFile() { m_file.flush(); QFile file(userLogsFilePath()); @@ -107,7 +108,7 @@ QString Debug::getLogFile() return file.readAll(); } -bool Debug::openLogsFolder() +bool Logger::openLogsFolder() { QString path = userLogsDir(); #ifdef Q_OS_WIN @@ -120,7 +121,7 @@ bool Debug::openLogsFolder() return true; } -bool Debug::openServiceLogsFolder() +bool Logger::openServiceLogsFolder() { QString path = Utils::systemLogPath(); path = "file:///" + path; @@ -128,12 +129,12 @@ bool Debug::openServiceLogsFolder() return true; } -QString Debug::appLogFileNamePath() +QString Logger::appLogFileNamePath() { return m_file.fileName(); } -void Debug::clearLogs() +void Logger::clearLogs() { bool isLogActive = m_file.isOpen(); m_file.close(); @@ -149,7 +150,7 @@ void Debug::clearLogs() } } -void Debug::clearServiceLogs() +void Logger::clearServiceLogs() { #ifdef AMNEZIA_DESKTOP IpcClient *m_IpcClient = new IpcClient; @@ -171,7 +172,7 @@ void Debug::clearServiceLogs() #endif } -void Debug::cleanUp() +void Logger::cleanUp() { clearLogs(); QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); diff --git a/client/debug.h b/client/logger.h similarity index 80% rename from client/debug.h rename to client/logger.h index 5664b486..bea5213d 100644 --- a/client/debug.h +++ b/client/logger.h @@ -1,5 +1,5 @@ -#ifndef DEBUG_H -#define DEBUG_H +#ifndef LOGGER_H +#define LOGGER_H #include #include @@ -9,14 +9,14 @@ #include "ui/property_helper.h" -class Debug : public QObject +class Logger : public QObject { Q_OBJECT AUTO_PROPERTY(QString, sshLog) AUTO_PROPERTY(QString, allLog) public: - static Debug& Instance(); + static Logger& Instance(); static void appendSshLog(const QString &log); static void appendAllLog(const QString &log); @@ -35,9 +35,9 @@ public: static QString getLogFile(); private: - Debug() {} - Debug(Debug const &) = delete; - Debug& operator= (Debug const&) = delete; + Logger() {} + Logger(Logger const &) = delete; + Logger& operator= (Logger const&) = delete; static QString userLogsDir(); @@ -48,4 +48,4 @@ private: friend void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg); }; -#endif // DEBUG_H +#endif // LOGGER_H diff --git a/client/protocols/ikev2_vpn_protocol_windows.cpp b/client/protocols/ikev2_vpn_protocol_windows.cpp index 44950f91..66c861d3 100644 --- a/client/protocols/ikev2_vpn_protocol_windows.cpp +++ b/client/protocols/ikev2_vpn_protocol_windows.cpp @@ -6,7 +6,7 @@ #include -#include "debug.h" +#include "logger.h" #include "ikev2_vpn_protocol_windows.h" #include "utilities.h" diff --git a/client/protocols/openvpnprotocol.cpp b/client/protocols/openvpnprotocol.cpp index fcce4ee6..150e84be 100644 --- a/client/protocols/openvpnprotocol.cpp +++ b/client/protocols/openvpnprotocol.cpp @@ -5,7 +5,7 @@ #include #include -#include "debug.h" +#include "logger.h" #include "defines.h" #include "utilities.h" #include "openvpnprotocol.h" diff --git a/client/protocols/shadowsocksvpnprotocol.cpp b/client/protocols/shadowsocksvpnprotocol.cpp index 6957bc3d..7e55b6f3 100644 --- a/client/protocols/shadowsocksvpnprotocol.cpp +++ b/client/protocols/shadowsocksvpnprotocol.cpp @@ -1,6 +1,6 @@ #include "shadowsocksvpnprotocol.h" -#include "debug.h" +#include "logger.h" #include "utilities.h" #include "containers/containers_defs.h" diff --git a/client/protocols/wireguardprotocol.cpp b/client/protocols/wireguardprotocol.cpp index 7f577ac5..985d835c 100644 --- a/client/protocols/wireguardprotocol.cpp +++ b/client/protocols/wireguardprotocol.cpp @@ -4,7 +4,7 @@ #include #include -#include "debug.h" +#include "logger.h" #include "wireguardprotocol.h" #include "utilities.h" diff --git a/client/settings.cpp b/client/settings.cpp index 08127ad1..efc63314 100644 --- a/client/settings.cpp +++ b/client/settings.cpp @@ -3,7 +3,7 @@ #include "utilities.h" #include "containers/containers_defs.h" -#include "debug.h" +#include "logger.h" const char Settings::cloudFlareNs1[] = "1.1.1.1"; const char Settings::cloudFlareNs2[] = "1.0.0.1"; @@ -211,9 +211,9 @@ void Settings::setSaveLogs(bool enabled) { m_settings.setValue("Conf/saveLogs", enabled); if (!isSaveLogs()) { - Debug::deInit(); + Logger::deInit(); } else { - if (!Debug::init()) { + if (!Logger::init()) { qWarning() << "Initialization of debug subsystem failed"; } } diff --git a/client/ui/pages_logic/AppSettingsLogic.cpp b/client/ui/pages_logic/AppSettingsLogic.cpp index b22918b2..3590c480 100644 --- a/client/ui/pages_logic/AppSettingsLogic.cpp +++ b/client/ui/pages_logic/AppSettingsLogic.cpp @@ -1,6 +1,6 @@ #include "AppSettingsLogic.h" -#include "debug.h" +#include "logger.h" #include "defines.h" #include "ui/qautostart.h" #include "ui/uilogic.h" @@ -62,18 +62,18 @@ void AppSettingsLogic::onCheckBoxSaveLogsCheckedToggled(bool checked) void AppSettingsLogic::onPushButtonOpenLogsClicked() { - Debug::openLogsFolder(); + Logger::openLogsFolder(); } void AppSettingsLogic::onPushButtonExportLogsClicked() { - uiLogic()->saveTextFile(tr("Save log"), "AmneziaVPN.log", ".log", Debug::getLogFile()); + uiLogic()->saveTextFile(tr("Save log"), "AmneziaVPN.log", ".log", Logger::getLogFile()); } void AppSettingsLogic::onPushButtonClearLogsClicked() { - Debug::clearLogs(); - Debug::clearServiceLogs(); + Logger::clearLogs(); + Logger::clearServiceLogs(); } void AppSettingsLogic::onPushButtonBackupAppConfigClicked() diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index e336fa76..061da41a 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -35,7 +35,7 @@ #include "ui/qautostart.h" -#include "debug.h" +#include "logger.h" #include "defines.h" #include "uilogic.h" #include "utilities.h" @@ -190,9 +190,9 @@ void UiLogic::keyPressEvent(Qt::Key key) case Qt::Key_AsciiTilde: case Qt::Key_QuoteLeft: emit toggleLogPanel(); break; - case Qt::Key_L: Debug::openLogsFolder(); + case Qt::Key_L: Logger::openLogsFolder(); break; - case Qt::Key_K: Debug::openServiceLogsFolder(); + case Qt::Key_K: Logger::openServiceLogsFolder(); break; #ifdef QT_DEBUG case Qt::Key_Q: From 686fc754b2878f407d3da432de9369c9cb183f7b Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Wed, 28 Dec 2022 17:22:49 +0300 Subject: [PATCH 05/12] renamed log class in service project to logger --- client/logger.cpp | 2 +- ipc/ipcserver.cpp | 10 +++++----- service/server/CMakeLists.txt | 8 ++++---- service/server/{log.cpp => logger.cpp} | 21 +++++++++++---------- service/server/{log.h => logger.h} | 8 ++++---- service/server/main.cpp | 4 ++-- service/server/server.pro | 4 ++-- 7 files changed, 29 insertions(+), 28 deletions(-) rename service/server/{log.cpp => logger.cpp} (83%) rename service/server/{log.h => logger.h} (87%) diff --git a/client/logger.cpp b/client/logger.cpp index 9b217218..d734e2d8 100644 --- a/client/logger.cpp +++ b/client/logger.cpp @@ -83,7 +83,7 @@ bool Logger::init() void Logger::deInit() { - qInstallMessageHandler(0); + qInstallMessageHandler(nullptr); qSetMessagePattern("%{message}"); m_textStream.setDevice(nullptr); m_file.close(); diff --git a/ipc/ipcserver.cpp b/ipc/ipcserver.cpp index d71d7c7d..3d248b84 100644 --- a/ipc/ipcserver.cpp +++ b/ipc/ipcserver.cpp @@ -5,7 +5,7 @@ #include #include "router.h" -#include "log.h" +#include "logger.h" #ifdef Q_OS_WIN #include "tapcontroller_win.h" @@ -111,16 +111,16 @@ QStringList IpcServer::getTapList() void IpcServer::cleanUp() { qDebug() << "IpcServer::cleanUp"; - Log::deinit(); - Log::cleanUp(); + Logger::deinit(); + Logger::cleanUp(); } void IpcServer::setLogsEnabled(bool enabled) { if (enabled) { - Log::init(); + Logger::init(); } else { - Log::deinit(); + Logger::deinit(); } } diff --git a/service/server/CMakeLists.txt b/service/server/CMakeLists.txt index 31ee3372..23df6424 100644 --- a/service/server/CMakeLists.txt +++ b/service/server/CMakeLists.txt @@ -15,7 +15,7 @@ set(HEADERS ${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserver.h ${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserverprocess.h ${CMAKE_CURRENT_LIST_DIR}/localserver.h - ${CMAKE_CURRENT_LIST_DIR}/log.h + ${CMAKE_CURRENT_LIST_DIR}/logger.h ${CMAKE_CURRENT_LIST_DIR}/router.h ${CMAKE_CURRENT_LIST_DIR}/systemservice.h ) @@ -25,7 +25,7 @@ set(SOURCES ${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserver.cpp ${CMAKE_CURRENT_LIST_DIR}/../../ipc/ipcserverprocess.cpp ${CMAKE_CURRENT_LIST_DIR}/localserver.cpp - ${CMAKE_CURRENT_LIST_DIR}/log.cpp + ${CMAKE_CURRENT_LIST_DIR}/logger.cpp ${CMAKE_CURRENT_LIST_DIR}/main.cpp ${CMAKE_CURRENT_LIST_DIR}/router.cpp ${CMAKE_CURRENT_LIST_DIR}/systemservice.cpp @@ -82,9 +82,9 @@ endif() include(${CMAKE_CURRENT_LIST_DIR}/../src/qtservice.cmake) include_directories( + ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/../../client ${CMAKE_CURRENT_LIST_DIR}/../../ipc - ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) @@ -107,4 +107,4 @@ add_custom_command( ${CMAKE_SOURCE_DIR}/deploy/data/${DEPLOY_ARTIFACT_PATH} $ COMMAND_EXPAND_LISTS -) \ No newline at end of file +) diff --git a/service/server/log.cpp b/service/server/logger.cpp similarity index 83% rename from service/server/log.cpp rename to service/server/logger.cpp index a5d56ae5..8b44e0c6 100644 --- a/service/server/log.cpp +++ b/service/server/logger.cpp @@ -1,15 +1,16 @@ +#include "logger.h" + #include #include #include -#include "log.h" #include "defines.h" #include "utilities.h" -QFile Log::m_file; -QTextStream Log::m_textStream; -QString Log::m_logFileName = QString("%1.log").arg(SERVICE_NAME); +QFile Logger::m_file; +QTextStream Logger::m_textStream; +QString Logger::m_logFileName = QString("%1.log").arg(SERVICE_NAME); void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg) { @@ -17,12 +18,12 @@ void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons return; } - Log::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush; + Logger::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush; std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl << std::flush; } -bool Log::init() +bool Logger::init() { if (m_file.isOpen()) return true; @@ -46,19 +47,19 @@ bool Log::init() return true; } -void Log::deinit() +void Logger::deinit() { m_file.close(); m_textStream.setDevice(nullptr); qInstallMessageHandler(nullptr); } -QString Log::serviceLogFileNamePath() +QString Logger::serviceLogFileNamePath() { return m_file.fileName(); } -void Log::clearLogs() +void Logger::clearLogs() { bool isLogActive = m_file.isOpen(); m_file.close(); @@ -78,7 +79,7 @@ void Log::clearLogs() } } -void Log::cleanUp() +void Logger::cleanUp() { clearLogs(); deinit(); diff --git a/service/server/log.h b/service/server/logger.h similarity index 87% rename from service/server/log.h rename to service/server/logger.h index e87dda1d..59044470 100644 --- a/service/server/log.h +++ b/service/server/logger.h @@ -1,12 +1,12 @@ -#ifndef LOG_H -#define LOG_H +#ifndef LOGGER_H +#define LOGGER_H #include #include #include #include -class Log +class Logger { public: static bool init(); @@ -25,4 +25,4 @@ private: static QTextStream m_textStream; }; -#endif // LOG_H +#endif // LOGGER_H diff --git a/service/server/main.cpp b/service/server/main.cpp index 6908a9d8..fe566652 100644 --- a/service/server/main.cpp +++ b/service/server/main.cpp @@ -2,7 +2,7 @@ #include "defines.h" #include "localserver.h" -#include "log.h" +#include "logger.h" #include "systemservice.h" #include "utilities.h" @@ -20,7 +20,7 @@ int main(int argc, char **argv) { Utils::initializePath(Utils::systemLogPath()); - Log::init(); + Logger::init(); if (argc == 2) { qInfo() << "Started as console application"; diff --git a/service/server/server.pro b/service/server/server.pro index 0d3ecd2a..ca7d85cb 100644 --- a/service/server/server.pro +++ b/service/server/server.pro @@ -10,7 +10,7 @@ HEADERS = \ ../../ipc/ipcserver.h \ ../../ipc/ipcserverprocess.h \ localserver.h \ - log.h \ + logger.h \ router.h \ systemservice.h @@ -19,7 +19,7 @@ SOURCES = \ ../../ipc/ipcserver.cpp \ ../../ipc/ipcserverprocess.cpp \ localserver.cpp \ - log.cpp \ + logger.cpp \ main.cpp \ router.cpp \ systemservice.cpp From 08a8eadb49f94edf59ab6b0f28307bc90fa1eaa0 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Sun, 1 Jan 2023 21:48:20 +0300 Subject: [PATCH 06/12] added display of a notification that the server is busy installing third-party software - refactoring doInstallAction functions --- client/CMakeLists.txt | 4 +- client/core/scripts_registry.cpp | 1 + client/core/scripts_registry.h | 3 +- client/core/servercontroller.cpp | 34 ++- client/core/servercontroller.h | 3 + client/resources.qrc | 1 + client/server_scripts/check_server_is_busy.sh | 4 + client/server_scripts/install_docker.sh | 2 +- .../ServerConfiguringProgressLogic.cpp | 68 +++-- .../ServerConfiguringProgressLogic.h | 27 +- .../ui/pages_logic/protocols/CloakLogic.cpp | 58 +++-- client/ui/pages_logic/protocols/CloakLogic.h | 4 + .../ui/pages_logic/protocols/OpenVpnLogic.cpp | 58 +++-- .../ui/pages_logic/protocols/OpenVpnLogic.h | 5 + .../protocols/ShadowSocksLogic.cpp | 74 ++++-- .../pages_logic/protocols/ShadowSocksLogic.h | 10 +- .../Pages/PageServerConfiguringProgress.qml | 16 ++ .../ui/qml/Pages/Protocols/PageProtoCloak.qml | 30 ++- .../qml/Pages/Protocols/PageProtoOpenVPN.qml | 32 ++- .../Pages/Protocols/PageProtoShadowSocks.qml | 46 +++- client/ui/uilogic.cpp | 232 +++--------------- client/ui/uilogic.h | 32 --- 22 files changed, 398 insertions(+), 346 deletions(-) create mode 100644 client/server_scripts/check_server_is_busy.sh diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 8aeddc32..82b3b4fd 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -21,13 +21,13 @@ set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "Autogen") find_package(Qt6 REQUIRED COMPONENTS Widgets Core Gui Network Xml RemoteObjects Quick Svg QuickControls2 - Core5Compat + Core5Compat Concurrent ) set(LIBS ${LIBS} Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Network Qt6::Xml Qt6::RemoteObjects Qt6::Quick Qt6::Svg Qt6::QuickControls2 - Qt6::Core5Compat + Qt6::Core5Compat Qt6::Concurrent ) qt_standard_project_setup() diff --git a/client/core/scripts_registry.cpp b/client/core/scripts_registry.cpp index 77c056bd..d33881a2 100644 --- a/client/core/scripts_registry.cpp +++ b/client/core/scripts_registry.cpp @@ -31,6 +31,7 @@ QString amnezia::scriptName(SharedScriptType type) case SharedScriptType::remove_all_containers: return QLatin1String("remove_all_containers.sh"); case SharedScriptType::setup_host_firewall: return QLatin1String("setup_host_firewall.sh"); case SharedScriptType::check_connection: return QLatin1String("check_connection.sh"); + case SharedScriptType::check_server_is_busy: return QLatin1String("check_server_is_busy.sh"); } } diff --git a/client/core/scripts_registry.h b/client/core/scripts_registry.h index 3d69d95a..9528d763 100644 --- a/client/core/scripts_registry.h +++ b/client/core/scripts_registry.h @@ -15,7 +15,8 @@ enum SharedScriptType { remove_container, remove_all_containers, setup_host_firewall, - check_connection + check_connection, + check_server_is_busy }; enum ProtocolScriptType { // Protocol scripts diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index c7336b62..ef1511b2 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "sftpchannel.h" #include "sshconnectionmanager.h" @@ -528,14 +530,36 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent stdOut += data + "\n"; }; - ErrorCode e = runScript(credentials, - replaceVars(amnezia::scriptData(SharedScriptType::install_docker), - genVarsForScript(credentials)), - cbReadStdOut, cbReadStdErr); + QFutureWatcher watcher; + + QFuture future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() { + do { + stdOut.clear(); + runScript(credentials, + replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy), + genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr); + if (!stdOut.isEmpty() || stdOut.contains("Unable to acquire the dpkg frontend lock")) { + emit serverIsBusy(true); + QThread::msleep(1000); + } + } while (!stdOut.isEmpty()); + }); + + watcher.setFuture(future); + + QEventLoop wait; + QObject::connect(&watcher, &QFutureWatcher::finished, &wait, &QEventLoop::quit); + wait.exec(); + + emit serverIsBusy(false); + + ErrorCode error = runScript(credentials, + replaceVars(amnezia::scriptData(SharedScriptType::install_docker), + genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr); if (stdOut.contains("command not found")) return ErrorCode::ServerDockerFailedError; - return e; + return error; } ErrorCode ServerController::prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config) diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index 091eaa52..b151dc54 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -84,6 +84,9 @@ private: std::shared_ptr m_settings; std::shared_ptr m_configurator; + +signals: + void serverIsBusy(const bool isBusy); }; #endif // SERVERCONTROLLER_H diff --git a/client/resources.qrc b/client/resources.qrc index a7e67e39..75a410d0 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -160,5 +160,6 @@ ui/qml/Pages/PageQrDecoderIos.qml server_scripts/website_tor/Dockerfile ui/qml/Pages/PageViewConfig.qml + server_scripts/check_server_is_busy.sh diff --git a/client/server_scripts/check_server_is_busy.sh b/client/server_scripts/check_server_is_busy.sh new file mode 100644 index 00000000..17c27864 --- /dev/null +++ b/client/server_scripts/check_server_is_busy.sh @@ -0,0 +1,4 @@ +pm_apt="/usr/bin/apt-get";\ +if [[ -f "$pm_apt" ]]; then pm=$pm_apt; else exit; fi;\ +if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi;\ +sudo fuser /var/lib/dpkg/lock-frontend \ No newline at end of file diff --git a/client/server_scripts/install_docker.sh b/client/server_scripts/install_docker.sh index baff7cb6..e12ab2c1 100644 --- a/client/server_scripts/install_docker.sh +++ b/client/server_scripts/install_docker.sh @@ -3,7 +3,7 @@ if [[ -f "$pm_apt" ]]; then pm=$pm_apt; docker_pkg="docker.io"; else pm=$pm_yum; if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi;\ docker_service=$(systemctl list-units --full -all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ if [[ -f "$pm_apt" ]]; then export DEBIAN_FRONTEND=noninteractive; fi;\ -if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y -q curl $docker_pkg; fi;\ +if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y -q curl $docker_pkg; fi;\ docker_service=$(systemctl list-units --full -all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ if [[ -z "$docker_service" ]]; then sleep 5 && sudo systemctl start docker && sleep 5; fi;\ docker --version diff --git a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp index 32ae366d..23697181 100644 --- a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp +++ b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp @@ -5,6 +5,8 @@ #include #include +#include "core/servercontroller.h" + ServerConfiguringProgressLogic::ServerConfiguringProgressLogic(UiLogic *logic, QObject *parent): PageLogicBase(logic, parent), m_progressBarValue{0}, @@ -13,7 +15,9 @@ ServerConfiguringProgressLogic::ServerConfiguringProgressLogic(UiLogic *logic, Q m_progressBarVisible{true}, m_progressBarMaximium{100}, m_progressBarTextVisible{true}, - m_progressBarText{tr("Configuring...")} + m_progressBarText{tr("Configuring...")}, + m_labelServerBusyVisible{false}, + m_labelServerBusyText{""} { } @@ -30,14 +34,14 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function void { set_pageEnabled(enabled); }; - ButtonFunc button; - LabelFunc info; + ButtonFunc noButton; + LabelFunc noWaitInfo; ProgressFunc progress; - progress.setVisibleFunc = [this] (bool visible) ->void { + progress.setVisibleFunc = [this] (bool visible) -> void { set_progressBarVisible(visible); }; - progress.setValueFunc = [this] (int value) ->void { + progress.setValueFunc = [this] (int value) -> void { set_progressBarValue(value); }; progress.getValueFunc = [this] (void) -> int { @@ -47,8 +51,24 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function void { + set_labelServerBusyText(text); + }; + busyInfo.setVisibleFunc = [this] (bool visible) -> void { + set_labelServerBusyVisible(visible); + }; + return doInstallAction(action, page, progress, noButton, noWaitInfo, busyInfo); +} +ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function &action, + const PageFunc &page, + const ProgressFunc &progress, + const ButtonFunc &button, + const LabelFunc &waitInfo, + const LabelFunc &serverBusyInfo) +{ progress.setVisibleFunc(true); if (page.setEnabledFunc) { page.setEnabledFunc(false); @@ -56,11 +76,11 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function 0) { + if (remainingVal > 0) { QTimer timer1; QEventLoop loop1; @@ -120,8 +158,8 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function &action); + AUTO_PROPERTY(bool, labelServerBusyVisible) + AUTO_PROPERTY(QString, labelServerBusyText) private: struct ProgressFunc { @@ -48,5 +43,23 @@ private: std::function setTextFunc; }; +public: + explicit ServerConfiguringProgressLogic(UiLogic *uiLogic, QObject *parent = nullptr); + ~ServerConfiguringProgressLogic() = default; + + friend class OpenVpnLogic; + friend class ShadowSocksLogic; + friend class CloakLogic; + friend class UiLogic; + + void onUpdatePage() override; + ErrorCode doInstallAction(const std::function &action); + ErrorCode doInstallAction(const std::function &action, + const PageFunc &page, + const ProgressFunc &progress, + const ButtonFunc &button, + const LabelFunc &waitInfo, + const LabelFunc &serverBusyInfo); + }; #endif // SERVER_CONFIGURING_PROGRESS_LOGIC_H diff --git a/client/ui/pages_logic/protocols/CloakLogic.cpp b/client/ui/pages_logic/protocols/CloakLogic.cpp index 59019990..1456e457 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.cpp +++ b/client/ui/pages_logic/protocols/CloakLogic.cpp @@ -1,7 +1,10 @@ #include "CloakLogic.h" -#include "core/servercontroller.h" + #include -#include "../../uilogic.h" + +#include "core/servercontroller.h" +#include "ui/uilogic.h" +#include "ui/pages_logic/ServerConfiguringProgressLogic.h" using namespace amnezia; using namespace PageEnumNS; @@ -59,40 +62,59 @@ void CloakLogic::onPushButtonSaveClicked() QJsonObject newContainerConfig = containerConfig; newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig); - UiLogic::PageFunc page_func; - page_func.setEnabledFunc = [this] (bool enabled) -> void { + ServerConfiguringProgressLogic::PageFunc pageFunc; + pageFunc.setEnabledFunc = [this] (bool enabled) -> void { set_pageEnabled(enabled); }; - UiLogic::ButtonFunc pushButton_save_func; - pushButton_save_func.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc; + saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void { set_pushButtonSaveVisible(visible); }; - UiLogic::LabelFunc label_info_func; - label_info_func.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::LabelFunc waitInfoFunc; + waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void { set_labelInfoVisible(visible); }; - label_info_func.setTextFunc = [this] (const QString& text) ->void { + waitInfoFunc.setTextFunc = [this] (const QString& text) -> void { set_labelInfoText(text); }; - UiLogic::ProgressFunc progressBar_reset; - progressBar_reset.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::ProgressFunc progressBarFunc; + progressBarFunc.setVisibleFunc = [this] (bool visible) -> void { set_progressBarResetVisible(visible); }; - progressBar_reset.setValueFunc = [this] (int value) ->void { + progressBarFunc.setValueFunc = [this] (int value) -> void { set_progressBarResetValue(value); }; - progressBar_reset.getValueFunc = [this] (void) -> int { + progressBarFunc.getValueFunc = [this] (void) -> int { return progressBarResetValue(); }; - progressBar_reset.getMaximiumFunc = [this] (void) -> int { + progressBarFunc.getMaximiumFunc = [this] (void) -> int { return progressBarResetMaximium(); }; + progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void { + set_progressBarTextVisible(visible); + }; + progressBarFunc.setTextFunc = [this] (const QString& text) -> void { + set_progressBarText(text); + }; - ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ - return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); + ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy; + busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void { + set_labelServerBusyText(text); + }; + busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void { + set_labelServerBusyVisible(visible); + }; + + progressBarFunc.setTextVisibleFunc(true); + progressBarFunc.setTextFunc(QString("Configuring...")); + ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ + return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), + uiLogic()->selectedDockerContainer, + containerConfig, + newContainerConfig); }, - page_func, progressBar_reset, - pushButton_save_func, label_info_func); + pageFunc, progressBarFunc, + saveButtonFunc, waitInfoFunc, busyInfoFuncy); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); diff --git a/client/ui/pages_logic/protocols/CloakLogic.h b/client/ui/pages_logic/protocols/CloakLogic.h index d88252c8..57afb5b0 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.h +++ b/client/ui/pages_logic/protocols/CloakLogic.h @@ -20,7 +20,11 @@ class CloakLogic : public PageProtocolLogicBase AUTO_PROPERTY(QString, labelInfoText) AUTO_PROPERTY(int, progressBarResetValue) AUTO_PROPERTY(int, progressBarResetMaximium) + AUTO_PROPERTY(bool, progressBarTextVisible) + AUTO_PROPERTY(QString, progressBarText) + AUTO_PROPERTY(bool, labelServerBusyVisible) + AUTO_PROPERTY(QString, labelServerBusyText) public: Q_INVOKABLE void onPushButtonSaveClicked(); diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp index 91f21151..a25fd134 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp @@ -1,7 +1,10 @@ #include "OpenVpnLogic.h" -#include "core/servercontroller.h" + #include -#include "../../uilogic.h" + +#include "core/servercontroller.h" +#include "ui/uilogic.h" +#include "ui/pages_logic/ServerConfiguringProgressLogic.h" using namespace amnezia; using namespace PageEnumNS; @@ -98,40 +101,59 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() QJsonObject newContainerConfig = containerConfig; newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig); - UiLogic::PageFunc page_proto_openvpn; - page_proto_openvpn.setEnabledFunc = [this] (bool enabled) -> void { + ServerConfiguringProgressLogic::PageFunc pageFunc; + pageFunc.setEnabledFunc = [this] (bool enabled) -> void { set_pageEnabled(enabled); }; - UiLogic::ButtonFunc pushButton_proto_openvpn_save; - pushButton_proto_openvpn_save.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc; + saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void { set_pushButtonSaveVisible(visible); }; - UiLogic::LabelFunc label_proto_openvpn_info; - label_proto_openvpn_info.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::LabelFunc waitInfoFunc; + waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void { set_labelProtoOpenVpnInfoVisible(visible); }; - label_proto_openvpn_info.setTextFunc = [this] (const QString& text) ->void { + waitInfoFunc.setTextFunc = [this] (const QString& text) -> void { set_labelProtoOpenVpnInfoText(text); }; - UiLogic::ProgressFunc progressBar_proto_openvpn_reset; - progressBar_proto_openvpn_reset.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::ProgressFunc progressBarFunc; + progressBarFunc.setVisibleFunc = [this] (bool visible) -> void { set_progressBarResetVisible(visible); }; - progressBar_proto_openvpn_reset.setValueFunc = [this] (int value) ->void { + progressBarFunc.setValueFunc = [this] (int value) -> void { set_progressBarResetValue(value); }; - progressBar_proto_openvpn_reset.getValueFunc = [this] (void) -> int { + progressBarFunc.getValueFunc = [this] (void) -> int { return progressBarResetValue(); }; - progressBar_proto_openvpn_reset.getMaximiumFunc = [this] (void) -> int { + progressBarFunc.getMaximiumFunc = [this] (void) -> int { return progressBarResetMaximium(); }; + progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void { + set_progressBarTextVisible(visible); + }; + progressBarFunc.setTextFunc = [this] (const QString& text) -> void { + set_progressBarText(text); + }; - ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ - return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); + ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy; + busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void { + set_labelServerBusyText(text); + }; + busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void { + set_labelServerBusyVisible(visible); + }; + + progressBarFunc.setTextVisibleFunc(true); + progressBarFunc.setTextFunc(QString("Configuring...")); + ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ + return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), + uiLogic()->selectedDockerContainer, + containerConfig, + newContainerConfig); }, - page_proto_openvpn, progressBar_proto_openvpn_reset, - pushButton_proto_openvpn_save, label_proto_openvpn_info); + pageFunc, progressBarFunc, + saveButtonFunc, waitInfoFunc, busyInfoFuncy); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.h b/client/ui/pages_logic/protocols/OpenVpnLogic.h index 23c2dd4d..1dafe5ee 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.h +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.h @@ -34,6 +34,11 @@ class OpenVpnLogic : public PageProtocolLogicBase AUTO_PROPERTY(QString, labelProtoOpenVpnInfoText) AUTO_PROPERTY(int, progressBarResetValue) AUTO_PROPERTY(int, progressBarResetMaximium) + AUTO_PROPERTY(bool, progressBarTextVisible) + AUTO_PROPERTY(QString, progressBarText) + + AUTO_PROPERTY(bool, labelServerBusyVisible) + AUTO_PROPERTY(QString, labelServerBusyText) public: Q_INVOKABLE void onPushButtonProtoOpenVpnSaveClicked(); diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp index 1d5da936..c2575a4d 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp @@ -1,7 +1,10 @@ #include "ShadowSocksLogic.h" -#include "core/servercontroller.h" + #include -#include "../../uilogic.h" + +#include "core/servercontroller.h" +#include "ui/pages_logic/ServerConfiguringProgressLogic.h" +#include "ui/uilogic.h" using namespace amnezia; using namespace PageEnumNS; @@ -11,12 +14,12 @@ ShadowSocksLogic::ShadowSocksLogic(UiLogic *logic, QObject *parent): m_comboBoxCipherText{"chacha20-poly1305"}, m_lineEditPortText{}, m_pushButtonSaveVisible{false}, - m_progressBaResetVisible{false}, + m_progressBarResetVisible{false}, m_lineEditPortEnabled{false}, m_labelInfoVisible{true}, m_labelInfoText{}, - m_progressBaResetValue{0}, - m_progressBaResetMaximium{100} + m_progressBarResetValue{0}, + m_progressBarResetMaximium{100} { } @@ -25,7 +28,7 @@ void ShadowSocksLogic::updateProtocolPage(const QJsonObject &ssConfig, DockerCon { set_pageEnabled(haveAuthData); set_pushButtonSaveVisible(haveAuthData); - set_progressBaResetVisible(haveAuthData); + set_progressBarResetVisible(haveAuthData); set_comboBoxCipherText(ssConfig.value(config_key::cipher). toString(protocols::shadowsocks::defaultCipher)); @@ -51,40 +54,59 @@ void ShadowSocksLogic::onPushButtonSaveClicked() QJsonObject containerConfig = m_settings->containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer); QJsonObject newContainerConfig = containerConfig; newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig); - UiLogic::PageFunc page_proto_shadowsocks; - page_proto_shadowsocks.setEnabledFunc = [this] (bool enabled) -> void { + ServerConfiguringProgressLogic::PageFunc pageFunc; + pageFunc.setEnabledFunc = [this] (bool enabled) -> void { set_pageEnabled(enabled); }; - UiLogic::ButtonFunc pushButton_proto_shadowsocks_save; - pushButton_proto_shadowsocks_save.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::ButtonFunc saveButtonFunc; + saveButtonFunc.setVisibleFunc = [this] (bool visible) -> void { set_pushButtonSaveVisible(visible); }; - UiLogic::LabelFunc label_proto_shadowsocks_info; - label_proto_shadowsocks_info.setVisibleFunc = [this] (bool visible) ->void { + ServerConfiguringProgressLogic::LabelFunc waitInfoFunc; + waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void { set_labelInfoVisible(visible); }; - label_proto_shadowsocks_info.setTextFunc = [this] (const QString& text) ->void { + waitInfoFunc.setTextFunc = [this] (const QString& text) -> void { set_labelInfoText(text); }; - UiLogic::ProgressFunc progressBar_reset; - progressBar_reset.setVisibleFunc = [this] (bool visible) ->void { - set_progressBaResetVisible(visible); + ServerConfiguringProgressLogic::ProgressFunc progressBarFunc; + progressBarFunc.setVisibleFunc = [this] (bool visible) -> void { + set_progressBarResetVisible(visible); }; - progressBar_reset.setValueFunc = [this] (int value) ->void { - set_progressBaResetValue(value); + progressBarFunc.setValueFunc = [this] (int value) -> void { + set_progressBarResetValue(value); }; - progressBar_reset.getValueFunc = [this] (void) -> int { - return progressBaResetValue(); + progressBarFunc.getValueFunc = [this] (void) -> int { + return progressBarResetValue(); }; - progressBar_reset.getMaximiumFunc = [this] (void) -> int { - return progressBaResetMaximium(); + progressBarFunc.getMaximiumFunc = [this] (void) -> int { + return progressBarResetMaximium(); + }; + progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void { + set_progressBarTextVisible(visible); + }; + progressBarFunc.setTextFunc = [this] (const QString& text) -> void { + set_progressBarText(text); }; - ErrorCode e = uiLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ - return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer, containerConfig, newContainerConfig); + ServerConfiguringProgressLogic::LabelFunc busyInfoFuncy; + busyInfoFuncy.setTextFunc = [this] (const QString& text) -> void { + set_labelServerBusyText(text); + }; + busyInfoFuncy.setVisibleFunc = [this] (bool visible) -> void { + set_labelServerBusyVisible(visible); + }; + + progressBarFunc.setTextVisibleFunc(true); + progressBarFunc.setTextFunc(QString("Configuring...")); + ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ + return m_serverController->updateContainer(m_settings->serverCredentials(uiLogic()->selectedServerIndex), + uiLogic()->selectedDockerContainer, + containerConfig, + newContainerConfig); }, - page_proto_shadowsocks, progressBar_reset, - pushButton_proto_shadowsocks_save, label_proto_shadowsocks_info); + pageFunc, progressBarFunc, + saveButtonFunc, waitInfoFunc, busyInfoFuncy); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.h b/client/ui/pages_logic/protocols/ShadowSocksLogic.h index 4e566825..1300511f 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.h +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.h @@ -12,13 +12,17 @@ class ShadowSocksLogic : public PageProtocolLogicBase AUTO_PROPERTY(QString, comboBoxCipherText) AUTO_PROPERTY(QString, lineEditPortText) AUTO_PROPERTY(bool, pushButtonSaveVisible) - AUTO_PROPERTY(bool, progressBaResetVisible) + AUTO_PROPERTY(bool, progressBarResetVisible) AUTO_PROPERTY(bool, lineEditPortEnabled) AUTO_PROPERTY(bool, labelInfoVisible) AUTO_PROPERTY(QString, labelInfoText) - AUTO_PROPERTY(int, progressBaResetValue) - AUTO_PROPERTY(int, progressBaResetMaximium) + AUTO_PROPERTY(int, progressBarResetValue) + AUTO_PROPERTY(int, progressBarResetMaximium) + AUTO_PROPERTY(bool, progressBarTextVisible) + AUTO_PROPERTY(QString, progressBarText) + AUTO_PROPERTY(bool, labelServerBusyVisible) + AUTO_PROPERTY(QString, labelServerBusyText) public: Q_INVOKABLE void onPushButtonSaveClicked(); diff --git a/client/ui/qml/Pages/PageServerConfiguringProgress.qml b/client/ui/qml/Pages/PageServerConfiguringProgress.qml index 1cd154ca..e481dbfe 100644 --- a/client/ui/qml/Pages/PageServerConfiguringProgress.qml +++ b/client/ui/qml/Pages/PageServerConfiguringProgress.qml @@ -27,6 +27,22 @@ PageBase { horizontalAlignment: Text.AlignHCenter } + LabelType { + id: labelServerBusy + x: 0 + anchors.top: label.bottom + anchors.topMargin: 30 + + anchors.horizontalCenter: parent.horizontalCenter + horizontalAlignment: Text.AlignHCenter + + width: parent.width - 40 + height: 41 + + text: ServerConfiguringProgressLogic.labelServerBusyText + visible: ServerConfiguringProgressLogic.labelServerBusyVisible + } + LabelType { anchors.bottom: pr.top anchors.bottomMargin: 20 diff --git a/client/ui/qml/Pages/Protocols/PageProtoCloak.qml b/client/ui/qml/Pages/Protocols/PageProtoCloak.qml index 01ad4f81..17dc829a 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoCloak.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoCloak.qml @@ -14,6 +14,7 @@ PageProtocolBase { enabled: logic.pageEnabled BackButton { id: back + enabled: logic.pageEnabled } Caption { @@ -110,12 +111,20 @@ PageProtocolBase { } } + LabelType { + id: label_server_busy + horizontalAlignment: Text.AlignHCenter + Layout.maximumWidth: parent.width + Layout.fillWidth: true + visible: logic.labelServerBusyVisible + text: logic.labelServerBusyText + } + LabelType { id: label_proto_cloak_info - x: 30 - anchors.bottom: pb_save.top - anchors.bottomMargin: 10 - width: parent.width - 40 + horizontalAlignment: Text.AlignHCenter + Layout.maximumWidth: parent.width + Layout.fillWidth: true visible: logic.labelInfoVisible text: logic.labelInfoText } @@ -146,6 +155,19 @@ PageProtocolBase { } } visible: logic.progressBarResetVisible + LabelType { + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + text: logic.progressBarText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#D4D4D4" + visible: logic.progressBarTextVisible + } } BlueButtonType { id: pb_save diff --git a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml index 8387b9fe..a644bf59 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml @@ -13,6 +13,7 @@ PageProtocolBase { BackButton { id: back + enabled: logic.pageEnabled } Caption { id: caption @@ -345,9 +346,19 @@ PageProtocolBase { } LabelType { - id: label_proto_openvpn_info + id: label_server_busy + horizontalAlignment: Text.AlignHCenter + Layout.maximumWidth: parent.width + Layout.fillWidth: true + visible: logic.labelServerBusyVisible + text: logic.labelServerBusyText + } - height: 41 + LabelType { + id: label_proto_openvpn_info + horizontalAlignment: Text.AlignHCenter + Layout.maximumWidth: parent.width + Layout.fillWidth: true visible: logic.labelProtoOpenVpnInfoVisible text: logic.labelProtoOpenVpnInfoText } @@ -395,11 +406,20 @@ PageProtocolBase { } } } - + LabelType { + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + text: logic.progressBarText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#D4D4D4" + visible: logic.progressBarTextVisible + } } - } - } - } diff --git a/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml b/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml index e2726106..3fe0df26 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml @@ -13,6 +13,7 @@ PageProtocolBase { BackButton { id: back + enabled: logic.pageEnabled } Caption { @@ -88,27 +89,33 @@ PageProtocolBase { Item { Layout.fillHeight: true } - } + LabelType { + id: label_server_busy + horizontalAlignment: Text.AlignHCenter + Layout.maximumWidth: parent.width + Layout.fillWidth: true + visible: logic.labelServerBusyVisible + text: logic.labelServerBusyText + } - LabelType { - id: label_proto_shadowsocks_info - x: 30 - anchors.bottom: pb_save.top - anchors.bottomMargin: 10 - width: parent.width - 40 - height: 41 - visible: logic.labelInfoVisible - text: logic.labelInfoText + LabelType { + id: label_proto_shadowsocks_info + horizontalAlignment: Text.AlignHCenter + Layout.maximumWidth: parent.width + Layout.fillWidth: true + visible: logic.labelInfoVisible + text: logic.labelInfoText + } } ProgressBar { id: progressBar_reset anchors.fill: pb_save from: 0 - to: logic.progressBaResetMaximium - value: logic.progressBaResetValue - visible: logic.progressBaResetVisible + to: logic.progressBarResetMaximium + value: logic.progressBarResetValue + visible: logic.progressBarResetVisible background: Rectangle { implicitWidth: parent.width implicitHeight: parent.height @@ -126,6 +133,19 @@ PageProtocolBase { color: Qt.rgba(255, 255, 255, 0.15); } } + LabelType { + anchors.left: parent.left + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + text: logic.progressBarText + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#D4D4D4" + visible: logic.progressBarTextVisible + } } BlueButtonType { diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index e336fa76..9d43f414 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -303,44 +303,62 @@ void UiLogic::installServer(QMap &containers) loop.exec(); qApp->processEvents(); - PageFunc page_new_server_configuring; - page_new_server_configuring.setEnabledFunc = [this] (bool enabled) -> void { + ServerConfiguringProgressLogic::PageFunc pageFunc; + pageFunc.setEnabledFunc = [this] (bool enabled) -> void { pageLogic()->set_pageEnabled(enabled); }; - ButtonFunc no_button; - LabelFunc label_new_server_configuring_wait_info; - label_new_server_configuring_wait_info.setTextFunc = [this] (const QString& text) -> void { + + ServerConfiguringProgressLogic::ButtonFunc noButton; + + ServerConfiguringProgressLogic::LabelFunc waitInfoFunc; + waitInfoFunc.setTextFunc = [this] (const QString& text) -> void { pageLogic()->set_labelWaitInfoText(text); }; - label_new_server_configuring_wait_info.setVisibleFunc = [this] (bool visible) ->void { + waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void { pageLogic()->set_labelWaitInfoVisible(visible); }; - ProgressFunc progressBar_new_server_configuring; - progressBar_new_server_configuring.setVisibleFunc = [this] (bool visible) ->void { + + ServerConfiguringProgressLogic::ProgressFunc progressBarFunc; + progressBarFunc.setVisibleFunc = [this] (bool visible) -> void { pageLogic()->set_progressBarVisible(visible); }; - progressBar_new_server_configuring.setValueFunc = [this] (int value) ->void { + progressBarFunc.setValueFunc = [this] (int value) -> void { pageLogic()->set_progressBarValue(value); }; - progressBar_new_server_configuring.getValueFunc = [this] (void) -> int { + progressBarFunc.getValueFunc = [this] (void) -> int { return pageLogic()->progressBarValue(); }; - progressBar_new_server_configuring.getMaximiumFunc = [this] (void) -> int { + progressBarFunc.getMaximiumFunc = [this] (void) -> int { return pageLogic()->progressBarMaximium(); }; - progressBar_new_server_configuring.setTextVisibleFunc = [this] (bool visible) ->void { + progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void { pageLogic()->set_progressBarTextVisible(visible); }; - progressBar_new_server_configuring.setTextFunc = [this] (const QString& text) ->void { + progressBarFunc.setTextFunc = [this] (const QString& text) -> void { pageLogic()->set_progressBarText(text); }; - bool ok = installContainers(installCredentials, containers, - page_new_server_configuring, - progressBar_new_server_configuring, - no_button, - label_new_server_configuring_wait_info); - if (ok) { + ServerConfiguringProgressLogic::LabelFunc busyInfoFunc; + busyInfoFunc.setTextFunc = [this] (const QString& text) -> void { + pageLogic()->set_labelServerBusyText(text); + }; + busyInfoFunc.setVisibleFunc = [this] (bool visible) -> void { + pageLogic()->set_labelServerBusyVisible(visible); + }; + + int count = 0; + ErrorCode error; + for (QMap::iterator i = containers.begin(); i != containers.end(); i++, count++) { + progressBarFunc.setTextFunc(QString("Installing %1 %2 %3").arg(count+1).arg(tr("of")).arg(containers.size())); + + error = pageLogic()->doInstallAction([&] () { + return m_serverController->setupContainer(installCredentials, i.key(), i.value()); + }, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc); + + m_serverController->disconnectFromHost(installCredentials); + } + + if (error == ErrorCode::NoError) { QJsonObject server; server.insert(config_key::hostName, installCredentials.hostName); server.insert(config_key::userName, installCredentials.userName); @@ -367,182 +385,6 @@ void UiLogic::installServer(QMap &containers) } } -bool UiLogic::installContainers(ServerCredentials credentials, - QMap &containers, - const PageFunc &page, - const ProgressFunc &progress, - const ButtonFunc &button, - const LabelFunc &info) -{ - if (!progress.setValueFunc) return false; - - if (page.setEnabledFunc) { - page.setEnabledFunc(false); - } - if (button.setVisibleFunc) { - button.setVisibleFunc(false); - } - - if (info.setVisibleFunc) { - info.setVisibleFunc(true); - } - if (info.setTextFunc) { - info.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes")); - } - - int cnt = 0; - for (QMap::iterator i = containers.begin(); i != containers.end(); i++, cnt++) { - QTimer timer; - connect(&timer, &QTimer::timeout, [progress](){ - progress.setValueFunc(progress.getValueFunc() + 1); - }); - - progress.setValueFunc(0); - timer.start(1000); - - progress.setTextVisibleFunc(true); - progress.setTextFunc(QString("Installing %1 %2 %3").arg(cnt+1).arg(tr("of")).arg(containers.size())); - - ErrorCode e = m_serverController->setupContainer(credentials, i.key(), i.value()); - qDebug() << "Setup server finished with code" << e; - m_serverController->disconnectFromHost(credentials); - - if (e) { - if (page.setEnabledFunc) { - page.setEnabledFunc(true); - } - if (button.setVisibleFunc) { - button.setVisibleFunc(true); - } - if (info.setVisibleFunc) { - info.setVisibleFunc(false); - } - - QMessageBox::warning(nullptr, APPLICATION_NAME, - tr("Error occurred while configuring server.") + "\n" + - errorString(e)); - - return false; - } - - // just ui progressbar tweak - timer.stop(); - - int remaining_val = progress.getMaximiumFunc() - progress.getValueFunc(); - - if (remaining_val > 0) { - QTimer timer1; - QEventLoop loop1; - - connect(&timer1, &QTimer::timeout, [&](){ - progress.setValueFunc(progress.getValueFunc() + 1); - if (progress.getValueFunc() >= progress.getMaximiumFunc()) { - loop1.quit(); - } - }); - - timer1.start(5); - loop1.exec(); - } - } - - - if (button.setVisibleFunc) { - button.setVisibleFunc(true); - } - if (page.setEnabledFunc) { - page.setEnabledFunc(true); - } - if (info.setTextFunc) { - info.setTextFunc(tr("Amnezia server installed")); - } - - return true; -} - -ErrorCode UiLogic::doInstallAction(const std::function &action, - const PageFunc &page, - const ProgressFunc &progress, - const ButtonFunc &button, - const LabelFunc &info) -{ - progress.setVisibleFunc(true); - if (page.setEnabledFunc) { - page.setEnabledFunc(false); - } - if (button.setVisibleFunc) { - button.setVisibleFunc(false); - } - if (info.setVisibleFunc) { - info.setVisibleFunc(true); - } - if (info.setTextFunc) { - info.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes")); - } - - QTimer timer; - connect(&timer, &QTimer::timeout, [progress](){ - progress.setValueFunc(progress.getValueFunc() + 1); - }); - - progress.setValueFunc(0); - timer.start(1000); - - ErrorCode e = action(); - qDebug() << "doInstallAction finished with code" << e; - - if (e) { - if (page.setEnabledFunc) { - page.setEnabledFunc(true); - } - if (button.setVisibleFunc) { - button.setVisibleFunc(true); - } - if (info.setVisibleFunc) { - info.setVisibleFunc(false); - } - QMessageBox::warning(nullptr, APPLICATION_NAME, - tr("Error occurred while configuring server.") + "\n" + - errorString(e)); - - progress.setVisibleFunc(false); - return e; - } - - // just ui progressbar tweak - timer.stop(); - - int remaining_val = progress.getMaximiumFunc() - progress.getValueFunc(); - - if (remaining_val > 0) { - QTimer timer1; - QEventLoop loop1; - - connect(&timer1, &QTimer::timeout, [&](){ - progress.setValueFunc(progress.getValueFunc() + 1); - if (progress.getValueFunc() >= progress.getMaximiumFunc()) { - loop1.quit(); - } - }); - - timer1.start(5); - loop1.exec(); - } - - - progress.setVisibleFunc(false); - if (button.setVisibleFunc) { - button.setVisibleFunc(true); - } - if (page.setEnabledFunc) { - page.setEnabledFunc(true); - } - if (info.setTextFunc) { - info.setTextFunc(tr("Operation finished")); - } - return ErrorCode::NoError; -} - PageProtocolLogicBase *UiLogic::protocolLogic(Proto p) { PageProtocolLogicBase *logic = m_protocolLogicMap.value(p); diff --git a/client/ui/uilogic.h b/client/ui/uilogic.h index 82f2d6ea..4cc006dd 100644 --- a/client/ui/uilogic.h +++ b/client/ui/uilogic.h @@ -136,38 +136,6 @@ private slots: private: PageEnumNS::Page currentPage(); - struct ProgressFunc { - std::function setVisibleFunc; - std::function setValueFunc; - std::function getValueFunc; - std::function getMaximiumFunc; - std::function setTextVisibleFunc; - std::function setTextFunc; - }; - struct PageFunc { - std::function setEnabledFunc; - }; - struct ButtonFunc { - std::function setVisibleFunc; - }; - struct LabelFunc { - std::function setVisibleFunc; - std::function setTextFunc; - }; - - bool installContainers(ServerCredentials credentials, - QMap &containers, - const PageFunc& page, - const ProgressFunc& progress, - const ButtonFunc& button, - const LabelFunc& info); - - ErrorCode doInstallAction(const std::function &action, - const PageFunc& page, - const ProgressFunc& progress, - const ButtonFunc& button, - const LabelFunc& info); - public: Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p); From 6ec090ea0dd5037e25de3af39d5e45df9d57511a Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 2 Jan 2023 17:32:27 +0300 Subject: [PATCH 07/12] added a "Cancel" button to interrupt the server configuration process when it is found that it is busy installing other software --- client/core/defs.h | 1 + client/core/errorstrings.cpp | 1 + client/core/servercontroller.cpp | 20 ++++++- client/core/servercontroller.h | 2 + .../ServerConfiguringProgressLogic.cpp | 55 ++++++++++++++----- .../ServerConfiguringProgressLogic.h | 12 +++- .../ui/pages_logic/protocols/CloakLogic.cpp | 13 ++++- client/ui/pages_logic/protocols/CloakLogic.h | 4 ++ .../ui/pages_logic/protocols/OpenVpnLogic.cpp | 15 ++++- .../ui/pages_logic/protocols/OpenVpnLogic.h | 5 +- .../protocols/ShadowSocksLogic.cpp | 13 ++++- .../pages_logic/protocols/ShadowSocksLogic.h | 4 ++ .../Pages/PageServerConfiguringProgress.qml | 20 +++++-- .../ui/qml/Pages/Protocols/PageProtoCloak.qml | 10 +++- .../qml/Pages/Protocols/PageProtoOpenVPN.qml | 49 +++++++++++------ .../Pages/Protocols/PageProtoShadowSocks.qml | 10 ++++ client/ui/uilogic.cpp | 7 ++- 17 files changed, 193 insertions(+), 48 deletions(-) diff --git a/client/core/defs.h b/client/core/defs.h index 5845fd3c..3f861401 100644 --- a/client/core/defs.h +++ b/client/core/defs.h @@ -31,6 +31,7 @@ enum ErrorCode ServerPortAlreadyAllocatedError, ServerContainerMissingError, ServerDockerFailedError, + ServerCancelInstallation, // Ssh connection errors SshSocketError, SshTimeoutError, SshProtocolError, diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp index 722dd4b4..1e7eb395 100644 --- a/client/core/errorstrings.cpp +++ b/client/core/errorstrings.cpp @@ -15,6 +15,7 @@ QString errorString(ErrorCode code){ case(ServerPortAlreadyAllocatedError): return QObject::tr("Server port already used. Check for another software"); case(ServerContainerMissingError): return QObject::tr("Server error: Docker container missing"); case(ServerDockerFailedError): return QObject::tr("Server error: Docker failed"); + case(ServerCancelInstallation): return QObject::tr("Installation canceled by user"); // Ssh connection errors case(SshSocketError): return QObject::tr("Ssh connection error"); diff --git a/client/core/servercontroller.cpp b/client/core/servercontroller.cpp index ef1511b2..c9d4f0de 100644 --- a/client/core/servercontroller.cpp +++ b/client/core/servercontroller.cpp @@ -530,10 +530,13 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent stdOut += data + "\n"; }; - QFutureWatcher watcher; + QFutureWatcher watcher; - QFuture future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() { + QFuture future = QtConcurrent::run([this, &stdOut, &cbReadStdOut, &cbReadStdErr, &credentials]() { do { + if (m_cancelInstallation) { + return ErrorCode::ServerCancelInstallation; + } stdOut.clear(); runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::check_server_is_busy), @@ -543,16 +546,22 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent QThread::msleep(1000); } } while (!stdOut.isEmpty()); + return ErrorCode::NoError; }); watcher.setFuture(future); QEventLoop wait; - QObject::connect(&watcher, &QFutureWatcher::finished, &wait, &QEventLoop::quit); + QObject::connect(&watcher, &QFutureWatcher::finished, &wait, &QEventLoop::quit); wait.exec(); + m_cancelInstallation = false; emit serverIsBusy(false); + if (future.result() != ErrorCode::NoError) { + return future.result(); + } + ErrorCode error = runScript(credentials, replaceVars(amnezia::scriptData(SharedScriptType::install_docker), genVarsForScript(credentials)), cbReadStdOut, cbReadStdErr); @@ -820,6 +829,11 @@ SshConnection *ServerController::connectToHost(const SshConnectionParameters &ss return client; } +void ServerController::setCancelInstallation(const bool cancel) +{ + m_cancelInstallation = cancel; +} + void ServerController::disconnectFromHost(const ServerCredentials &credentials) { SshConnection *client = acquireConnection(sshParams(credentials)); diff --git a/client/core/servercontroller.h b/client/core/servercontroller.h index b151dc54..c64401da 100644 --- a/client/core/servercontroller.h +++ b/client/core/servercontroller.h @@ -73,6 +73,7 @@ public: QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr); QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams); + void setCancelInstallation(const bool cancel); private: ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container); @@ -85,6 +86,7 @@ private: std::shared_ptr m_settings; std::shared_ptr m_configurator; + bool m_cancelInstallation = false; signals: void serverIsBusy(const bool isBusy); }; diff --git a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp index 23697181..c6e7085b 100644 --- a/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp +++ b/client/ui/pages_logic/ServerConfiguringProgressLogic.cpp @@ -59,22 +59,28 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function void { + set_pushButtonCancelVisible(visible); + }; + + return doInstallAction(action, page, progress, noButton, noWaitInfo, busyInfo, cancelButton); } ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function &action, const PageFunc &page, const ProgressFunc &progress, - const ButtonFunc &button, + const ButtonFunc &saveButton, const LabelFunc &waitInfo, - const LabelFunc &serverBusyInfo) + const LabelFunc &serverBusyInfo, + const ButtonFunc &cancelButton) { progress.setVisibleFunc(true); if (page.setEnabledFunc) { page.setEnabledFunc(false); } - if (button.setVisibleFunc) { - button.setVisibleFunc(false); + if (saveButton.setVisibleFunc) { + saveButton.setVisibleFunc(false); } if (waitInfo.setVisibleFunc) { waitInfo.setVisibleFunc(true); @@ -91,33 +97,47 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function &action, const PageFunc &page, const ProgressFunc &progress, - const ButtonFunc &button, + const ButtonFunc &saveButton, const LabelFunc &waitInfo, - const LabelFunc &serverBusyInfo); + const LabelFunc &serverBusyInfo, + const ButtonFunc &cancelButton); + +signals: + void cancelDoInstallAction(const bool cancel); }; #endif // SERVER_CONFIGURING_PROGRESS_LOGIC_H diff --git a/client/ui/pages_logic/protocols/CloakLogic.cpp b/client/ui/pages_logic/protocols/CloakLogic.cpp index 1456e457..6e179013 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.cpp +++ b/client/ui/pages_logic/protocols/CloakLogic.cpp @@ -105,6 +105,11 @@ void CloakLogic::onPushButtonSaveClicked() set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + set_pushButtonCancelVisible(visible); + }; + progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ @@ -114,7 +119,8 @@ void CloakLogic::onPushButtonSaveClicked() newContainerConfig); }, pageFunc, progressBarFunc, - saveButtonFunc, waitInfoFunc, busyInfoFuncy); + saveButtonFunc, waitInfoFunc, + busyInfoFuncy, cancelButtonFunc); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); @@ -123,3 +129,8 @@ void CloakLogic::onPushButtonSaveClicked() qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; } + +void CloakLogic::onPushButtonCancelClicked() +{ + emit uiLogic()->pageLogic()->cancelDoInstallAction(true); +} diff --git a/client/ui/pages_logic/protocols/CloakLogic.h b/client/ui/pages_logic/protocols/CloakLogic.h index 57afb5b0..5c39e8ac 100644 --- a/client/ui/pages_logic/protocols/CloakLogic.h +++ b/client/ui/pages_logic/protocols/CloakLogic.h @@ -25,8 +25,12 @@ class CloakLogic : public PageProtocolLogicBase AUTO_PROPERTY(bool, labelServerBusyVisible) AUTO_PROPERTY(QString, labelServerBusyText) + + AUTO_PROPERTY(bool, pushButtonCancelVisible) + public: Q_INVOKABLE void onPushButtonSaveClicked(); + Q_INVOKABLE void onPushButtonCancelClicked(); public: explicit CloakLogic(UiLogic *uiLogic, QObject *parent = nullptr); diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp index a25fd134..a37b365b 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.cpp +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.cpp @@ -92,7 +92,7 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo set_lineEditPortEnabled(container == DockerContainer::OpenVpn); } -void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() +void OpenVpnLogic::onPushButtonSaveClicked() { QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn); protocolConfig = getProtocolConfigFromPage(protocolConfig); @@ -144,6 +144,11 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + set_pushButtonCancelVisible(visible); + }; + progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ @@ -153,7 +158,8 @@ void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked() newContainerConfig); }, pageFunc, progressBarFunc, - saveButtonFunc, waitInfoFunc, busyInfoFuncy); + saveButtonFunc, waitInfoFunc, + busyInfoFuncy, cancelButtonFunc); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); @@ -178,3 +184,8 @@ QJsonObject OpenVpnLogic::getProtocolConfigFromPage(QJsonObject oldConfig) oldConfig.insert(config_key::additional_server_config, textAreaAdditionalServerConfig()); return oldConfig; } + +void OpenVpnLogic::onPushButtonCancelClicked() +{ + emit uiLogic()->pageLogic()->cancelDoInstallAction(true); +} diff --git a/client/ui/pages_logic/protocols/OpenVpnLogic.h b/client/ui/pages_logic/protocols/OpenVpnLogic.h index 1dafe5ee..dd861238 100644 --- a/client/ui/pages_logic/protocols/OpenVpnLogic.h +++ b/client/ui/pages_logic/protocols/OpenVpnLogic.h @@ -40,8 +40,11 @@ class OpenVpnLogic : public PageProtocolLogicBase AUTO_PROPERTY(bool, labelServerBusyVisible) AUTO_PROPERTY(QString, labelServerBusyText) + AUTO_PROPERTY(bool, pushButtonCancelVisible) + public: - Q_INVOKABLE void onPushButtonProtoOpenVpnSaveClicked(); + Q_INVOKABLE void onPushButtonSaveClicked(); + Q_INVOKABLE void onPushButtonCancelClicked(); public: explicit OpenVpnLogic(UiLogic *uiLogic, QObject *parent = nullptr); diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp index c2575a4d..94a8ee04 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.cpp @@ -97,6 +97,11 @@ void ShadowSocksLogic::onPushButtonSaveClicked() set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + set_pushButtonCancelVisible(visible); + }; + progressBarFunc.setTextVisibleFunc(true); progressBarFunc.setTextFunc(QString("Configuring...")); ErrorCode e = uiLogic()->pageLogic()->doInstallAction([this, containerConfig, &newContainerConfig](){ @@ -106,7 +111,8 @@ void ShadowSocksLogic::onPushButtonSaveClicked() newContainerConfig); }, pageFunc, progressBarFunc, - saveButtonFunc, waitInfoFunc, busyInfoFuncy); + saveButtonFunc, waitInfoFunc, + busyInfoFuncy, cancelButtonFunc); if (!e) { m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig); @@ -114,3 +120,8 @@ void ShadowSocksLogic::onPushButtonSaveClicked() } qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer; } + +void ShadowSocksLogic::onPushButtonCancelClicked() +{ + emit uiLogic()->pageLogic()->cancelDoInstallAction(true); +} diff --git a/client/ui/pages_logic/protocols/ShadowSocksLogic.h b/client/ui/pages_logic/protocols/ShadowSocksLogic.h index 1300511f..da859959 100644 --- a/client/ui/pages_logic/protocols/ShadowSocksLogic.h +++ b/client/ui/pages_logic/protocols/ShadowSocksLogic.h @@ -23,8 +23,12 @@ class ShadowSocksLogic : public PageProtocolLogicBase AUTO_PROPERTY(bool, labelServerBusyVisible) AUTO_PROPERTY(QString, labelServerBusyText) + + AUTO_PROPERTY(bool, pushButtonCancelVisible) + public: Q_INVOKABLE void onPushButtonSaveClicked(); + Q_INVOKABLE void onPushButtonCancelClicked(); public: explicit ShadowSocksLogic(UiLogic *uiLogic, QObject *parent = nullptr); diff --git a/client/ui/qml/Pages/PageServerConfiguringProgress.qml b/client/ui/qml/Pages/PageServerConfiguringProgress.qml index e481dbfe..87c602c3 100644 --- a/client/ui/qml/Pages/PageServerConfiguringProgress.qml +++ b/client/ui/qml/Pages/PageServerConfiguringProgress.qml @@ -10,7 +10,6 @@ PageBase { page: PageEnum.ServerConfiguringProgress logic: ServerConfiguringProgressLogic - enabled: ServerConfiguringProgressLogic.pageEnabled Caption { id: caption text: qsTr("Configuring...") @@ -56,14 +55,27 @@ PageBase { visible: ServerConfiguringProgressLogic.labelWaitInfoVisible } - ProgressBar { - id: pr + + BlueButtonType { + id: pb_cancel + z: 1 anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: logo.bottom anchors.bottomMargin: 40 - width: parent.width - 40 + width: root.width - 60 height: 40 + text: qsTr("Cancel") + visible: ServerConfiguringProgressLogic.pushButtonCancelVisible + enabled: ServerConfiguringProgressLogic.pushButtonCancelVisible + onClicked: { + ServerConfiguringProgressLogic.onPushButtonCancelClicked() + } + } + ProgressBar { + id: pr + enabled: ServerConfiguringProgressLogic.pageEnabled + anchors.fill: pb_cancel from: 0 to: ServerConfiguringProgressLogic.progressBarMaximium value: ServerConfiguringProgressLogic.progressBarValue diff --git a/client/ui/qml/Pages/Protocols/PageProtoCloak.qml b/client/ui/qml/Pages/Protocols/PageProtoCloak.qml index 17dc829a..86a2584a 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoCloak.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoCloak.qml @@ -129,7 +129,6 @@ PageProtocolBase { text: logic.labelInfoText } - ProgressBar { id: progressBar_proto_cloak_reset anchors.horizontalCenter: parent.horizontalCenter @@ -184,4 +183,13 @@ PageProtocolBase { } } + BlueButtonType { + anchors.fill: pb_save + text: qsTr("Cancel") + visible: logic.pushButtonCancelVisible + enabled: logic.pushButtonCancelVisible + onClicked: { + logic.onPushButtonCancelClicked() + } + } } diff --git a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml index a644bf59..19dad8e6 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoOpenVPN.qml @@ -37,7 +37,6 @@ PageProtocolBase { ColumnLayout { id: content - enabled: logic.pageEnabled anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right @@ -45,12 +44,13 @@ PageProtocolBase { LabelType { id: lb_subnet + enabled: logic.pageEnabled height: 21 text: qsTr("VPN Addresses Subnet") } TextFieldType { id: tf_subnet - + enabled: logic.pageEnabled implicitWidth: parent.width height: 31 text: logic.lineEditSubnetText @@ -59,15 +59,16 @@ PageProtocolBase { } } - // LabelType { id: lb_proto + enabled: logic.pageEnabled Layout.topMargin: 20 height: 21 text: qsTr("Network protocol") } Rectangle { id: rect_proto + enabled: logic.pageEnabled implicitWidth: root.width - 60 height: 71 border.width: 1 @@ -99,8 +100,8 @@ PageProtocolBase { } } - // RowLayout { + enabled: logic.pageEnabled Layout.topMargin: 10 Layout.fillWidth: true LabelType { @@ -122,12 +123,9 @@ PageProtocolBase { } } - - - // CheckBoxType { id: check_auto_enc - + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Auto-negotiate encryption") @@ -140,15 +138,16 @@ PageProtocolBase { } } - // LabelType { id: lb_cipher + enabled: logic.pageEnabled height: 21 text: qsTr("Cipher") } ComboBoxType { id: cb_cipher + enabled: logic.pageEnabled && !check_auto_enc.checked implicitWidth: parent.width height: 31 @@ -175,18 +174,18 @@ PageProtocolBase { onCurrentTextChanged: { logic.comboBoxVpnCipherText = currentText } - enabled: !check_auto_enc.checked } - // LabelType { id: lb_hash + enabled: logic.pageEnabled height: 21 Layout.topMargin: 20 text: qsTr("Hash") } ComboBoxType { id: cb_hash + enabled: logic.pageEnabled && !check_auto_enc.checked height: 31 implicitWidth: parent.width model: [ @@ -212,11 +211,11 @@ PageProtocolBase { onCurrentTextChanged: { logic.comboBoxVpnHashText = currentText } - enabled: !check_auto_enc.checked } CheckBoxType { id: check_tls + enabled: logic.pageEnabled implicitWidth: parent.width Layout.topMargin: 20 height: 21 @@ -230,6 +229,7 @@ PageProtocolBase { CheckBoxType { id: check_block_dns + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Block DNS requests outside of VPN") @@ -242,7 +242,7 @@ PageProtocolBase { BasicButtonType { id: pb_client_config - + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Additional client config commands →") @@ -267,6 +267,7 @@ PageProtocolBase { Rectangle { id: rect_client_conf + enabled: logic.pageEnabled implicitWidth: root.width - 60 height: 101 border.width: 1 @@ -288,14 +289,12 @@ PageProtocolBase { } } } - - } BasicButtonType { id: pb_server_config - + enabled: logic.pageEnabled implicitWidth: parent.width height: 21 text: qsTr("Additional server config commands →") @@ -320,6 +319,7 @@ PageProtocolBase { Rectangle { id: rect_server_conf + enabled: logic.pageEnabled implicitWidth: root.width - 60 height: 101 border.width: 1 @@ -347,6 +347,7 @@ PageProtocolBase { LabelType { id: label_server_busy + enabled: logic.pageEnabled horizontalAlignment: Text.AlignHCenter Layout.maximumWidth: parent.width Layout.fillWidth: true @@ -356,6 +357,7 @@ PageProtocolBase { LabelType { id: label_proto_openvpn_info + enabled: logic.pageEnabled horizontalAlignment: Text.AlignHCenter Layout.maximumWidth: parent.width Layout.fillWidth: true @@ -371,18 +373,31 @@ PageProtocolBase { BlueButtonType { id: pb_save + enabled: logic.pageEnabled z: 1 height: 40 text: qsTr("Save and restart VPN") width: parent.width visible: logic.pushButtonSaveVisible onClicked: { - logic.onPushButtonProtoOpenVpnSaveClicked() + logic.onPushButtonSaveClicked() + } + } + + BlueButtonType { + z: 1 + anchors.fill: pb_save + text: qsTr("Cancel") + visible: logic.pushButtonCancelVisible + enabled: logic.pushButtonCancelVisible + onClicked: { + logic.onPushButtonCancelClicked() } } ProgressBar { id: progress_save + enabled: logic.pageEnabled anchors.fill: pb_save from: 0 to: logic.progressBarResetMaximium diff --git a/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml b/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml index 3fe0df26..4d627fe2 100644 --- a/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml +++ b/client/ui/qml/Pages/Protocols/PageProtoShadowSocks.qml @@ -162,4 +162,14 @@ PageProtocolBase { logic.onPushButtonSaveClicked() } } + + BlueButtonType { + anchors.fill: pb_save + text: qsTr("Cancel") + visible: logic.pushButtonCancelVisible + enabled: logic.pushButtonCancelVisible + onClicked: { + logic.onPushButtonCancelClicked() + } + } } diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index 9d43f414..ef50c464 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -346,6 +346,11 @@ void UiLogic::installServer(QMap &containers) pageLogic()->set_labelServerBusyVisible(visible); }; + ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc; + cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void { + pageLogic()->set_pushButtonCancelVisible(visible); + }; + int count = 0; ErrorCode error; for (QMap::iterator i = containers.begin(); i != containers.end(); i++, count++) { @@ -353,7 +358,7 @@ void UiLogic::installServer(QMap &containers) error = pageLogic()->doInstallAction([&] () { return m_serverController->setupContainer(installCredentials, i.key(), i.value()); - }, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc); + }, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc, cancelButtonFunc); m_serverController->disconnectFromHost(installCredentials); } From 19a41b2792d0e5600ef0d7760392459691d53bff Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Sun, 15 Jan 2023 18:47:16 +0300 Subject: [PATCH 08/12] swapped "Clear client cached profile" and "Clear server from Amnesia software" buttons --- client/ui/qml/Pages/PageServerSettings.qml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/ui/qml/Pages/PageServerSettings.qml b/client/ui/qml/Pages/PageServerSettings.qml index 1d3a281f..921cc8d9 100644 --- a/client/ui/qml/Pages/PageServerSettings.qml +++ b/client/ui/qml/Pages/PageServerSettings.qml @@ -87,19 +87,19 @@ PageBase { BlueButtonType { Layout.fillWidth: true Layout.topMargin: 60 - text: ServerSettingsLogic.pushButtonClearText - visible: ServerSettingsLogic.pushButtonClearVisible + text: ServerSettingsLogic.pushButtonClearClientCacheText + visible: ServerSettingsLogic.pushButtonClearClientCacheVisible onClicked: { - ServerSettingsLogic.onPushButtonClearServer() + ServerSettingsLogic.onPushButtonClearClientCacheClicked() } } BlueButtonType { Layout.fillWidth: true Layout.topMargin: 10 - text: ServerSettingsLogic.pushButtonClearClientCacheText - visible: ServerSettingsLogic.pushButtonClearClientCacheVisible + text: ServerSettingsLogic.pushButtonClearText + visible: ServerSettingsLogic.pushButtonClearVisible onClicked: { - ServerSettingsLogic.onPushButtonClearClientCacheClicked() + ServerSettingsLogic.onPushButtonClearServer() } } BlueButtonType { From 3175b0c4ffee77a1d93592113336c4516ee84e33 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Mon, 16 Jan 2023 16:20:12 +0300 Subject: [PATCH 09/12] Changed the indentation of the "Installed Protocols and Services" heading on the "Server Containers" page --- client/ui/qml/Pages/PageServerContainers.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/ui/qml/Pages/PageServerContainers.qml b/client/ui/qml/Pages/PageServerContainers.qml index bab16c68..4b8383e6 100644 --- a/client/ui/qml/Pages/PageServerContainers.qml +++ b/client/ui/qml/Pages/PageServerContainers.qml @@ -190,12 +190,12 @@ PageBase { left: parent.left; right: parent.right; } - topPadding: 20 spacing: 10 Caption { id: cap1 text: qsTr("Installed Protocols and Services") + leftPadding: -20 font.pixelSize: 20 } From 44d2627e2a08d6444e3d7b0408a05c36bc32ace8 Mon Sep 17 00:00:00 2001 From: pokamest Date: Mon, 16 Jan 2023 17:11:00 +0000 Subject: [PATCH 10/12] Tiny fix [no ci] --- client/settings.cpp | 2 +- client/settings.h | 2 +- client/ui/pages_logic/VpnLogic.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/settings.cpp b/client/settings.cpp index efc63314..135e87ba 100644 --- a/client/settings.cpp +++ b/client/settings.cpp @@ -217,7 +217,7 @@ void Settings::setSaveLogs(bool enabled) qWarning() << "Initialization of debug subsystem failed"; } } - emit updateVpnPage(); + emit saveLogsChanged(); } QString Settings::routeModeString(RouteMode mode) const diff --git a/client/settings.h b/client/settings.h index 25f03773..28a49e18 100644 --- a/client/settings.h +++ b/client/settings.h @@ -114,7 +114,7 @@ public: bool restoreAppConfig(const QByteArray &cfg) { return m_settings.restoreAppConfig(cfg); } signals: - void updateVpnPage(); + void saveLogsChanged(); private: SecureQSettings m_settings; diff --git a/client/ui/pages_logic/VpnLogic.cpp b/client/ui/pages_logic/VpnLogic.cpp index 1fd69c6b..5f6cf077 100644 --- a/client/ui/pages_logic/VpnLogic.cpp +++ b/client/ui/pages_logic/VpnLogic.cpp @@ -33,7 +33,7 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent): connect(this, &VpnLogic::connectToVpn, uiLogic()->m_vpnConnection, &VpnConnection::connectToVpn, Qt::QueuedConnection); connect(this, &VpnLogic::disconnectFromVpn, uiLogic()->m_vpnConnection, &VpnConnection::disconnectFromVpn, Qt::QueuedConnection); - connect(m_settings.get(), &Settings::updateVpnPage, this, &VpnLogic::onUpdatePage); + connect(m_settings.get(), &Settings::saveLogsChanged, this, &VpnLogic::onUpdatePage); if (m_settings->isAutoConnect() && m_settings->defaultServerIndex() >= 0) { QTimer::singleShot(1000, this, [this](){ From 9f114a1dad1354c9b2d63cc7816fbc7d03cbdcc1 Mon Sep 17 00:00:00 2001 From: pokamest Date: Mon, 16 Jan 2023 18:12:30 +0000 Subject: [PATCH 11/12] Tiny fix [no ci] --- client/server_scripts/install_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/server_scripts/install_docker.sh b/client/server_scripts/install_docker.sh index e12ab2c1..baff7cb6 100644 --- a/client/server_scripts/install_docker.sh +++ b/client/server_scripts/install_docker.sh @@ -3,7 +3,7 @@ if [[ -f "$pm_apt" ]]; then pm=$pm_apt; docker_pkg="docker.io"; else pm=$pm_yum; if [[ ! -f "/usr/bin/sudo" ]]; then $pm update -y -q; $pm install -y -q sudo; fi;\ docker_service=$(systemctl list-units --full -all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ if [[ -f "$pm_apt" ]]; then export DEBIAN_FRONTEND=noninteractive; fi;\ -if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y -q curl $docker_pkg; fi;\ +if [[ -z "$docker_service" ]]; then sudo $pm update -y -q; sudo $pm install -y -q curl $docker_pkg; fi;\ docker_service=$(systemctl list-units --full -all | grep docker.service | grep -v inactive | grep -v dead | grep -v failed);\ if [[ -z "$docker_service" ]]; then sleep 5 && sudo systemctl start docker && sleep 5; fi;\ docker --version From b9717e98947a71589c071c6e6fede67b61381afc Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Tue, 17 Jan 2023 17:11:45 +0300 Subject: [PATCH 12/12] removed unused code --- client/CMakeLists.txt | 2 - client/client.pro | 2 - client/resources.qrc | 1 - client/ui/framelesswindow.cpp | 314 ---------------------------------- client/ui/framelesswindow.h | 158 ----------------- client/ui/qml/TitleBar.qml | 38 ---- client/ui/qml/main.qml | 4 +- client/ui/uilogic.cpp | 26 --- 8 files changed, 2 insertions(+), 543 deletions(-) delete mode 100644 client/ui/framelesswindow.cpp delete mode 100644 client/ui/framelesswindow.h delete mode 100644 client/ui/qml/TitleBar.qml diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 1a1f052d..857185e9 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -134,12 +134,10 @@ if(WIN32) set(HEADERS ${HEADERS} ${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.h - ${CMAKE_CURRENT_LIST_DIR}/ui/framelesswindow.h ) set(SOURCES ${SOURCES} ${CMAKE_CURRENT_LIST_DIR}/protocols/ikev2_vpn_protocol_windows.cpp - ${CMAKE_CURRENT_LIST_DIR}/ui/framelesswindow.cpp ) set(RESOURCES ${RESOURCES} diff --git a/client/client.pro b/client/client.pro index 13383b7c..f96c9944 100644 --- a/client/client.pro +++ b/client/client.pro @@ -164,11 +164,9 @@ win32 { HEADERS += \ protocols/ikev2_vpn_protocol_windows.h \ - ui/framelesswindow.h SOURCES += \ protocols/ikev2_vpn_protocol_windows.cpp \ - ui/framelesswindow.cpp VERSION = 2.0.0.0 QMAKE_TARGET_COMPANY = "AmneziaVPN" diff --git a/client/resources.qrc b/client/resources.qrc index 0c325062..040bf750 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -62,7 +62,6 @@ server_scripts/website_tor/configure_container.sh server_scripts/website_tor/run_container.sh ui/qml/main.qml - ui/qml/TitleBar.qml ui/qml/Pages/PageBase.qml ui/qml/Pages/PageAppSetting.qml ui/qml/Pages/PageGeneralSettings.qml diff --git a/client/ui/framelesswindow.cpp b/client/ui/framelesswindow.cpp deleted file mode 100644 index 489ea134..00000000 --- a/client/ui/framelesswindow.cpp +++ /dev/null @@ -1,314 +0,0 @@ -// This code is a part of Qt-Nice-Frameless-Window -// https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window -// Licensed by MIT License - https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window/blob/master/LICENSE - - -#include "framelesswindow.h" -#include -#include -#include -#include -#include - -#ifdef Q_OS_WIN - -#include -#include -#include -#include -#include // Fixes error C2504: 'IUnknown' : base class undefined -#include -#include -#pragma comment (lib,"Dwmapi.lib") // Adds missing library, fixes error LNK2019: unresolved external symbol __imp__DwmExtendFrameIntoClientArea -#pragma comment (lib,"user32.lib") - -CFramelessWindow::CFramelessWindow(QWidget *parent) - : QMainWindow(parent), - m_titlebar(Q_NULLPTR), - m_borderWidth(5), - m_bJustMaximized(false), - m_bResizeable(true) -{ -// setWindowFlag(Qt::Window,true); -// setWindowFlag(Qt::FramelessWindowHint, true); -// setWindowFlag(Qt::WindowSystemMenuHint, true); -// setWindowFlag() is not avaliable before Qt v5.9, so we should use setWindowFlags instead - - if (QOperatingSystemVersion::current() > QOperatingSystemVersion::Windows7) { - setWindowFlags(windowFlags() | Qt::Window | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint); - setResizeable(m_bResizeable); - } -} - -void CFramelessWindow::setResizeable(bool resizeable) -{ - bool visible = isVisible(); - m_bResizeable = resizeable; - if (m_bResizeable){ - setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint); -// setWindowFlag(Qt::WindowMaximizeButtonHint); - - //此行代码可以带回Aero效果,同时也带回了标题栏和边框,在nativeEvent()会再次去掉标题栏 - // - //this line will get titlebar/thick frame/Aero back, which is exactly what we want - //we will get rid of titlebar and thick frame again in nativeEvent() later - HWND hwnd = (HWND)this->winId(); - DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); - ::SetWindowLong(hwnd, GWL_STYLE, style | WS_MAXIMIZEBOX | WS_THICKFRAME | WS_CAPTION); - }else{ - setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint); -// setWindowFlag(Qt::WindowMaximizeButtonHint,false); - - HWND hwnd = (HWND)this->winId(); - DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); - ::SetWindowLong(hwnd, GWL_STYLE, style & ~WS_MAXIMIZEBOX & ~WS_CAPTION); - } - - //保留一个像素的边框宽度,否则系统不会绘制边框阴影 - // - //we better left 1 piexl width of border untouch, so OS can draw nice shadow around it - const MARGINS shadow = { 1, 1, 1, 1 }; - DwmExtendFrameIntoClientArea(HWND(winId()), &shadow); - - setVisible(visible); -} - -void CFramelessWindow::setResizeableAreaWidth(int width) -{ - if (1 > width) width = 1; - m_borderWidth = width; -} - -void CFramelessWindow::setTitleBar(QWidget* titlebar) -{ - m_titlebar = titlebar; - if (!titlebar) return; - connect(titlebar, SIGNAL(destroyed(QObject*)), this, SLOT(onTitleBarDestroyed())); -} - -void CFramelessWindow::onTitleBarDestroyed() -{ - if (m_titlebar == QObject::sender()) - { - m_titlebar = Q_NULLPTR; - } -} - -void CFramelessWindow::addIgnoreWidget(QWidget* widget) -{ - if (!widget) return; - if (m_whiteList.contains(widget)) return; - m_whiteList.append(widget); -} - -bool CFramelessWindow::nativeEvent(const QByteArray &eventType, void *message, long *result) -{ - if (QOperatingSystemVersion::current() <= QOperatingSystemVersion::Windows7) { - return QMainWindow::nativeEvent(eventType, message, reinterpret_cast(result)); - } - - //Workaround for known bug -> check Qt forum : https://forum.qt.io/topic/93141/qtablewidget-itemselectionchanged/13 - #if (QT_VERSION == QT_VERSION_CHECK(5, 11, 1)) - MSG* msg = *reinterpret_cast(message); - #else - MSG* msg = reinterpret_cast(message); - #endif - - switch (msg->message) - { - case WM_NCCALCSIZE: - { - NCCALCSIZE_PARAMS& params = *reinterpret_cast(msg->lParam); - if (params.rgrc[0].top != 0) - params.rgrc[0].top -= 1; - - //this kills the window frame and title bar we added with WS_THICKFRAME and WS_CAPTION - *result = WVR_REDRAW; - return true; - } - case WM_NCHITTEST: - { - *result = 0; - - const LONG border_width = m_borderWidth; - RECT winrect; - GetWindowRect(HWND(winId()), &winrect); - - long x = GET_X_LPARAM(msg->lParam); - long y = GET_Y_LPARAM(msg->lParam); - - if(m_bResizeable) - { - - bool resizeWidth = minimumWidth() != maximumWidth(); - bool resizeHeight = minimumHeight() != maximumHeight(); - - if(resizeWidth) - { - //left border - if (x >= winrect.left && x < winrect.left + border_width) - { - *result = HTLEFT; - } - //right border - if (x < winrect.right && x >= winrect.right - border_width) - { - *result = HTRIGHT; - } - } - if(resizeHeight) - { - //bottom border - if (y < winrect.bottom && y >= winrect.bottom - border_width) - { - *result = HTBOTTOM; - } - //top border - if (y >= winrect.top && y < winrect.top + border_width) - { - *result = HTTOP; - } - } - if(resizeWidth && resizeHeight) - { - //bottom left corner - if (x >= winrect.left && x < winrect.left + border_width && - y < winrect.bottom && y >= winrect.bottom - border_width) - { - *result = HTBOTTOMLEFT; - } - //bottom right corner - if (x < winrect.right && x >= winrect.right - border_width && - y < winrect.bottom && y >= winrect.bottom - border_width) - { - *result = HTBOTTOMRIGHT; - } - //top left corner - if (x >= winrect.left && x < winrect.left + border_width && - y >= winrect.top && y < winrect.top + border_width) - { - *result = HTTOPLEFT; - } - //top right corner - if (x < winrect.right && x >= winrect.right - border_width && - y >= winrect.top && y < winrect.top + border_width) - { - *result = HTTOPRIGHT; - } - } - } - if (0!=*result) return true; - - //*result still equals 0, that means the cursor locate OUTSIDE the frame area - //but it may locate in titlebar area - if (!m_titlebar) return false; - - //support highdpi - double dpr = this->devicePixelRatioF(); - QPoint pos = m_titlebar->mapFromGlobal(QPoint(x/dpr,y/dpr)); - - if (!m_titlebar->rect().contains(pos)) return false; - QWidget* child = m_titlebar->childAt(pos); - if (!child) - { - *result = HTCAPTION; - return true; - }else{ - if (m_whiteList.contains(child)) - { - *result = HTCAPTION; - return true; - } - } - return false; - } //end case WM_NCHITTEST - case WM_GETMINMAXINFO: - { - if (::IsZoomed(msg->hwnd)) { - RECT frame = { 0, 0, 0, 0 }; - AdjustWindowRectEx(&frame, WS_OVERLAPPEDWINDOW, FALSE, 0); - - //record frame area data - double dpr = this->devicePixelRatioF(); - - m_frames.setLeft(abs(frame.left)/dpr+0.5); - m_frames.setTop(abs(frame.bottom)/dpr+0.5); - m_frames.setRight(abs(frame.right)/dpr+0.5); - m_frames.setBottom(abs(frame.bottom)/dpr+0.5); - - QMainWindow::setContentsMargins(m_frames.left()+m_margins.left(), \ - m_frames.top()+m_margins.top(), \ - m_frames.right()+m_margins.right(), \ - m_frames.bottom()+m_margins.bottom()); - m_bJustMaximized = true; - }else { - if (m_bJustMaximized) - { - QMainWindow::setContentsMargins(m_margins); - m_frames = QMargins(); - m_bJustMaximized = false; - } - } - return false; - } - default: - return QMainWindow::nativeEvent(eventType, message, reinterpret_cast(result)); - } -} - -void CFramelessWindow::setContentsMargins(const QMargins &margins) -{ - QMainWindow::setContentsMargins(margins+m_frames); - m_margins = margins; -} -void CFramelessWindow::setContentsMargins(int left, int top, int right, int bottom) -{ - QMainWindow::setContentsMargins(left+m_frames.left(),\ - top+m_frames.top(), \ - right+m_frames.right(), \ - bottom+m_frames.bottom()); - m_margins.setLeft(left); - m_margins.setTop(top); - m_margins.setRight(right); - m_margins.setBottom(bottom); -} -QMargins CFramelessWindow::contentsMargins() const -{ - QMargins margins = QMainWindow::contentsMargins(); - margins -= m_frames; - return margins; -} -void CFramelessWindow::getContentsMargins(int *left, int *top, int *right, int *bottom) const -{ - getContentsMargins(left,top,right,bottom); - if (!(left&&top&&right&&bottom)) return; - if (isMaximized()) - { - *left -= m_frames.left(); - *top -= m_frames.top(); - *right -= m_frames.right(); - *bottom -= m_frames.bottom(); - } -} -QRect CFramelessWindow::contentsRect() const -{ - QRect rect = QMainWindow::contentsRect(); - int width = rect.width(); - int height = rect.height(); - rect.setLeft(rect.left() - m_frames.left()); - rect.setTop(rect.top() - m_frames.top()); - rect.setWidth(width); - rect.setHeight(height); - return rect; -} -void CFramelessWindow::showFullScreen() -{ - if (isMaximized()) - { - QMainWindow::setContentsMargins(m_margins); - m_frames = QMargins(); - } - QMainWindow::showFullScreen(); -} - -#endif //Q_OS_WIN diff --git a/client/ui/framelesswindow.h b/client/ui/framelesswindow.h deleted file mode 100644 index ac560231..00000000 --- a/client/ui/framelesswindow.h +++ /dev/null @@ -1,158 +0,0 @@ -// This code is a part of Qt-Nice-Frameless-Window -// https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window -// Licensed by MIT License - https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window/blob/master/LICENSE - - -#ifndef CFRAMELESSWINDOW_H -#define CFRAMELESSWINDOW_H -#include "qsystemdetection.h" -#include -#include - -//A nice frameless window for both Windows and OS X -//Author: Bringer-of-Light -//Github: https://github.com/Bringer-of-Light/Qt-Nice-Frameless-Window -// Usage: use "CFramelessWindow" as base class instead of "QMainWindow", and enjoy -#ifdef Q_OS_WIN -#include -#include -#include -#include -class CFramelessWindow : public QMainWindow -{ - Q_OBJECT -public: - explicit CFramelessWindow(QWidget *parent = 0); -public: - - //设置是否可以通过鼠标调整窗口大小 - //if resizeable is set to false, then the window can not be resized by mouse - //but still can be resized programtically - void setResizeable(bool resizeable=true); - bool isResizeable(){return m_bResizeable;} - - //设置可调整大小区域的宽度,在此区域内,可以使用鼠标调整窗口大小 - //set border width, inside this aera, window can be resized by mouse - void setResizeableAreaWidth(int width = 5); -protected: - //设置一个标题栏widget,此widget会被当做标题栏对待 - //set a widget which will be treat as SYSTEM titlebar - void setTitleBar(QWidget* titlebar); - - //在标题栏控件内,也可以有子控件如标签控件“label1”,此label1遮盖了标题栏,导致不能通过label1拖动窗口 - //要解决此问题,使用addIgnoreWidget(label1) - //generally, we can add widget say "label1" on titlebar, and it will cover the titlebar under it - //as a result, we can not drag and move the MainWindow with this "label1" again - //we can fix this by add "label1" to a ignorelist, just call addIgnoreWidget(label1) - void addIgnoreWidget(QWidget* widget); - - bool nativeEvent(const QByteArray &eventType, void *message, long *result); -private slots: - void onTitleBarDestroyed(); -public: - void setContentsMargins(const QMargins &margins); - void setContentsMargins(int left, int top, int right, int bottom); - QMargins contentsMargins() const; - QRect contentsRect() const; - void getContentsMargins(int *left, int *top, int *right, int *bottom) const; -public slots: - void showFullScreen(); -private: - QWidget* m_titlebar; - QList m_whiteList; - int m_borderWidth; - - QMargins m_margins; - QMargins m_frames; - bool m_bJustMaximized; - - bool m_bResizeable; -}; - -#elif defined Q_OS_MAC || defined Q_OS_LINUX -#include -#include -#include -class CFramelessWindow : public QMainWindow -{ - Q_OBJECT -public: - explicit CFramelessWindow(QWidget *parent = 0); -private: - void initUI(); -public: - //设置可拖动区域的高度,在此区域内,可以通过鼠标拖动窗口, 0表示整个窗口都可拖动 - //In draggable area, window can be moved by mouse, (height = 0) means that the whole window is draggable - void setDraggableAreaHeight(int height = 0); - - //只有OS X10.10及以后系统,才支持OS X原生样式包括:三个系统按钮、窗口圆角、窗口阴影 - //类初始化完成后,可以通过此函数查看是否已经启用了原生样式。如果未启动,需要自定义关闭按钮、最小化按钮、最大化按钮 - //Native style(three system button/ round corner/ drop shadow) works only on OS X 10.10 or later - //after init, we should check whether NativeStyle is OK with this function - //if NOT ok, we should implement close button/ min button/ max button ourself - bool isNativeStyleOK() {return m_bNativeSystemBtn;} - - //如果设置setCloseBtnQuit(false),那么点击关闭按钮后,程序不会退出,而是会隐藏,只有在OS X 10.10 及以后系统中有效 - //if setCloseBtnQuit(false), then when close button is clicked, the application will hide itself instead of quit - //be carefull, after you set this to false, you can NOT change it to true again - //this function should be called inside of the constructor function of derived classes, and can NOT be called more than once - //only works for OS X 10.10 or later - void setCloseBtnQuit(bool bQuit = true); - - //启用或禁用关闭按钮,只有在isNativeStyleOK()返回true的情况下才有效 - //enable or disable Close button, only worked if isNativeStyleOK() returns true - void setCloseBtnEnabled(bool bEnable = true); - - //启用或禁用最小化按钮,只有在isNativeStyleOK()返回true的情况下才有效 - //enable or disable Miniaturize button, only worked if isNativeStyleOK() returns true - void setMinBtnEnabled(bool bEnable = true); - - //启用或禁用zoom(最大化)按钮,只有在isNativeStyleOK()返回true的情况下才有效 - //enable or disable Zoom button(fullscreen button), only worked if isNativeStyleOK() returns true - void setZoomBtnEnabled(bool bEnable = true); - - bool isCloseBtnEnabled() {return m_bIsCloseBtnEnabled;} - bool isMinBtnEnabled() {return m_bIsMinBtnEnabled;} - bool isZoomBtnEnabled() {return m_bIsZoomBtnEnabled;} -protected: - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); -private: - int m_draggableHeight; - bool m_bWinMoving; - bool m_bMousePressed; - QPoint m_MousePos; - QPoint m_WindowPos; - bool m_bCloseBtnQuit; - bool m_bNativeSystemBtn; - bool m_bIsCloseBtnEnabled, m_bIsMinBtnEnabled, m_bIsZoomBtnEnabled; - - //=============================================== - //TODO - //下面的代码是试验性质的 - //tentative code - - //窗口从全屏状态恢复正常大小时,标题栏又会出现,原因未知。 - //默认情况下,系统的最大化按钮(zoom button)是进入全屏,为了避免标题栏重新出现的问题, - //以上代码已经重新定义了系统zoom button的行为,是其功能变为最大化而不是全屏 - //以下代码尝试,每次窗口从全屏状态恢复正常大小时,都再次进行设置,以消除标题栏 - //after the window restore from fullscreen mode, the titlebar will show again, it looks like a BUG - //on OS X 10.10 and later, click the system green button (zoom button) will make the app become fullscreen - //so we have override it's action to "maximized" in the CFramelessWindow Constructor function - //but we may try something else such as delete the titlebar again and again... -private: - bool m_bTitleBarVisible; - - void setTitlebarVisible(bool bTitlebarVisible = false); - bool isTitlebarVisible() {return m_bTitleBarVisible;} -private slots: - void onRestoreFromFullScreen(); -signals: - void restoreFromFullScreen(); -protected: - void resizeEvent(QResizeEvent *event); -}; -#endif - -#endif // CFRAMELESSWINDOW_H diff --git a/client/ui/qml/TitleBar.qml b/client/ui/qml/TitleBar.qml deleted file mode 100644 index cf6aed8a..00000000 --- a/client/ui/qml/TitleBar.qml +++ /dev/null @@ -1,38 +0,0 @@ -import QtQuick -import QtQuick.Controls -import "./" -import "Config" - -Rectangle { - id: root - color: "#F5F5F5" - width: GC.screenWidth - height: 30 - signal closeButtonClicked() - - Button { - id: closeButton - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 5 - icon.source: "qrc:/images/close.png" - icon.width: 16 - icon.height: 16 - width: height - height: 20 - background: Item {} - contentItem: Image { - source: closeButton.icon.source - anchors.fill: closeButton - anchors.margins: ms.containsMouse ? 3 : 4 - } - MouseArea { - id: ms - hoverEnabled: true - anchors.fill: closeButton - } - onClicked: { - root.closeButtonClicked() - } - } -} diff --git a/client/ui/qml/main.qml b/client/ui/qml/main.qml index 101dd384..7f631f96 100644 --- a/client/ui/qml/main.qml +++ b/client/ui/qml/main.qml @@ -85,14 +85,14 @@ Window { } Rectangle { - y: GC.isDesktop() ? titleBar.height : 0 + y: 0 anchors.fill: parent color: "white" } StackView { id: pageLoader - y: GC.isDesktop() ? titleBar.height : 0 + y: 0 anchors.fill: parent focus: true diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index 94da8103..2393f99e 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -267,32 +267,6 @@ void UiLogic::onGotoCurrentProtocolsPage() emit goToPage(Page::ServerContainers); } -//void UiLogic::showEvent(QShowEvent *event) -//{ -//#if defined Q_OS_MACX -// if (!event->spontaneous()) { -// setDockIconVisible(true); -// } -// if (needToHideCustomTitlebar) { -// ui->widget_tittlebar->hide(); -// resize(width(), 640); -// ui->stackedWidget_main->move(0,0); -// } -//#endif -//} - -//void UiLogic::hideEvent(QHideEvent *event) -//{ -//#if defined Q_OS_MACX -// if (!event->spontaneous()) { -// setDockIconVisible(false); -// } -//#endif -//} - - - - void UiLogic::installServer(QMap &containers) { if (containers.isEmpty()) return;