Merge branch 'qt_migration' of github.com:amnezia-vpn/desktop-client into feature/qt6-client-management-panel
This commit is contained in:
commit
8ea80a616e
54 changed files with 876 additions and 1778 deletions
|
@ -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()
|
||||
|
@ -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}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
|
||||
#include "core/servercontroller.h"
|
||||
#include "debug.h"
|
||||
#include "logger.h"
|
||||
#include "defines.h"
|
||||
#include <QQuickStyle>
|
||||
|
||||
|
@ -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();
|
||||
});
|
||||
|
|
|
@ -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 \
|
||||
|
@ -85,9 +85,6 @@ HEADERS += \
|
|||
utilities.h \
|
||||
vpnconnection.h \
|
||||
protocols/vpnprotocol.h \
|
||||
logger.h \
|
||||
loghandler.h \
|
||||
loglevel.h \
|
||||
constants.h \
|
||||
platforms/ios/QRCodeReaderBase.h
|
||||
|
||||
|
@ -106,7 +103,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 \
|
||||
|
@ -146,8 +143,6 @@ SOURCES += \
|
|||
utilities.cpp \
|
||||
vpnconnection.cpp \
|
||||
protocols/vpnprotocol.cpp \
|
||||
logger.cpp \
|
||||
loghandler.cpp \
|
||||
platforms/ios/QRCodeReaderBase.cpp
|
||||
|
||||
RESOURCES += \
|
||||
|
@ -164,11 +159,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"
|
||||
|
|
|
@ -31,6 +31,7 @@ enum ErrorCode
|
|||
ServerPortAlreadyAllocatedError,
|
||||
ServerContainerMissingError,
|
||||
ServerDockerFailedError,
|
||||
ServerCancelInstallation,
|
||||
|
||||
// Ssh connection errors
|
||||
SshSocketError, SshTimeoutError, SshProtocolError,
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include <QApplication>
|
||||
#include <QTemporaryFile>
|
||||
#include <QFileInfo>
|
||||
#include <QThread>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include "sftpchannel.h"
|
||||
#include "sshconnectionmanager.h"
|
||||
|
@ -79,7 +81,7 @@ ErrorCode ServerController::runScript(const ServerCredentials &credentials, QStr
|
|||
}
|
||||
|
||||
qDebug().noquote() << "EXEC" << lineToExec;
|
||||
Debug::appendSshLog("Run command:" + lineToExec);
|
||||
Logger::appendSshLog("Run command:" + lineToExec);
|
||||
|
||||
QSharedPointer<SshRemoteProcess> proc = client->createRemoteProcess(lineToExec.toUtf8());
|
||||
|
||||
|
@ -105,7 +107,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 +116,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 +142,7 @@ ErrorCode ServerController::runContainerScript(const ServerCredentials &credenti
|
|||
const std::function<void (const QString &, QSharedPointer<QSsh::SshRemoteProcess>)> &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;
|
||||
|
@ -528,14 +530,45 @@ ErrorCode ServerController::installDockerWorker(const ServerCredentials &credent
|
|||
stdOut += data + "\n";
|
||||
};
|
||||
|
||||
ErrorCode e = runScript(credentials,
|
||||
replaceVars(amnezia::scriptData(SharedScriptType::install_docker),
|
||||
genVarsForScript(credentials)),
|
||||
cbReadStdOut, cbReadStdErr);
|
||||
QFutureWatcher<ErrorCode> watcher;
|
||||
|
||||
QFuture<ErrorCode> 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),
|
||||
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());
|
||||
return ErrorCode::NoError;
|
||||
});
|
||||
|
||||
watcher.setFuture(future);
|
||||
|
||||
QEventLoop wait;
|
||||
QObject::connect(&watcher, &QFutureWatcher<ErrorCode>::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);
|
||||
|
||||
if (stdOut.contains("command not found")) return ErrorCode::ServerDockerFailedError;
|
||||
|
||||
return e;
|
||||
return error;
|
||||
}
|
||||
|
||||
ErrorCode ServerController::prepareHostWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||
|
@ -796,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));
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <QObject>
|
||||
#include "sshconnection.h"
|
||||
#include "sshremoteprocess.h"
|
||||
#include "debug.h"
|
||||
#include "logger.h"
|
||||
#include "defs.h"
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
|
@ -73,7 +73,9 @@ public:
|
|||
QString checkSshConnection(const ServerCredentials &credentials, ErrorCode *errorCode = nullptr);
|
||||
QSsh::SshConnection *connectToHost(const QSsh::SshConnectionParameters &sshParams);
|
||||
|
||||
ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||
void setCancelInstallation(const bool cancel);
|
||||
|
||||
ErrorCode startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config = QJsonObject());
|
||||
private:
|
||||
|
||||
ErrorCode installDockerWorker(const ServerCredentials &credentials, DockerContainer container);
|
||||
|
@ -84,6 +86,10 @@ private:
|
|||
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
||||
|
||||
bool m_cancelInstallation = false;
|
||||
signals:
|
||||
void serverIsBusy(const bool isBusy);
|
||||
};
|
||||
|
||||
#endif // SERVERCONTROLLER_H
|
||||
|
|
173
client/debug.cpp
173
client/debug.cpp
|
@ -1,173 +0,0 @@
|
|||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <QUrl>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "debug.h"
|
||||
#include "defines.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
#include <core/ipcclient.h>
|
||||
#endif
|
||||
|
||||
QFile Debug::m_file;
|
||||
QTextStream Debug::m_textStream;
|
||||
QString Debug::m_logFileName = QString("%1.log").arg(APPLICATION_NAME);
|
||||
|
||||
void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg)
|
||||
{
|
||||
if (msg.simplified().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip annoying messages from Qt
|
||||
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font")) {
|
||||
return;
|
||||
}
|
||||
|
||||
Debug::m_textStream << qFormatLogMessage(type, context, msg) << Qt::endl << Qt::flush;
|
||||
Debug::appendAllLog(qFormatLogMessage(type, context, msg));
|
||||
|
||||
std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl << std::flush;
|
||||
}
|
||||
|
||||
Debug &Debug::Instance()
|
||||
{
|
||||
static Debug s;
|
||||
return s;
|
||||
}
|
||||
|
||||
void Debug::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)
|
||||
{
|
||||
Instance().m_allLog.append(log + "\n");
|
||||
emit Instance().allLogChanged(Instance().allLog());
|
||||
}
|
||||
|
||||
bool Debug::init()
|
||||
{
|
||||
qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} %{type} %{message}");
|
||||
|
||||
QString path = userLogsDir();
|
||||
QDir appDir(path);
|
||||
if (!appDir.mkpath(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_file.setFileName(appDir.filePath(m_logFileName));
|
||||
if (!m_file.open(QIODevice::Append)) {
|
||||
qWarning() << "Cannot open log file:" << m_logFileName;
|
||||
return false;
|
||||
}
|
||||
m_file.setTextModeEnabled(true);
|
||||
m_textStream.setDevice(&m_file);
|
||||
|
||||
#ifndef QT_DEBUG
|
||||
qInstallMessageHandler(debugMessageHandler);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Debug::userLogsDir()
|
||||
{
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log";
|
||||
}
|
||||
|
||||
QString Debug::userLogsFilePath()
|
||||
{
|
||||
return userLogsDir() + QDir::separator() + m_logFileName;
|
||||
}
|
||||
|
||||
QString Debug::getLogFile()
|
||||
{
|
||||
m_file.flush();
|
||||
QFile file(userLogsFilePath());
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
return file.readAll();
|
||||
}
|
||||
|
||||
bool Debug::openLogsFolder()
|
||||
{
|
||||
QString path = userLogsDir();
|
||||
#ifdef Q_OS_WIN
|
||||
path = "file:///" + path;
|
||||
#endif
|
||||
if (!QDesktopServices::openUrl(QUrl::fromLocalFile(path))) {
|
||||
qWarning() << "Can't open url:" << path;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Debug::openServiceLogsFolder()
|
||||
{
|
||||
QString path = Utils::systemLogPath();
|
||||
path = "file:///" + path;
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Debug::appLogFileNamePath()
|
||||
{
|
||||
return m_file.fileName();
|
||||
}
|
||||
|
||||
void Debug::clearLogs()
|
||||
{
|
||||
bool isLogActive = m_file.isOpen();
|
||||
m_file.close();
|
||||
|
||||
QFile file(userLogsFilePath());
|
||||
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
file.resize(0);
|
||||
file.close();
|
||||
|
||||
if (isLogActive) {
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
void Debug::clearServiceLogs()
|
||||
{
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
IpcClient *m_IpcClient = new IpcClient;
|
||||
|
||||
if (!m_IpcClient->isSocketConnected()) {
|
||||
if (!IpcClient::init(m_IpcClient)) {
|
||||
qWarning() << "Error occured when init IPC client";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IpcClient->Interface()) {
|
||||
m_IpcClient->Interface()->setLogsEnabled(false);
|
||||
m_IpcClient->Interface()->cleanUp();
|
||||
}
|
||||
else {
|
||||
qWarning() << "Error occured cleaning up service logs";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Debug::cleanUp()
|
||||
{
|
||||
clearLogs();
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||
dir.removeRecursively();
|
||||
|
||||
clearServiceLogs();
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
#ifndef DEBUG_H
|
||||
#define DEBUG_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
|
||||
#include "ui/property_helper.h"
|
||||
|
||||
class Debug : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
AUTO_PROPERTY(QString, sshLog)
|
||||
AUTO_PROPERTY(QString, allLog)
|
||||
|
||||
public:
|
||||
static Debug& Instance();
|
||||
|
||||
static void appendSshLog(const QString &log);
|
||||
static void appendAllLog(const QString &log);
|
||||
|
||||
|
||||
static bool init();
|
||||
static bool openLogsFolder();
|
||||
static bool openServiceLogsFolder();
|
||||
static QString appLogFileNamePath();
|
||||
static void clearLogs();
|
||||
static void clearServiceLogs();
|
||||
static void cleanUp();
|
||||
|
||||
static QString userLogsFilePath();
|
||||
static QString getLogFile();
|
||||
|
||||
private:
|
||||
Debug() {}
|
||||
Debug(Debug const &) = delete;
|
||||
Debug& operator= (Debug const&) = delete;
|
||||
|
||||
static QString userLogsDir();
|
||||
|
||||
static QFile m_file;
|
||||
static QTextStream m_textStream;
|
||||
static QString m_logFileName;
|
||||
|
||||
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
|
||||
};
|
||||
|
||||
#endif // DEBUG_H
|
|
@ -1,59 +1,182 @@
|
|||
/* 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) {}
|
||||
#include <QDateTime>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <QUrl>
|
||||
|
||||
Logger::Logger(const QStringList& modules, const QString& className)
|
||||
: m_modules(modules), m_className(className) {}
|
||||
#include <iostream>
|
||||
|
||||
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); }
|
||||
#include "defines.h"
|
||||
#include "utilities.h"
|
||||
|
||||
Logger::Log::Log(Logger* logger, LogLevel logLevel)
|
||||
: m_logger(logger), m_logLevel(logLevel), m_data(new Data()) {}
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
#include <core/ipcclient.h>
|
||||
#endif
|
||||
|
||||
Logger::Log::~Log() {
|
||||
LogHandler::messageHandler(m_logLevel, m_logger->modules(),
|
||||
m_logger->className(), m_data->m_buffer.trimmed());
|
||||
delete m_data;
|
||||
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)
|
||||
{
|
||||
if (msg.simplified().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip annoying messages from Qt
|
||||
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font")) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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 &Logger::Instance()
|
||||
{
|
||||
static Logger s;
|
||||
return s;
|
||||
}
|
||||
|
||||
Logger::Log& Logger::Log::operator<<(QTextStreamFunction t) {
|
||||
m_data->m_ts << t;
|
||||
return *this;
|
||||
void Logger::appendSshLog(const QString &log)
|
||||
{
|
||||
QString dt = QDateTime::currentDateTime().toString();
|
||||
Instance().m_sshLog.append(dt + ": " + log + "\n");
|
||||
emit Instance().sshLogChanged(Instance().sshLog());
|
||||
}
|
||||
|
||||
// static
|
||||
QString Logger::sensitive(const QString& input) {
|
||||
#ifdef QT_DEBUG
|
||||
return input;
|
||||
#else
|
||||
return QString(input.length(), 'X');
|
||||
void Logger::appendAllLog(const QString &log)
|
||||
{
|
||||
Instance().m_allLog.append(log + "\n");
|
||||
emit Instance().allLogChanged(Instance().allLog());
|
||||
}
|
||||
|
||||
bool Logger::init()
|
||||
{
|
||||
qSetMessagePattern("%{time yyyy-MM-dd hh:mm:ss} %{type} %{message}");
|
||||
|
||||
QString path = userLogsDir();
|
||||
QDir appDir(path);
|
||||
if (!appDir.mkpath(path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_file.setFileName(appDir.filePath(m_logFileName));
|
||||
if (!m_file.open(QIODevice::Append)) {
|
||||
qWarning() << "Cannot open log file:" << m_logFileName;
|
||||
return false;
|
||||
}
|
||||
m_file.setTextModeEnabled(true);
|
||||
m_textStream.setDevice(&m_file);
|
||||
|
||||
#ifndef QT_DEBUG
|
||||
qInstallMessageHandler(debugMessageHandler);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Logger::deInit()
|
||||
{
|
||||
qInstallMessageHandler(nullptr);
|
||||
qSetMessagePattern("%{message}");
|
||||
m_textStream.setDevice(nullptr);
|
||||
m_file.close();
|
||||
}
|
||||
|
||||
QString Logger::userLogsDir()
|
||||
{
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/log";
|
||||
}
|
||||
|
||||
QString Logger::userLogsFilePath()
|
||||
{
|
||||
return userLogsDir() + QDir::separator() + m_logFileName;
|
||||
}
|
||||
|
||||
QString Logger::getLogFile()
|
||||
{
|
||||
m_file.flush();
|
||||
QFile file(userLogsFilePath());
|
||||
|
||||
file.open(QIODevice::ReadOnly);
|
||||
return file.readAll();
|
||||
}
|
||||
|
||||
bool Logger::openLogsFolder()
|
||||
{
|
||||
QString path = userLogsDir();
|
||||
#ifdef Q_OS_WIN
|
||||
path = "file:///" + path;
|
||||
#endif
|
||||
if (!QDesktopServices::openUrl(QUrl::fromLocalFile(path))) {
|
||||
qWarning() << "Can't open url:" << path;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Logger::openServiceLogsFolder()
|
||||
{
|
||||
QString path = Utils::systemLogPath();
|
||||
path = "file:///" + path;
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Logger::appLogFileNamePath()
|
||||
{
|
||||
return m_file.fileName();
|
||||
}
|
||||
|
||||
void Logger::clearLogs()
|
||||
{
|
||||
bool isLogActive = m_file.isOpen();
|
||||
m_file.close();
|
||||
|
||||
QFile file(userLogsFilePath());
|
||||
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||
file.resize(0);
|
||||
file.close();
|
||||
|
||||
if (isLogActive) {
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::clearServiceLogs()
|
||||
{
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
IpcClient *m_IpcClient = new IpcClient;
|
||||
|
||||
if (!m_IpcClient->isSocketConnected()) {
|
||||
if (!IpcClient::init(m_IpcClient)) {
|
||||
qWarning() << "Error occured when init IPC client";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_IpcClient->Interface()) {
|
||||
m_IpcClient->Interface()->setLogsEnabled(false);
|
||||
m_IpcClient->Interface()->cleanUp();
|
||||
}
|
||||
else {
|
||||
qWarning() << "Error occured cleaning up service logs";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Logger::cleanUp()
|
||||
{
|
||||
clearLogs();
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||
dir.removeRecursively();
|
||||
|
||||
clearServiceLogs();
|
||||
}
|
||||
|
|
105
client/logger.h
105
client/logger.h
|
@ -1,90 +1,51 @@
|
|||
/* 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 <QDebug>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QIODevice>
|
||||
#include <QTextStream>
|
||||
|
||||
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";
|
||||
#include "ui/property_helper.h"
|
||||
|
||||
#if defined(MVPN_LINUX) || defined(MVPN_ANDROID)
|
||||
constexpr const char* LOG_LINUX = "linux";
|
||||
#endif
|
||||
class Logger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
AUTO_PROPERTY(QString, sshLog)
|
||||
AUTO_PROPERTY(QString, allLog)
|
||||
|
||||
#ifdef MVPN_WINDOWS
|
||||
constexpr const char* LOG_WINDOWS = "windows";
|
||||
#endif
|
||||
public:
|
||||
static Logger& Instance();
|
||||
|
||||
#if __APPLE__ || defined(MVPN_WASM)
|
||||
constexpr const char* LOG_MACOS = "macos";
|
||||
constexpr const char* LOG_IOS = "ios";
|
||||
#endif
|
||||
static void appendSshLog(const QString &log);
|
||||
static void appendAllLog(const QString &log);
|
||||
|
||||
#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);
|
||||
static bool init();
|
||||
static void deInit();
|
||||
static bool openLogsFolder();
|
||||
static bool openServiceLogsFolder();
|
||||
static QString appLogFileNamePath();
|
||||
static void clearLogs();
|
||||
static void clearServiceLogs();
|
||||
static void cleanUp();
|
||||
|
||||
const QStringList& modules() const { return m_modules; }
|
||||
const QString& className() const { return m_className; }
|
||||
static QString userLogsFilePath();
|
||||
static QString getLogFile();
|
||||
|
||||
class Log {
|
||||
public:
|
||||
Log(Logger* logger, LogLevel level);
|
||||
~Log();
|
||||
private:
|
||||
Logger() {}
|
||||
Logger(Logger const &) = delete;
|
||||
Logger& operator= (Logger const&) = delete;
|
||||
|
||||
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);
|
||||
static QString userLogsDir();
|
||||
|
||||
private:
|
||||
Logger* m_logger;
|
||||
LogLevel m_logLevel;
|
||||
static QFile m_file;
|
||||
static QTextStream m_textStream;
|
||||
static QString m_logFileName;
|
||||
|
||||
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;
|
||||
friend void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
|
||||
};
|
||||
|
||||
#endif // LOGGER_H
|
||||
#endif // LOGGER_H
|
||||
|
|
|
@ -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 <QDate>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QMessageLogContext>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QStandardPaths>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
|
||||
#ifdef MVPN_ANDROID
|
||||
# include <android/log.h>
|
||||
#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<QMutex>& 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<QMutex>& 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<QMutex>& 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<QMutex>& 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<QMutex>& 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<QMutex>& 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<QMutex>& 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<QMutex>& proofOfLock) {
|
||||
Q_UNUSED(proofOfLock);
|
||||
|
||||
if (m_logFile) {
|
||||
delete m_output;
|
||||
m_output = nullptr;
|
||||
|
||||
delete m_logFile;
|
||||
m_logFile = nullptr;
|
||||
}
|
||||
}
|
|
@ -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 <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QVector>
|
||||
#include <QMutexLocker>
|
||||
|
||||
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<QMutex>& proofOfLock);
|
||||
|
||||
static LogHandler* maybeCreate(const QMutexLocker<QMutex>& proofOfLock);
|
||||
|
||||
void addLog(const Log& log, const QMutexLocker<QMutex>& proofOfLock);
|
||||
|
||||
bool matchLogLevel(const Log& log, const QMutexLocker<QMutex>& proofOfLock) const;
|
||||
bool matchModule(const Log& log, const QMutexLocker<QMutex>& proofOfLock) const;
|
||||
|
||||
void openLogFile(const QMutexLocker<QMutex>& proofOfLock);
|
||||
|
||||
void closeLogFile(const QMutexLocker<QMutex>& proofOfLock);
|
||||
|
||||
static void cleanupLogFile(const QMutexLocker<QMutex>& proofOfLock);
|
||||
|
||||
const LogLevel m_minLogLevel;
|
||||
const QStringList m_modules;
|
||||
bool m_showDebug = false;
|
||||
|
||||
QFile* m_logFile = nullptr;
|
||||
QTextStream* m_output = nullptr;
|
||||
};
|
||||
|
||||
#endif // LOGHANDLER_H
|
|
@ -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
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <chrono>
|
||||
|
||||
#include "debug.h"
|
||||
#include "logger.h"
|
||||
#include "ikev2_vpn_protocol_windows.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <QTcpServer>
|
||||
#include <QRandomGenerator>
|
||||
|
||||
#include "debug.h"
|
||||
#include "logger.h"
|
||||
#include "defines.h"
|
||||
#include "utilities.h"
|
||||
#include "openvpnprotocol.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "shadowsocksvpnprotocol.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "logger.h"
|
||||
#include "utilities.h"
|
||||
#include "containers/containers_defs.h"
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <QTcpSocket>
|
||||
#include <QThread>
|
||||
|
||||
#include "debug.h"
|
||||
#include "logger.h"
|
||||
#include "wireguardprotocol.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@
|
|||
<file>server_scripts/website_tor/configure_container.sh</file>
|
||||
<file>server_scripts/website_tor/run_container.sh</file>
|
||||
<file>ui/qml/main.qml</file>
|
||||
<file>ui/qml/TitleBar.qml</file>
|
||||
<file>ui/qml/Pages/PageBase.qml</file>
|
||||
<file>ui/qml/Pages/PageAppSetting.qml</file>
|
||||
<file>ui/qml/Pages/PageGeneralSettings.qml</file>
|
||||
|
@ -134,6 +133,7 @@
|
|||
<file>ui/qml/Controls/SvgButtonType.qml</file>
|
||||
<file>ui/qml/Config/GlobalConfig.qml</file>
|
||||
<file>ui/qml/Config/qmldir</file>
|
||||
<file>server_scripts/check_server_is_busy.sh</file>
|
||||
<file>server_scripts/dns/configure_container.sh</file>
|
||||
<file>server_scripts/dns/Dockerfile</file>
|
||||
<file>server_scripts/dns/run_container.sh</file>
|
||||
|
|
4
client/server_scripts/check_server_is_busy.sh
Normal file
4
client/server_scripts/check_server_is_busy.sh
Normal file
|
@ -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
|
|
@ -3,6 +3,7 @@
|
|||
#include "utilities.h"
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "logger.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()) {
|
||||
Logger::deInit();
|
||||
} else {
|
||||
if (!Logger::init()) {
|
||||
qWarning() << "Initialization of debug subsystem failed";
|
||||
}
|
||||
}
|
||||
emit saveLogsChanged();
|
||||
}
|
||||
|
||||
QString Settings::routeModeString(RouteMode mode) const
|
||||
{
|
||||
switch (mode) {
|
||||
|
|
|
@ -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 saveLogsChanged();
|
||||
|
||||
private:
|
||||
SecureQSettings m_settings;
|
||||
|
||||
|
|
|
@ -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 <QApplication>
|
||||
#include <QPoint>
|
||||
#include <QSize>
|
||||
#include <QSysInfo>
|
||||
#include <QOperatingSystemVersion>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
#include <windows.h>
|
||||
#include <WinUser.h>
|
||||
#include <windowsx.h>
|
||||
#include <dwmapi.h>
|
||||
#include <objidl.h> // Fixes error C2504: 'IUnknown' : base class undefined
|
||||
#include <gdiplus.h>
|
||||
#include <GdiPlusColor.h>
|
||||
#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<qintptr*>(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<MSG**>(message);
|
||||
#else
|
||||
MSG* msg = reinterpret_cast<MSG*>(message);
|
||||
#endif
|
||||
|
||||
switch (msg->message)
|
||||
{
|
||||
case WM_NCCALCSIZE:
|
||||
{
|
||||
NCCALCSIZE_PARAMS& params = *reinterpret_cast<NCCALCSIZE_PARAMS*>(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<qintptr*>(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
|
|
@ -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 <QObject>
|
||||
#include <QMainWindow>
|
||||
|
||||
//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 <QWidget>
|
||||
#include <QList>
|
||||
#include <QMargins>
|
||||
#include <QRect>
|
||||
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<QWidget*> 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 <QMouseEvent>
|
||||
#include <QResizeEvent>
|
||||
#include <QPoint>
|
||||
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
|
|
@ -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()
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include <QEventLoop>
|
||||
#include <QMessageBox>
|
||||
|
||||
#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<Er
|
|||
page.setEnabledFunc = [this] (bool enabled) -> 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,20 +51,42 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
|
|||
return progressBarMaximium();
|
||||
};
|
||||
|
||||
LabelFunc busyInfo;
|
||||
busyInfo.setTextFunc = [this] (const QString& text) -> void {
|
||||
set_labelServerBusyText(text);
|
||||
};
|
||||
busyInfo.setVisibleFunc = [this] (bool visible) -> void {
|
||||
set_labelServerBusyVisible(visible);
|
||||
};
|
||||
|
||||
ButtonFunc cancelButton;
|
||||
cancelButton.setVisibleFunc = [this] (bool visible) -> void {
|
||||
set_pushButtonCancelVisible(visible);
|
||||
};
|
||||
|
||||
return doInstallAction(action, page, progress, noButton, noWaitInfo, busyInfo, cancelButton);
|
||||
}
|
||||
|
||||
ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<ErrorCode()> &action,
|
||||
const PageFunc &page,
|
||||
const ProgressFunc &progress,
|
||||
const ButtonFunc &saveButton,
|
||||
const LabelFunc &waitInfo,
|
||||
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 (info.setVisibleFunc) {
|
||||
info.setVisibleFunc(true);
|
||||
if (waitInfo.setVisibleFunc) {
|
||||
waitInfo.setVisibleFunc(true);
|
||||
}
|
||||
if (info.setTextFunc) {
|
||||
info.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes"));
|
||||
if (waitInfo.setTextFunc) {
|
||||
waitInfo.setTextFunc(tr("Please wait, configuring process may take up to 5 minutes"));
|
||||
}
|
||||
|
||||
QTimer timer;
|
||||
|
@ -71,18 +97,50 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
|
|||
progress.setValueFunc(0);
|
||||
timer.start(1000);
|
||||
|
||||
QMetaObject::Connection cancelDoInstallActionConnection;
|
||||
if (cancelButton.setVisibleFunc) {
|
||||
cancelDoInstallActionConnection = connect(this, &ServerConfiguringProgressLogic::cancelDoInstallAction,
|
||||
m_serverController.get(), &ServerController::setCancelInstallation);
|
||||
}
|
||||
|
||||
|
||||
QMetaObject::Connection serverBusyConnection;
|
||||
if (serverBusyInfo.setVisibleFunc && serverBusyInfo.setTextFunc) {
|
||||
serverBusyConnection = connect(m_serverController.get(),
|
||||
&ServerController::serverIsBusy,
|
||||
this,
|
||||
[&serverBusyInfo, &timer, &cancelButton](const bool isBusy) {
|
||||
isBusy ? timer.stop() : timer.start(1000);
|
||||
serverBusyInfo.setVisibleFunc(isBusy);
|
||||
serverBusyInfo.setTextFunc(isBusy ? "Amnesia has detected that your server is currently "
|
||||
"busy installing other software. Amnesia installation "
|
||||
"will pause until the server finishes installing other software"
|
||||
: "");
|
||||
if (cancelButton.setVisibleFunc) {
|
||||
cancelButton.setVisibleFunc(isBusy ? true : false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ErrorCode e = action();
|
||||
qDebug() << "doInstallAction finished with code" << e;
|
||||
if (cancelButton.setVisibleFunc) {
|
||||
disconnect(cancelDoInstallActionConnection);
|
||||
}
|
||||
|
||||
if (serverBusyInfo.setVisibleFunc && serverBusyInfo.setTextFunc) {
|
||||
disconnect(serverBusyConnection);
|
||||
}
|
||||
|
||||
if (e) {
|
||||
if (page.setEnabledFunc) {
|
||||
page.setEnabledFunc(true);
|
||||
}
|
||||
if (button.setVisibleFunc) {
|
||||
button.setVisibleFunc(true);
|
||||
if (saveButton.setVisibleFunc) {
|
||||
saveButton.setVisibleFunc(true);
|
||||
}
|
||||
if (info.setVisibleFunc) {
|
||||
info.setVisibleFunc(false);
|
||||
if (waitInfo.setVisibleFunc) {
|
||||
waitInfo.setVisibleFunc(false);
|
||||
}
|
||||
QMessageBox::warning(nullptr, APPLICATION_NAME,
|
||||
tr("Error occurred while configuring server.") + "\n" +
|
||||
|
@ -95,9 +153,9 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
|
|||
// just ui progressbar tweak
|
||||
timer.stop();
|
||||
|
||||
int remaining_val = progress.getMaximiumFunc() - progress.getValueFunc();
|
||||
int remainingVal = progress.getMaximiumFunc() - progress.getValueFunc();
|
||||
|
||||
if (remaining_val > 0) {
|
||||
if (remainingVal > 0) {
|
||||
QTimer timer1;
|
||||
QEventLoop loop1;
|
||||
|
||||
|
@ -114,14 +172,19 @@ ErrorCode ServerConfiguringProgressLogic::doInstallAction(const std::function<Er
|
|||
|
||||
|
||||
progress.setVisibleFunc(false);
|
||||
if (button.setVisibleFunc) {
|
||||
button.setVisibleFunc(true);
|
||||
if (saveButton.setVisibleFunc) {
|
||||
saveButton.setVisibleFunc(true);
|
||||
}
|
||||
if (page.setEnabledFunc) {
|
||||
page.setEnabledFunc(true);
|
||||
}
|
||||
if (info.setTextFunc) {
|
||||
info.setTextFunc(tr("Operation finished"));
|
||||
if (waitInfo.setTextFunc) {
|
||||
waitInfo.setTextFunc(tr("Operation finished"));
|
||||
}
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
void ServerConfiguringProgressLogic::onPushButtonCancelClicked()
|
||||
{
|
||||
cancelDoInstallAction(true);
|
||||
}
|
||||
|
|
|
@ -20,13 +20,12 @@ class ServerConfiguringProgressLogic : public PageLogicBase
|
|||
AUTO_PROPERTY(int, progressBarMaximium)
|
||||
AUTO_PROPERTY(bool, progressBarTextVisible)
|
||||
AUTO_PROPERTY(QString, progressBarText)
|
||||
AUTO_PROPERTY(bool, labelServerBusyVisible)
|
||||
AUTO_PROPERTY(QString, labelServerBusyText)
|
||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
||||
|
||||
public:
|
||||
explicit ServerConfiguringProgressLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
~ServerConfiguringProgressLogic() = default;
|
||||
|
||||
void onUpdatePage() override;
|
||||
ErrorCode doInstallAction(const std::function<ErrorCode()> &action);
|
||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
||||
|
||||
private:
|
||||
struct ProgressFunc {
|
||||
|
@ -48,5 +47,27 @@ private:
|
|||
std::function<void(const QString&)> 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<ErrorCode()> &action);
|
||||
ErrorCode doInstallAction(const std::function<ErrorCode()> &action,
|
||||
const PageFunc &page,
|
||||
const ProgressFunc &progress,
|
||||
const ButtonFunc &saveButton,
|
||||
const LabelFunc &waitInfo,
|
||||
const LabelFunc &serverBusyInfo,
|
||||
const ButtonFunc &cancelButton);
|
||||
|
||||
signals:
|
||||
void cancelDoInstallAction(const bool cancel);
|
||||
|
||||
};
|
||||
#endif // SERVER_CONFIGURING_PROGRESS_LOGIC_H
|
||||
|
|
|
@ -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::saveLogsChanged, 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());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "CloakLogic.h"
|
||||
#include "core/servercontroller.h"
|
||||
|
||||
#include <functional>
|
||||
#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,65 @@ 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);
|
||||
};
|
||||
|
||||
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
||||
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||
set_pushButtonCancelVisible(visible);
|
||||
};
|
||||
|
||||
progressBarFunc.setTextVisibleFunc(true);
|
||||
progressBarFunc.setTextFunc(QString("Configuring..."));
|
||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->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, cancelButtonFunc);
|
||||
|
||||
if (!e) {
|
||||
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
|
||||
|
@ -101,3 +129,8 @@ void CloakLogic::onPushButtonSaveClicked()
|
|||
|
||||
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
|
||||
}
|
||||
|
||||
void CloakLogic::onPushButtonCancelClicked()
|
||||
{
|
||||
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
||||
}
|
||||
|
|
|
@ -20,9 +20,17 @@ 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)
|
||||
|
||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
||||
|
||||
public:
|
||||
Q_INVOKABLE void onPushButtonSaveClicked();
|
||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
||||
|
||||
public:
|
||||
explicit CloakLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "OpenVpnLogic.h"
|
||||
#include "core/servercontroller.h"
|
||||
|
||||
#include <functional>
|
||||
#include "../../uilogic.h"
|
||||
|
||||
#include "core/servercontroller.h"
|
||||
#include "ui/uilogic.h"
|
||||
#include "ui/pages_logic/ServerConfiguringProgressLogic.h"
|
||||
|
||||
using namespace amnezia;
|
||||
using namespace PageEnumNS;
|
||||
|
@ -100,7 +103,7 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo
|
|||
set_isThirdPartyConfig(openvpnConfig.value(config_key::isThirdPartyConfig).isBool());
|
||||
}
|
||||
|
||||
void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
|
||||
void OpenVpnLogic::onPushButtonSaveClicked()
|
||||
{
|
||||
QJsonObject protocolConfig = m_settings->protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn);
|
||||
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
||||
|
@ -109,40 +112,65 @@ 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);
|
||||
};
|
||||
|
||||
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
||||
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||
set_pushButtonCancelVisible(visible);
|
||||
};
|
||||
|
||||
progressBarFunc.setTextVisibleFunc(true);
|
||||
progressBarFunc.setTextFunc(QString("Configuring..."));
|
||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->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, cancelButtonFunc);
|
||||
|
||||
if (!e) {
|
||||
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
|
||||
|
@ -167,3 +195,8 @@ QJsonObject OpenVpnLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|||
oldConfig.insert(config_key::additional_server_config, textAreaAdditionalServerConfig());
|
||||
return oldConfig;
|
||||
}
|
||||
|
||||
void OpenVpnLogic::onPushButtonCancelClicked()
|
||||
{
|
||||
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
||||
}
|
||||
|
|
|
@ -34,12 +34,20 @@ 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)
|
||||
|
||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
||||
|
||||
AUTO_PROPERTY(QString, openVpnLastConfigText)
|
||||
AUTO_PROPERTY(bool, isThirdPartyConfig)
|
||||
|
||||
public:
|
||||
Q_INVOKABLE void onPushButtonProtoOpenVpnSaveClicked();
|
||||
Q_INVOKABLE void onPushButtonSaveClicked();
|
||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
||||
|
||||
public:
|
||||
explicit OpenVpnLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "ShadowSocksLogic.h"
|
||||
#include "core/servercontroller.h"
|
||||
|
||||
#include <functional>
|
||||
#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,65 @@ 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);
|
||||
};
|
||||
|
||||
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
||||
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||
set_pushButtonCancelVisible(visible);
|
||||
};
|
||||
|
||||
progressBarFunc.setTextVisibleFunc(true);
|
||||
progressBarFunc.setTextFunc(QString("Configuring..."));
|
||||
ErrorCode e = uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->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, cancelButtonFunc);
|
||||
|
||||
if (!e) {
|
||||
m_settings->setContainerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, newContainerConfig);
|
||||
|
@ -92,3 +120,8 @@ void ShadowSocksLogic::onPushButtonSaveClicked()
|
|||
}
|
||||
qDebug() << "Protocol saved with code:" << e << "for" << uiLogic()->selectedServerIndex << uiLogic()->selectedDockerContainer;
|
||||
}
|
||||
|
||||
void ShadowSocksLogic::onPushButtonCancelClicked()
|
||||
{
|
||||
emit uiLogic()->pageLogic<ServerConfiguringProgressLogic>()->cancelDoInstallAction(true);
|
||||
}
|
||||
|
|
|
@ -12,15 +12,23 @@ 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)
|
||||
|
||||
AUTO_PROPERTY(bool, pushButtonCancelVisible)
|
||||
|
||||
public:
|
||||
Q_INVOKABLE void onPushButtonSaveClicked();
|
||||
Q_INVOKABLE void onPushButtonCancelClicked();
|
||||
|
||||
public:
|
||||
explicit ShadowSocksLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
|
|
|
@ -10,7 +10,6 @@ PageBase {
|
|||
page: PageEnum.ServerConfiguringProgress
|
||||
logic: ServerConfiguringProgressLogic
|
||||
|
||||
enabled: ServerConfiguringProgressLogic.pageEnabled
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Configuring...")
|
||||
|
@ -27,6 +26,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
|
||||
|
@ -40,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
|
||||
|
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
@ -96,19 +96,19 @@ PageBase {
|
|||
BlueButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 10
|
||||
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 {
|
||||
|
|
|
@ -31,6 +31,7 @@ PageBase {
|
|||
}
|
||||
|
||||
UrlButtonType {
|
||||
id: button_donate
|
||||
y: 10
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: 21
|
||||
|
@ -55,6 +56,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"
|
||||
|
|
|
@ -14,6 +14,7 @@ PageProtocolBase {
|
|||
enabled: logic.pageEnabled
|
||||
BackButton {
|
||||
id: back
|
||||
enabled: logic.pageEnabled
|
||||
}
|
||||
|
||||
Caption {
|
||||
|
@ -110,17 +111,24 @@ 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
|
||||
}
|
||||
|
||||
|
||||
ProgressBar {
|
||||
id: progressBar_proto_cloak_reset
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
@ -146,6 +154,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
|
||||
|
@ -162,4 +183,13 @@ PageProtocolBase {
|
|||
}
|
||||
}
|
||||
|
||||
BlueButtonType {
|
||||
anchors.fill: pb_save
|
||||
text: qsTr("Cancel")
|
||||
visible: logic.pushButtonCancelVisible
|
||||
enabled: logic.pushButtonCancelVisible
|
||||
onClicked: {
|
||||
logic.onPushButtonCancelClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ PageProtocolBase {
|
|||
|
||||
BackButton {
|
||||
id: back
|
||||
enabled: logic.pageEnabled
|
||||
}
|
||||
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("OpenVPN Settings")
|
||||
|
@ -33,16 +35,17 @@ PageProtocolBase {
|
|||
|
||||
ColumnLayout {
|
||||
visible: !logic.isThirdPartyConfig
|
||||
enabled: logic.pageEnabled
|
||||
|
||||
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
|
||||
|
@ -51,15 +54,17 @@ 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: parent.width
|
||||
height: 71
|
||||
border.width: 1
|
||||
|
@ -91,8 +96,8 @@ PageProtocolBase {
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
RowLayout {
|
||||
enabled: logic.pageEnabled
|
||||
Layout.topMargin: 10
|
||||
Layout.fillWidth: true
|
||||
LabelType {
|
||||
|
@ -114,12 +119,9 @@ PageProtocolBase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
CheckBoxType {
|
||||
id: check_auto_enc
|
||||
|
||||
enabled: logic.pageEnabled
|
||||
implicitWidth: parent.width
|
||||
height: 21
|
||||
text: qsTr("Auto-negotiate encryption")
|
||||
|
@ -132,15 +134,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
|
||||
|
@ -167,18 +170,19 @@ 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: [
|
||||
|
@ -204,11 +208,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
|
||||
|
@ -222,6 +226,7 @@ PageProtocolBase {
|
|||
|
||||
CheckBoxType {
|
||||
id: check_block_dns
|
||||
enabled: logic.pageEnabled
|
||||
implicitWidth: parent.width
|
||||
height: 21
|
||||
text: qsTr("Block DNS requests outside of VPN")
|
||||
|
@ -231,10 +236,9 @@ PageProtocolBase {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
BasicButtonType {
|
||||
id: pb_client_config
|
||||
|
||||
enabled: logic.pageEnabled
|
||||
implicitWidth: parent.width
|
||||
height: 21
|
||||
text: qsTr("Additional client config commands →")
|
||||
|
@ -259,6 +263,7 @@ PageProtocolBase {
|
|||
|
||||
Rectangle {
|
||||
id: rect_client_conf
|
||||
enabled: logic.pageEnabled
|
||||
implicitWidth: root.width - 60
|
||||
height: 101
|
||||
border.width: 1
|
||||
|
@ -284,10 +289,9 @@ PageProtocolBase {
|
|||
|
||||
}
|
||||
|
||||
|
||||
BasicButtonType {
|
||||
id: pb_server_config
|
||||
|
||||
enabled: logic.pageEnabled
|
||||
implicitWidth: parent.width
|
||||
height: 21
|
||||
text: qsTr("Additional server config commands →")
|
||||
|
@ -312,6 +316,7 @@ PageProtocolBase {
|
|||
|
||||
Rectangle {
|
||||
id: rect_server_conf
|
||||
enabled: logic.pageEnabled
|
||||
implicitWidth: root.width - 60
|
||||
height: 101
|
||||
border.width: 1
|
||||
|
@ -338,8 +343,21 @@ PageProtocolBase {
|
|||
}
|
||||
|
||||
LabelType {
|
||||
id: label_proto_openvpn_info
|
||||
id: label_server_busy
|
||||
enabled: logic.pageEnabled
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.maximumWidth: parent.width
|
||||
Layout.fillWidth: true
|
||||
visible: logic.labelServerBusyVisible
|
||||
text: logic.labelServerBusyText
|
||||
}
|
||||
|
||||
LabelType {
|
||||
id: label_proto_openvpn_info
|
||||
enabled: logic.pageEnabled
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
Layout.maximumWidth: parent.width
|
||||
Layout.fillWidth: true
|
||||
height: 41
|
||||
visible: logic.labelProtoOpenVpnInfoVisible
|
||||
text: logic.labelProtoOpenVpnInfoText
|
||||
|
@ -353,13 +371,25 @@ 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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -389,6 +419,19 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -412,5 +455,4 @@ PageProtocolBase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
@ -142,4 +162,14 @@ PageProtocolBase {
|
|||
logic.onPushButtonSaveClicked()
|
||||
}
|
||||
}
|
||||
|
||||
BlueButtonType {
|
||||
anchors.fill: pb_save
|
||||
text: qsTr("Cancel")
|
||||
visible: logic.pushButtonCancelVisible
|
||||
enabled: logic.pushButtonCancelVisible
|
||||
onClicked: {
|
||||
logic.onPushButtonCancelClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -88,14 +88,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
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include "ui/qautostart.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "logger.h"
|
||||
#include "defines.h"
|
||||
#include "uilogic.h"
|
||||
#include "utilities.h"
|
||||
|
@ -193,9 +193,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:
|
||||
|
@ -270,32 +270,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<DockerContainer, QJsonObject> &containers)
|
||||
{
|
||||
if (containers.isEmpty()) return;
|
||||
|
@ -306,44 +280,67 @@ void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &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<ServerConfiguringProgressLogic>()->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<ServerConfiguringProgressLogic>()->set_labelWaitInfoText(text);
|
||||
};
|
||||
label_new_server_configuring_wait_info.setVisibleFunc = [this] (bool visible) ->void {
|
||||
waitInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||
pageLogic<ServerConfiguringProgressLogic>()->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<ServerConfiguringProgressLogic>()->set_progressBarVisible(visible);
|
||||
};
|
||||
progressBar_new_server_configuring.setValueFunc = [this] (int value) ->void {
|
||||
progressBarFunc.setValueFunc = [this] (int value) -> void {
|
||||
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarValue(value);
|
||||
};
|
||||
progressBar_new_server_configuring.getValueFunc = [this] (void) -> int {
|
||||
progressBarFunc.getValueFunc = [this] (void) -> int {
|
||||
return pageLogic<ServerConfiguringProgressLogic>()->progressBarValue();
|
||||
};
|
||||
progressBar_new_server_configuring.getMaximiumFunc = [this] (void) -> int {
|
||||
progressBarFunc.getMaximiumFunc = [this] (void) -> int {
|
||||
return pageLogic<ServerConfiguringProgressLogic>()->progressBarMaximium();
|
||||
};
|
||||
progressBar_new_server_configuring.setTextVisibleFunc = [this] (bool visible) ->void {
|
||||
progressBarFunc.setTextVisibleFunc = [this] (bool visible) -> void {
|
||||
pageLogic<ServerConfiguringProgressLogic>()->set_progressBarTextVisible(visible);
|
||||
};
|
||||
progressBar_new_server_configuring.setTextFunc = [this] (const QString& text) ->void {
|
||||
progressBarFunc.setTextFunc = [this] (const QString& text) -> void {
|
||||
pageLogic<ServerConfiguringProgressLogic>()->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<ServerConfiguringProgressLogic>()->set_labelServerBusyText(text);
|
||||
};
|
||||
busyInfoFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||
pageLogic<ServerConfiguringProgressLogic>()->set_labelServerBusyVisible(visible);
|
||||
};
|
||||
|
||||
ServerConfiguringProgressLogic::ButtonFunc cancelButtonFunc;
|
||||
cancelButtonFunc.setVisibleFunc = [this] (bool visible) -> void {
|
||||
pageLogic<ServerConfiguringProgressLogic>()->set_pushButtonCancelVisible(visible);
|
||||
};
|
||||
|
||||
int count = 0;
|
||||
ErrorCode error;
|
||||
for (QMap<DockerContainer, QJsonObject>::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<ServerConfiguringProgressLogic>()->doInstallAction([&] () {
|
||||
return m_serverController->setupContainer(installCredentials, i.key(), i.value());
|
||||
}, pageFunc, progressBarFunc, noButton, waitInfoFunc, busyInfoFunc, cancelButtonFunc);
|
||||
|
||||
m_serverController->disconnectFromHost(installCredentials);
|
||||
}
|
||||
|
||||
if (error == ErrorCode::NoError) {
|
||||
QJsonObject server;
|
||||
server.insert(config_key::hostName, installCredentials.hostName);
|
||||
server.insert(config_key::userName, installCredentials.userName);
|
||||
|
@ -370,182 +367,6 @@ void UiLogic::installServer(QMap<DockerContainer, QJsonObject> &containers)
|
|||
}
|
||||
}
|
||||
|
||||
bool UiLogic::installContainers(ServerCredentials credentials,
|
||||
QMap<DockerContainer, QJsonObject> &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<DockerContainer, QJsonObject>::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<ErrorCode()> &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);
|
||||
|
|
|
@ -143,38 +143,6 @@ private slots:
|
|||
|
||||
private:
|
||||
PageEnumNS::Page currentPage();
|
||||
struct ProgressFunc {
|
||||
std::function<void(bool)> setVisibleFunc;
|
||||
std::function<void(int)> setValueFunc;
|
||||
std::function<int(void)> getValueFunc;
|
||||
std::function<int(void)> getMaximiumFunc;
|
||||
std::function<void(bool)> setTextVisibleFunc;
|
||||
std::function<void(const QString&)> setTextFunc;
|
||||
};
|
||||
struct PageFunc {
|
||||
std::function<void(bool)> setEnabledFunc;
|
||||
};
|
||||
struct ButtonFunc {
|
||||
std::function<void(bool)> setVisibleFunc;
|
||||
};
|
||||
struct LabelFunc {
|
||||
std::function<void(bool)> setVisibleFunc;
|
||||
std::function<void(const QString&)> setTextFunc;
|
||||
};
|
||||
|
||||
bool installContainers(ServerCredentials credentials,
|
||||
QMap<DockerContainer, QJsonObject> &containers,
|
||||
const PageFunc& page,
|
||||
const ProgressFunc& progress,
|
||||
const ButtonFunc& button,
|
||||
const LabelFunc& info);
|
||||
|
||||
ErrorCode doInstallAction(const std::function<ErrorCode()> &action,
|
||||
const PageFunc& page,
|
||||
const ProgressFunc& progress,
|
||||
const ButtonFunc& button,
|
||||
const LabelFunc& info);
|
||||
|
||||
|
||||
public:
|
||||
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <QLocalSocket>
|
||||
|
||||
#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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
$<TARGET_FILE_DIR:${PROJECT}>
|
||||
COMMAND_EXPAND_LISTS
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
#include "logger.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#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();
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
#ifndef LOGGER_H
|
||||
#define LOGGER_H
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QString>
|
||||
#include <QTextStream>
|
||||
|
||||
class Log
|
||||
class Logger
|
||||
{
|
||||
public:
|
||||
static bool init();
|
||||
|
@ -25,4 +25,4 @@ private:
|
|||
static QTextStream m_textStream;
|
||||
};
|
||||
|
||||
#endif // LOG_H
|
||||
#endif // LOGGER_H
|
|
@ -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";
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue