Поддержка протокола Sftp (File Sharing) по ТЗ по гранту от Теплицы

социальных технологий (2021 год)
+ небольшой рефакторинг
This commit is contained in:
pokamest 2021-09-22 14:49:08 +03:00
parent 6ee203a21d
commit 3bcc12869b
45 changed files with 645 additions and 338 deletions

View file

@ -56,6 +56,7 @@ HEADERS += \
ui/pages_logic/WizardLogic.h \
ui/pages_logic/protocols/CloakLogic.h \
ui/pages_logic/protocols/OpenVpnLogic.h \
ui/pages_logic/protocols/OtherProtocolsLogic.h \
ui/pages_logic/protocols/PageProtocolLogicBase.h \
ui/pages_logic/protocols/ShadowSocksLogic.h \
ui/property_helper.h \
@ -107,6 +108,7 @@ SOURCES += \
ui/pages_logic/WizardLogic.cpp \
ui/pages_logic/protocols/CloakLogic.cpp \
ui/pages_logic/protocols/OpenVpnLogic.cpp \
ui/pages_logic/protocols/OtherProtocolsLogic.cpp \
ui/pages_logic/protocols/PageProtocolLogicBase.cpp \
ui/pages_logic/protocols/ShadowSocksLogic.cpp \
ui/models/servers_model.cpp \

View file

@ -38,7 +38,7 @@ QVector<amnezia::Protocol> ContainerProps::protocolsForContainer(amnezia::Docker
return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak };
default:
return {};
return { defaultProtocol(container) };
}
}
@ -62,7 +62,8 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
{DockerContainer::WireGuard, "WireGuard"},
{DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")},
{DockerContainer::Dns, QObject::tr("DNS Service")},
{DockerContainer::FileShare, QObject::tr("File Sharing Service")}
{DockerContainer::FileShare, QObject::tr("SMB file sharing service")},
{DockerContainer::Sftp, QObject::tr("Sftp file sharing service")}
};
}
@ -76,7 +77,8 @@ QMap<DockerContainer, QString> ContainerProps::containerDescriptions()
{DockerContainer::WireGuard, QObject::tr("WireGuard container")},
{DockerContainer::TorWebSite, QObject::tr("Web site in TOR network")},
{DockerContainer::Dns, QObject::tr("DNS Service")},
{DockerContainer::FileShare, QObject::tr("File Sharing Service")}
{DockerContainer::FileShare, QObject::tr("SMB file sharing service - is Window file sharing protocol")},
{DockerContainer::Sftp, QObject::tr("Sftp file sharing service - is secure FTP service")}
};
}

View file

@ -22,7 +22,8 @@ enum DockerContainer {
//non-vpn
TorWebSite,
Dns,
FileShare
FileShare,
Sftp
};
Q_ENUM_NS(DockerContainer)
} // namespace ContainerEnumNS
@ -43,6 +44,7 @@ public:
Q_INVOKABLE static QMap<DockerContainer, QString> containerHumanNames();
Q_INVOKABLE static QMap<DockerContainer, QString> containerDescriptions();
// these protocols will be displayed in container settings
Q_INVOKABLE static QVector<Protocol> protocolsForContainer(DockerContainer container);
Q_INVOKABLE static ServiceType containerService(DockerContainer c);

View file

@ -12,6 +12,9 @@ QString amnezia::scriptFolder(amnezia::DockerContainer container)
case DockerContainer::ShadowSocks: return QLatin1String("openvpn_shadowsocks");
case DockerContainer::WireGuard: return QLatin1String("wireguard");
case DockerContainer::TorWebSite: return QLatin1String("website_tor");
case DockerContainer::Dns: return QLatin1String("dns");
case DockerContainer::FileShare: return QLatin1String("file_share");
case DockerContainer::Sftp: return QLatin1String("sftp");
default: return "";
}
}
@ -46,12 +49,12 @@ QString amnezia::scriptData(amnezia::SharedScriptType type)
QString fileName = QString(":/server_scripts/%1").arg(amnezia::scriptName(type));
QFile file(fileName);
if (! file.open(QIODevice::ReadOnly)) {
qDebug() << "Error opening script" << fileName;
qDebug() << "Warning: script missing" << fileName;
return "";
}
QByteArray ba = file.readAll();
if (ba.isEmpty()) {
qDebug() << "Error, script is empty" << fileName;
qDebug() << "Warning: script is empty" << fileName;
}
return ba;
}
@ -61,7 +64,7 @@ QString amnezia::scriptData(amnezia::ProtocolScriptType type, DockerContainer co
QString fileName = QString(":/server_scripts/%1/%2").arg(amnezia::scriptFolder(container), amnezia::scriptName(type));
QFile file(fileName);
if (! file.open(QIODevice::ReadOnly)) {
qDebug() << "Error opening script" << fileName;
qDebug() << "Warning: script missing" << fileName;
return "";
}
QByteArray data = file.readAll();

View file

@ -413,6 +413,29 @@ ErrorCode ServerController::updateContainer(const ServerCredentials &credentials
}
}
QJsonObject ServerController::createContainerInitialConfig(DockerContainer container, int port, TransportProto tp)
{
Protocol mainProto = ContainerProps::defaultProtocol(container);
QJsonObject config {
{ config_key::container, ContainerProps::containerToString(container) }
};
QJsonObject protoConfig;
protoConfig.insert(config_key::port, QString::number(port));
protoConfig.insert(config_key::transport_proto, ProtocolProps::transportProtoToString(tp, mainProto));
if (container == DockerContainer::Sftp) {
protoConfig.insert(config_key::userName, protocols::sftp::defaultUserName);
protoConfig.insert(config_key::password, Utils::getRandomString(10));
}
config.insert(ProtocolProps::protoToString(mainProto), protoConfig);
return config;
}
bool ServerController::isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig)
{
const QJsonObject &oldProtoConfig = oldConfig[ContainerProps::containerToString(container)].toObject();
@ -512,6 +535,7 @@ ErrorCode ServerController::runContainerWorker(const ServerCredentials &credenti
if (stdOut.contains("address already in use")) return ErrorCode::ServerPortAlreadyAllocatedError;
if (stdOut.contains("is already in use by container")) return ErrorCode::ServerPortAlreadyAllocatedError;
if (stdOut.contains("invalid publish")) return ErrorCode::ServerDockerFailedError;
return e;
}
@ -525,9 +549,14 @@ ErrorCode ServerController::configureContainerWorker(const ServerCredentials &cr
ErrorCode ServerController::startupContainerWorker(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
{
QString script = amnezia::scriptData(ProtocolScriptType::container_startup, container);
if (script.isEmpty()) {
return ErrorCode::NoError;
}
ErrorCode e = uploadTextFileToContainer(container, credentials,
replaceVars(amnezia::scriptData(ProtocolScriptType::container_startup, container),
genVarsForScript(credentials, container, config)),
replaceVars(script, genVarsForScript(credentials, container, config)),
"/opt/amnezia/start.sh");
if (e) return e;
@ -542,6 +571,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Protocol::Cloak)).toObject();
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Protocol::ShadowSocks)).toObject();
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Protocol::WireGuard)).toObject();
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Protocol::Sftp)).toObject();
//
Vars vars;
@ -588,6 +618,9 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
vars.append({{"$WIREGUARD_SERVER_PORT", wireguarConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) }});
// Sftp vars
vars.append({{"$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Protocol::Sftp))) }});
QString serverIp = Utils::getIPAddress(credentials.hostName);
if (!serverIp.isEmpty()) {

View file

@ -32,6 +32,9 @@ public:
static ErrorCode updateContainer(const ServerCredentials &credentials, DockerContainer container,
const QJsonObject &oldConfig, const QJsonObject &newConfig = QJsonObject());
// create initial config - generate passwords, etc
static QJsonObject createContainerInitialConfig(DockerContainer container, int port, TransportProto tp);
static bool isReinstallContainerRequred(DockerContainer container, const QJsonObject &oldConfig, const QJsonObject &newConfig);
static ErrorCode checkOpenVpnServer(DockerContainer container, const ServerCredentials &credentials);

View file

@ -70,7 +70,8 @@ QMap<amnezia::Protocol, QString> ProtocolProps::protocolHumanNames()
{Protocol::WireGuard, "WireGuard"},
{Protocol::TorWebSite, "Web site in TOR network"},
{Protocol::Dns, "DNS Service"},
{Protocol::FileShare, "File Sharing Service"}
{Protocol::FileShare, "File Sharing Service"},
{Protocol::Sftp, QObject::tr("Sftp service")}
};
}
@ -105,6 +106,7 @@ int ProtocolProps::defaultPort(Protocol p)
case Protocol::TorWebSite : return 443;
case Protocol::Dns : return 53;
case Protocol::FileShare : return 139;
case Protocol::Sftp : return 222;
default: return -1;
}
}
@ -132,9 +134,11 @@ TransportProto ProtocolProps::defaultTransportProto(Protocol p)
case Protocol::Cloak : return TransportProto::Tcp;
case Protocol::ShadowSocks : return TransportProto::Tcp;
case Protocol::WireGuard : return TransportProto::Udp;
// non-vpn
case Protocol::TorWebSite : return TransportProto::Tcp;
case Protocol::Dns : return TransportProto::Udp;
case Protocol::FileShare : return TransportProto::Tcp;
case Protocol::FileShare : return TransportProto::Udp;
case Protocol::Sftp : return TransportProto::Tcp;
default: return TransportProto::Udp;
}
}
@ -147,9 +151,11 @@ bool ProtocolProps::defaultTransportProtoChangeable(Protocol p)
case Protocol::Cloak : return false;
case Protocol::ShadowSocks : return false;
case Protocol::WireGuard : return false;
// non-vpn
case Protocol::TorWebSite : return false;
case Protocol::Dns : return false;
case Protocol::FileShare : return false;
default: return -1;
case Protocol::Sftp : return false;
default: return false;
}
}

View file

@ -100,6 +100,10 @@ constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
}
namespace sftp {
constexpr char defaultUserName[] = "sftp_user";
} // namespace sftp
} // namespace protocols
@ -118,9 +122,12 @@ enum Protocol {
ShadowSocks,
Cloak,
WireGuard,
// non-vpn
TorWebSite,
Dns,
FileShare
FileShare,
Sftp
};
Q_ENUM_NS(Protocol)
@ -177,6 +184,14 @@ static void declareQmlProtocolEnum() {
"TransportProto",
"Error: only enums"
);
qmlRegisterUncreatableMetaObject(
ProtocolEnumNS::staticMetaObject,
"ProtocolEnum",
1, 0,
"ServiceType",
"Error: only enums"
);
}
} // namespace amnezia

View file

@ -114,5 +114,12 @@
<file>images/delete.png</file>
<file>ui/qml/Controls/FadeBehavior.qml</file>
<file>ui/qml/Controls/VisibleBehavior.qml</file>
<file>server_scripts/dns/configure_container.sh</file>
<file>server_scripts/dns/Dockerfile</file>
<file>server_scripts/dns/run_container.sh</file>
<file>server_scripts/sftp/configure_container.sh</file>
<file>server_scripts/sftp/Dockerfile</file>
<file>server_scripts/sftp/run_container.sh</file>
<file>ui/qml/Pages/Protocols/PageProtoSftp.qml</file>
</qresource>
</RCC>

View file

@ -0,0 +1,3 @@
FROM mvance/unbound:latest
LABEL maintainer="AmneziaVPN"

View file

@ -0,0 +1,2 @@
# Run container
sudo docker run -d --restart always --cap-add=NET_ADMIN -p 53:53/udp -p 53:53/tcp --name $CONTAINER_NAME $CONTAINER_NAME

View file

@ -0,0 +1,3 @@
FROM atmoz/sftp
LABEL maintainer="AmneziaVPN"

View file

@ -0,0 +1 @@
sudo docker run -d --restart always -p $SFTP_PORT:22/tcp --name $CONTAINER_NAME $CONTAINER_NAME $SFTP_USER:$SFTP_PASSWORD:::upload

View file

@ -1,13 +0,0 @@
# Wireguard config
sudo docker exec -i $CONTAINER_NAME bash -c '\
mkdir -p /opt/amnezia/wireguard; \
cd /opt/amnezia/wireguard || exit 1; \
WIREGUARD_SERVER_PRIVATE_KEY=$(wg genkey) && echo $WIREGUARD_SERVER_PRIVATE_KEY > /opt/amnezia/wireguard/wireguard_server_private_key.key; \
WIREGUARD_SERVER_PUBLIC_KEY=$(echo $WIREGUARD_SERVER_PRIVATE_KEY | wg pubkey) && echo $WIREGUARD_SERVER_PUBLIC_KEY > /opt/amnezia/wireguard/wireguard_server_public_key.key; \
WIREGUARD_PSK=$(wg genpsk) && echo $WIREGUARD_PSK > /opt/amnezia/wireguard/wireguard_psk.key; \
echo -e "\
[Interface]\\n\
PrivateKey = $WIREGUARD_SERVER_PRIVATE_KEY \\n\
Address = $WIREGUARD_SUBNET_IP/$WIREGUARD_SUBNET_CIDR \\n\
ListenPort = $WIREGUARD_SERVER_PORT \\n\
" >/opt/amnezia/wireguard/wg0.conf'

View file

@ -16,7 +16,7 @@ AppSettingsLogic::AppSettingsLogic(UiLogic *logic, QObject *parent):
}
void AppSettingsLogic::updatePage()
void AppSettingsLogic::onUpdatePage()
{
set_checkBoxAutostartChecked(Autostart::isAutostart());
set_checkBoxAutoConnectChecked(m_settings.isAutoConnect());

View file

@ -14,7 +14,7 @@ class AppSettingsLogic : public PageLogicBase
AUTO_PROPERTY(QString, labelVersionText)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onCheckBoxAutostartToggled(bool checked);
Q_INVOKABLE void onCheckBoxAutoconnectToggled(bool checked);

View file

@ -9,7 +9,7 @@ GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent):
}
void GeneralSettingsLogic::updatePage()
void GeneralSettingsLogic::onUpdatePage()
{
set_pushButtonGeneralSettingsShareConnectionEnable(m_settings.haveAuthData(m_settings.defaultServerIndex()));
}

View file

@ -12,7 +12,7 @@ class GeneralSettingsLogic : public PageLogicBase
AUTO_PROPERTY(bool, pushButtonGeneralSettingsShareConnectionEnable)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonGeneralSettingsServerSettingsClicked();
Q_INVOKABLE void onPushButtonGeneralSettingsShareConnectionClicked();

View file

@ -10,7 +10,7 @@ NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
}
void NetworkSettingsLogic::updatePage()
void NetworkSettingsLogic::onUpdatePage()
{
set_lineEditDns1Text(m_settings.primaryDns());
set_lineEditDns2Text(m_settings.secondaryDns());
@ -35,13 +35,13 @@ void NetworkSettingsLogic::onLineEditDns2EditFinished(const QString &text)
void NetworkSettingsLogic::onPushButtonResetDns1Clicked()
{
m_settings.setPrimaryDns(m_settings.cloudFlareNs1);
updatePage();
onUpdatePage();
}
void NetworkSettingsLogic::onPushButtonResetDns2Clicked()
{
m_settings.setSecondaryDns(m_settings.cloudFlareNs2);
updatePage();
onUpdatePage();
}
QString NetworkSettingsLogic::getIpAddressValidatorRegex() const

View file

@ -14,7 +14,7 @@ class NetworkSettingsLogic : public PageLogicBase
READONLY_PROPERTY(QString, ipAddressValidatorRegex)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onLineEditDns1EditFinished(const QString& text);
Q_INVOKABLE void onLineEditDns2EditFinished(const QString& text);

View file

@ -9,7 +9,7 @@ NewServerProtocolsLogic::NewServerProtocolsLogic(UiLogic *logic, QObject *parent
}
void NewServerProtocolsLogic::updatePage()
void NewServerProtocolsLogic::onUpdatePage()
{
set_progressBarConnectionMinimum(0);
set_progressBarConnectionMaximum(300);

View file

@ -13,7 +13,7 @@ class NewServerProtocolsLogic : public PageLogicBase
AUTO_PROPERTY(double, progressBarConnectionMaximum)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp);
public:

View file

@ -19,7 +19,7 @@ public:
explicit PageLogicBase(UiLogic *uiLogic, QObject *parent = nullptr);
~PageLogicBase() = default;
Q_INVOKABLE virtual void updatePage() {}
Q_INVOKABLE virtual void onUpdatePage() {}
protected:
UiLogic *uiLogic() const { return m_uiLogic; }
@ -27,5 +27,7 @@ protected:
Settings m_settings;
UiLogic *m_uiLogic;
signals:
void updatePage();
};
#endif // PAGE_LOGIC_BASE_H

View file

@ -18,13 +18,15 @@ ServerContainersLogic::ServerContainersLogic(UiLogic *logic, QObject *parent):
{
}
void ServerContainersLogic::updateServerContainersPage()
void ServerContainersLogic::onUpdatePage()
{
ContainersModel *c_model = qobject_cast<ContainersModel *>(uiLogic()->containersModel());
c_model->setSelectedServerIndex(uiLogic()->selectedServerIndex);
ProtocolsModel *p_model = qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel());
p_model->setSelectedServerIndex(uiLogic()->selectedServerIndex);
emit updatePage();
}
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p)
@ -41,7 +43,7 @@ void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c,
void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c)
{
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c);
updateServerContainersPage();
onUpdatePage();
}
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
@ -62,23 +64,12 @@ void ServerContainersLogic::onPushButtonRemoveClicked(DockerContainer container)
if (c.isEmpty()) m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, DockerContainer::None);
else m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c.keys().first());
}
updateServerContainersPage();
onUpdatePage();
}
void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int port, TransportProto tp)
{
QMap<DockerContainer, QJsonObject> containers;
Protocol mainProto = ContainerProps::defaultProtocol(c);
QJsonObject config {
{ config_key::container, ContainerProps::containerToString(c) },
{ ProtocolProps::protoToString(mainProto), QJsonObject {
{ config_key::port, QString::number(port) },
{ config_key::transport_proto, ProtocolProps::transportProtoToString(tp, mainProto) }}
}
};
containers.insert(c, config);
QJsonObject config = ServerController::createContainerInitialConfig(c, port, tp);
emit uiLogic()->goToPage(Page::ServerConfiguringProgress);
qApp->processEvents();
@ -88,10 +79,12 @@ void ServerContainersLogic::onPushButtonContinueClicked(DockerContainer c, int p
});
if (!e) {
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, QJsonObject());
m_settings.setContainerConfig(uiLogic()->selectedServerIndex, c, config);
if (ContainerProps::containerService(c) == ServiceType::Vpn) {
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c);
}
}
updateServerContainersPage();
onUpdatePage();
emit uiLogic()->closePage();
}

View file

@ -10,7 +10,7 @@ class ServerContainersLogic : public PageLogicBase
Q_OBJECT
public:
Q_INVOKABLE void updateServerContainersPage();
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p);
Q_INVOKABLE void onPushButtonDefaultClicked(DockerContainer c);

View file

@ -14,7 +14,7 @@ ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent):
void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
{
m_settings.setDefaultServer(index);
updatePage();
onUpdatePage();
}
void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
@ -23,7 +23,7 @@ void ServerListLogic::onServerListPushbuttonSettingsClicked(int index)
uiLogic()->goToPage(Page::ServerSettings);
}
void ServerListLogic::updatePage()
void ServerListLogic::onUpdatePage()
{
const QJsonArray &servers = m_settings.serversArray();
int defaultServer = m_settings.defaultServerIndex();

View file

@ -12,7 +12,7 @@ class ServerListLogic : public PageLogicBase
READONLY_PROPERTY(QObject *, serverListModel)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onServerListPushbuttonDefaultClicked(int index);
Q_INVOKABLE void onServerListPushbuttonSettingsClicked(int index);

View file

@ -21,7 +21,7 @@ ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent):
}
void ServerSettingsLogic::updatePage()
void ServerSettingsLogic::onUpdatePage()
{
set_labelWaitInfoVisible(false);
set_labelWaitInfoText("");
@ -91,7 +91,7 @@ void ServerSettingsLogic::onPushButtonForgetServer()
uiLogic()->selectedServerIndex = -1;
uiLogic()->serverListLogic()->updatePage();
uiLogic()->serverListLogic()->onUpdatePage();
if (m_settings.serversCount() == 0) {
uiLogic()->setStartPage(Page::Start);
@ -121,7 +121,7 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
QJsonObject server = m_settings.server(uiLogic()->selectedServerIndex);
server.insert(config_key::description, newText);
m_settings.editServer(uiLogic()->selectedServerIndex, server);
uiLogic()->serverListLogic()->updatePage();
uiLogic()->serverListLogic()->onUpdatePage();
}
void ServerSettingsLogic::onPushButtonShareFullClicked()

View file

@ -21,7 +21,7 @@ class ServerSettingsLogic : public PageLogicBase
AUTO_PROPERTY(QString, labelCurrentVpnProtocolText)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonClearServer();
Q_INVOKABLE void onPushButtonForgetServer();

View file

@ -21,7 +21,7 @@ StartPageLogic::StartPageLogic(UiLogic *logic, QObject *parent):
}
void StartPageLogic::updatePage()
void StartPageLogic::onUpdatePage()
{
set_lineEditStartExistingCodeText("");
set_textEditSshKeyText("");

View file

@ -23,7 +23,7 @@ class StartPageLogic : public PageLogicBase
AUTO_PROPERTY(bool, pushButtonConnectVisible)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonConnect();
Q_INVOKABLE void onPushButtonImport();

View file

@ -12,7 +12,7 @@ WizardLogic::WizardLogic(UiLogic *logic, QObject *parent):
}
void WizardLogic::updatePage()
void WizardLogic::onUpdatePage()
{
set_lineEditHighWebsiteMaskingText(protocols::cloak::defaultRedirSite);
}

View file

@ -16,7 +16,7 @@ class WizardLogic : public PageLogicBase
AUTO_PROPERTY(QString, lineEditHighWebsiteMaskingText)
public:
Q_INVOKABLE void updatePage() override;
Q_INVOKABLE void onUpdatePage() override;
Q_INVOKABLE void onPushButtonVpnModeFinishClicked();
Q_INVOKABLE void onPushButtonLowFinishClicked();

View file

@ -0,0 +1,30 @@
#include "OtherProtocolsLogic.h"
#include "core/servercontroller.h"
#include <functional>
#include "../../uilogic.h"
using namespace amnezia;
using namespace PageEnumNS;
OtherProtocolsLogic::OtherProtocolsLogic(UiLogic *logic, QObject *parent):
PageProtocolLogicBase(logic, parent)
{
}
void OtherProtocolsLogic::updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData)
{
set_labelTftpUserNameText(config.value(config_key::userName).toString());
set_labelTftpPasswordText(config.value(config_key::password).toString(protocols::sftp::defaultUserName));
set_labelTftpPortText(config.value(config_key::port).toString(protocols::sftp::defaultUserName));
}
//QJsonObject OtherProtocolsLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
//{
//}
void OtherProtocolsLogic::onPushButtonProtoShadowSocksSaveClicked()
{
}

View file

@ -0,0 +1,31 @@
#ifndef OTHER_PROTOCOLS_LOGIC_H
#define OTHER_PROTOCOLS_LOGIC_H
#include "PageProtocolLogicBase.h"
class UiLogic;
class OtherProtocolsLogic : public PageProtocolLogicBase
{
Q_OBJECT
AUTO_PROPERTY(QString, labelTftpUserNameText)
AUTO_PROPERTY(QString, labelTftpPasswordText)
AUTO_PROPERTY(QString, labelTftpPortText)
public:
Q_INVOKABLE void onPushButtonProtoShadowSocksSaveClicked();
public:
explicit OtherProtocolsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
~OtherProtocolsLogic() = default;
void updateProtocolPage(const QJsonObject &config, DockerContainer container, bool haveAuthData) override;
//QJsonObject getProtocolConfigFromPage(QJsonObject oldConfig) override;
private:
Settings m_settings;
UiLogic *m_uiLogic;
};
#endif // OTHER_PROTOCOLS_LOGIC_H

View file

@ -1,5 +1,6 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import Qt.labs.platform 1.0
TextField {
id: root
@ -8,6 +9,7 @@ TextField {
width: parent.width - 80
height: 40
anchors.topMargin: 5
selectByMouse: true
selectionColor: "darkgray"
font.pixelSize: 16
@ -35,4 +37,36 @@ TextField {
return "#A7A7A7"
}
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: contextMenu.open()
}
Menu {
id: contextMenu
onAboutToShow: console.log("aboutToShow")
onAboutToHide: console.log("aboutToHide")
MenuItem {
text: qsTr("C&ut")
shortcut: StandardKey.Cut
enabled: root.selectedText
onTriggered: root.cut()
}
MenuItem {
text: qsTr("&Copy")
shortcut: StandardKey.Copy
enabled: root.selectedText
onTriggered: root.copy()
}
MenuItem {
text: qsTr("&Paste")
shortcut: StandardKey.Paste
enabled: root.canPaste
onTriggered: root.paste()
}
}
}

View file

@ -5,6 +5,7 @@ import SortFilterProxyModel 0.2
import ContainerProps 1.0
import ProtocolProps 1.0
import PageEnum 1.0
import ProtocolEnum 1.0
import "./"
import "../Controls"
import "../Config"
@ -16,6 +17,18 @@ PageBase {
logic: ServerContainersLogic
enabled: ServerContainersLogic.pageEnabled
function resetPage() {
container_selector.selectedIndex = -1
}
Connections {
target: logic
function onUpdatePage() {
root.resetPage()
}
}
BackButton {
id: back
}
@ -174,7 +187,7 @@ PageBase {
Caption {
id: cap1
text: qsTr("Installed VPN containers")
text: qsTr("Installed Protocols and Services")
font.pixelSize: 20
}
@ -268,16 +281,13 @@ PageBase {
else tb_c.currentIndex = index
UiLogic.protocolsModel.setSelectedDockerContainer(proxyContainersModel.mapToSource(index))
//ServerContainersLogic.setSelectedDockerContainer(proxyContainersModel.mapToSource(index))
//container_selector.containerSelected(index)
//root.close()
}
}
}
ImageButtonType {
id: button_default
visible: service_type_role == ProtocolEnum.Vpn
Layout.alignment: Qt.AlignRight
checkable: true

View file

@ -100,7 +100,7 @@ PageBase {
y: 210
width: 300
height: 40
text: qsTr("Protocols and services")
text: qsTr("Protocols and Services")
onClicked: {
UiLogic.goToPage(PageEnum.ServerContainers)
}

View file

@ -1,5 +1,6 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import ProtocolEnum 1.0
import "../"
import "../../Controls"
@ -13,113 +14,52 @@ PageProtocolBase {
BackButton {
id: back
}
Item {
x: 0
y: 40
width: 380
height: 600
enabled: logic.pageEnabled
CheckBoxType {
x: 30
y: 280
width: 321
height: 21
text: qsTr("Auto-negotiate encryption")
checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked
}
onClicked: {
logic.checkBoxProtoOpenVpnAutoEncryptionClicked()
}
}
CheckBoxType {
x: 30
y: 430
width: 321
height: 21
text: qsTr("Block DNS requests outside of VPN")
checked: logic.checkBoxProtoOpenVpnBlockDnsChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnBlockDnsChecked = checked
}
}
CheckBoxType {
x: 30
y: 390
width: 321
height: 21
text: qsTr("Enable TLS auth")
checked: logic.checkBoxProtoOpenVpnTlsAuthChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnTlsAuthChecked = checked
Caption {
id: caption
text: qsTr("OpenVPN Settings")
}
}
ComboBoxType {
Item {
enabled: logic.pageEnabled
anchors.top: caption.bottom
anchors.bottom: parent.bottom
width: parent.width
LabelType {
id: lb_subnet
x: 30
y: 340
width: 151
anchors.top: parent.top
width: parent.width
height: 21
text: qsTr("VPN Addresses Subnet")
}
TextFieldType {
id: tf_subnet
x: 30
anchors.top: lb_subnet.bottom
width: parent.width - 60
height: 31
model: [
qsTr("AES-256-GCM"),
qsTr("AES-192-GCM"),
qsTr("AES-128-GCM"),
qsTr("AES-256-CBC"),
qsTr("AES-192-CBC"),
qsTr("AES-128-CBC"),
qsTr("ChaCha20-Poly1305"),
qsTr("ARIA-256-CBC"),
qsTr("CAMELLIA-256-CBC"),
qsTr("none")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnCipherText === model[i]) {
return i
text: logic.lineEditProtoOpenVpnSubnetText
onEditingFinished: {
logic.lineEditProtoOpenVpnSubnetText = text
}
}
return -1
}
onCurrentTextChanged: {
logic.comboBoxProtoOpenVpnCipherText = currentText
}
enabled: logic.comboBoxProtoOpenVpnCipherEnabled
}
ComboBoxType {
x: 200
y: 340
width: 151
height: 31
model: [
qsTr("SHA512"),
qsTr("SHA384"),
qsTr("SHA256"),
qsTr("SHA3-512"),
qsTr("SHA3-384"),
qsTr("SHA3-256"),
qsTr("whirlpool"),
qsTr("BLAKE2b512"),
qsTr("BLAKE2s256"),
qsTr("SHA1")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnHashText === model[i]) {
return i
}
}
return -1
}
onCurrentTextChanged: {
logic.comboBoxProtoOpenVpnHashText = currentText
}
enabled: logic.comboBoxProtoOpenVpnHashEnabled
//
LabelType {
id: lb_proto
x: 30
anchors.top: tf_subnet.bottom
width: parent.width
height: 21
text: qsTr("Network protocol")
}
Rectangle {
id: rect_proto
x: 30
y: 140
width: 321
anchors.top: lb_proto.bottom
width: parent.width - 60
height: 71
border.width: 1
border.color: "lightgray"
@ -149,68 +89,27 @@ PageProtocolBase {
enabled: logic.radioButtonProtoOpenVpnUdpEnabled
}
}
//
LabelType {
id: lb_port
anchors.top: rect_proto.bottom
anchors.topMargin: 20
x: 30
y: 110
width: 151
height: 21
text: qsTr("Network protocol")
}
LabelType {
x: 30
y: 230
width: 151
width: root.width / 2 - 10
height: 31
text: qsTr("Port")
}
Text {
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 24
color: "#100A44"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: qsTr("OpenVPN Settings")
x: 10
y: 0
width: 340
height: 30
}
LabelType {
x: 200
y: 310
width: 151
height: 21
text: qsTr("Hash")
}
LabelType {
x: 30
y: 40
width: 291
height: 21
text: qsTr("VPN Addresses Subnet")
}
LabelType {
x: 30
y: 310
width: 151
height: 21
text: qsTr("Cipher")
}
LabelType {
id: label_proto_openvpn_info
x: 30
y: 550
width: 321
height: 41
visible: logic.labelProtoOpenVpnInfoVisible
text: logic.labelProtoOpenVpnInfoText
}
TextFieldType {
id: lineEdit_proto_openvpn_port
x: 200
y: 230
width: 151
id: tf_port
anchors.top: rect_proto.bottom
anchors.topMargin: 20
anchors.left: parent.horizontalCenter
anchors.right: parent.right
anchors.rightMargin: 30
height: 31
text: logic.lineEditProtoOpenVpnPortText
onEditingFinished: {
@ -218,19 +117,157 @@ PageProtocolBase {
}
enabled: logic.lineEditProtoOpenVpnPortEnabled
}
TextFieldType {
id: lineEdit_proto_openvpn_subnet
//
CheckBoxType {
id: check_auto_enc
anchors.top: lb_port.bottom
anchors.topMargin: 20
x: 30
y: 65
width: 321
width: parent.width
height: 21
text: qsTr("Auto-negotiate encryption")
checked: logic.checkBoxProtoOpenVpnAutoEncryptionChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnAutoEncryptionChecked = checked
}
onClicked: {
logic.checkBoxProtoOpenVpnAutoEncryptionClicked()
}
}
//
LabelType {
id: lb_cipher
x: 30
anchors.top: check_auto_enc.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Cipher")
}
ComboBoxType {
id: cb_cipher
x: 30
anchors.top: lb_cipher.bottom
width: parent.width - 60
height: 31
text: logic.lineEditProtoOpenVpnSubnetText
onEditingFinished: {
logic.lineEditProtoOpenVpnSubnetText = text
model: [
qsTr("AES-256-GCM"),
qsTr("AES-192-GCM"),
qsTr("AES-128-GCM"),
qsTr("AES-256-CBC"),
qsTr("AES-192-CBC"),
qsTr("AES-128-CBC"),
qsTr("ChaCha20-Poly1305"),
qsTr("ARIA-256-CBC"),
qsTr("CAMELLIA-256-CBC"),
qsTr("none")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnCipherText === model[i]) {
return i
}
}
return -1
}
onCurrentTextChanged: {
logic.comboBoxProtoOpenVpnCipherText = currentText
}
enabled: logic.comboBoxProtoOpenVpnCipherEnabled
}
//
LabelType {
id: lb_hash
anchors.top: cb_cipher.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Hash")
}
ComboBoxType {
id: cb_hash
x: 30
height: 31
anchors.top: lb_hash.bottom
width: parent.width - 60
model: [
qsTr("SHA512"),
qsTr("SHA384"),
qsTr("SHA256"),
qsTr("SHA3-512"),
qsTr("SHA3-384"),
qsTr("SHA3-256"),
qsTr("whirlpool"),
qsTr("BLAKE2b512"),
qsTr("BLAKE2s256"),
qsTr("SHA1")
]
currentIndex: {
for (let i = 0; i < model.length; ++i) {
if (logic.comboBoxProtoOpenVpnHashText === model[i]) {
return i
}
}
return -1
}
onCurrentTextChanged: {
logic.comboBoxProtoOpenVpnHashText = currentText
}
enabled: logic.comboBoxProtoOpenVpnHashEnabled
}
CheckBoxType {
id: check_tls
x: 30
anchors.top: cb_hash.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Enable TLS auth")
checked: logic.checkBoxProtoOpenVpnTlsAuthChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnTlsAuthChecked = checked
}
}
CheckBoxType {
id: check_block_dns
x: 30
anchors.top: check_tls.bottom
anchors.topMargin: 20
width: parent.width
height: 21
text: qsTr("Block DNS requests outside of VPN")
checked: logic.checkBoxProtoOpenVpnBlockDnsChecked
onCheckedChanged: {
logic.checkBoxProtoOpenVpnBlockDnsChecked = checked
}
}
// LabelType {
// id: label_proto_openvpn_info
// x: 30
// y: 550
// width: 321
// height: 41
// visible: logic.labelProtoOpenVpnInfoVisible
// text: logic.labelProtoOpenVpnInfoText
// }
ProgressBar {
id: progressBar_proto_openvpn_reset
id: progress_save
anchors.horizontalCenter: parent.horizontalCenter
y: 500
width: 321
@ -250,7 +287,7 @@ PageProtocolBase {
implicitWidth: parent.width
implicitHeight: parent.height
Rectangle {
width: progressBar_proto_openvpn_reset.visualPosition * parent.width
width: progress_save.visualPosition * parent.width
height: parent.height
radius: 4
color: Qt.rgba(255, 255, 255, 0.15);
@ -258,9 +295,12 @@ PageProtocolBase {
}
}
BlueButtonType {
id: pb_save
anchors.horizontalCenter: parent.horizontalCenter
y: 500
width: 321
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
x: 30
width: parent.width - 60
height: 40
text: qsTr("Save and restart VPN")
visible: logic.pushButtonOpenvpnSaveVisible

View file

@ -0,0 +1,79 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import ProtocolEnum 1.0
import "../"
import "../../Controls"
import "../../Config"
PageProtocolBase {
id: root
protocol: ProtocolEnum.Sftp
logic: UiLogic.protocolLogic(protocol)
BackButton {
id: back
}
Caption {
id: caption
text: qsTr("SFTF settings")
}
Rectangle {
id: frame_settings
width: parent.width
anchors.top: caption.bottom
anchors.topMargin: 10
border.width: 1
border.color: "lightgray"
anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
radius: 2
Grid {
id: grid
anchors.fill: parent
columns: 2
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
topPadding: 5
leftPadding: 10
spacing: 5
LabelType {
width: 130
text: qsTr("Port")
}
TextFieldType {
id: tf_port_num
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
text: logic.labelTftpPortText
readOnly: true
}
LabelType {
width: 130
text: qsTr("User Name")
}
TextFieldType {
id: tf_user_name
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
text: logic.labelTftpUserNameText
readOnly: true
}
LabelType {
width: 130
text: qsTr("Password")
}
TextFieldType {
id: tf_password
width: parent.width - 130 - parent.spacing - parent.leftPadding * 2
text: logic.labelTftpPasswordText
readOnly: true
}
}
}
}

View file

@ -31,7 +31,7 @@ Window {
function gotoPage(page, reset, slide) {
if (reset) {
if (page === PageEnum.ServerSettings) {
ServerSettingsLogic.updatePage();
ServerSettingsLogic.onUpdatePage();
}
if (page === PageEnum.ShareConnection) {
}
@ -39,32 +39,32 @@ Window {
WizardLogic.radioButtonMediumChecked = true
}
if (page === PageEnum.WizardHigh) {
WizardLogic.updatePage();
WizardLogic.onUpdatePage();
}
if (page === PageEnum.ServerConfiguringProgress) {
ServerConfiguringProgressLogic.progressBarValue = 0;
}
if (page === PageEnum.GeneralSettings) {
GeneralSettingsLogic.updatePage();
GeneralSettingsLogic.onUpdatePage();
}
if (page === PageEnum.ServersList) {
ServerListLogic.updatePage();
ServerListLogic.onUpdatePage();
}
if (page === PageEnum.Start) {
StartPageLogic.pushButtonBackFromStartVisible = !pageLoader.empty
StartPageLogic.updatePage();
StartPageLogic.onUpdatePage();
}
if (page === PageEnum.NewServerProtocols) {
NewServerProtocolsLogic.updatePage()
NewServerProtocolsLogic.onUpdatePage()
}
if (page === PageEnum.ServerContainers) {
ServerContainersLogic.updateServerContainersPage()
ServerContainersLogic.onUpdatePage()
}
if (page === PageEnum.AppSettings) {
AppSettingsLogic.updatePage()
AppSettingsLogic.onUpdatePage()
}
if (page === PageEnum.NetworkSettings) {
NetworkSettingsLogic.updatePage()
NetworkSettingsLogic.onUpdatePage()
}
if (page === PageEnum.Sites) {
SitesLogic.updateSitesPage()
@ -84,8 +84,8 @@ Window {
}
function gotoProtocolPage(protocol, reset, slide) {
if (reset) {
protocolPages[protocol].logic.updatePage();
if (reset && protocolPages[protocol] !== "undefined") {
protocolPages[protocol].logic.onUpdatePage();
}
if (slide) {
@ -113,7 +113,7 @@ Window {
}
if (page === PageEnum.Start) {
UiLogic.pushButtonBackFromStartVisible = !pageLoader.empty
UiLogic.updatePage();
UiLogic.onUpdatePage();
}
}
@ -154,26 +154,31 @@ Window {
// initialItem: page_servers
onCurrentItemChanged: {
console.debug("QML onCurrentItemChanged " + pageLoader.currentItem)
UiLogic.currentPageValue = currentItem.page
}
Keys.onReleased: {
if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
console.debug("Back button captured")
if (UiLogic.currentPageValue !== PageEnum.VPN &&
UiLogic.currentPageValue !== PageEnum.ServerConfiguring &&
!(UiLogic.currentPageValue === PageEnum.Start && pageLoader.depth < 2)) {
close_page();
}
// Keys.onReleased: {
// if (event.key === Qt.Key_Back || event.key === Qt.Key_Escape) {
// console.debug("Back button captured")
// if (UiLogic.currentPageValue !== PageEnum.VPN &&
// UiLogic.currentPageValue !== PageEnum.ServerConfiguring &&
// !(UiLogic.currentPageValue === PageEnum.Start && pageLoader.depth < 2)) {
// close_page();
// }
// TODO: fix
//if (ui->stackedWidget_main->currentWidget()->isEnabled()) {
// closePage();
//}
// // TODO: fix
// //if (ui->stackedWidget_main->currentWidget()->isEnabled()) {
// // closePage();
// //}
event.accepted = true
}
// event.accepted = true
// }
// }
Keys.onPressed: {
UiLogic.keyPressEvent(event.key)
}
}
@ -220,13 +225,9 @@ Window {
obj.visible = false
if (isProtocol) {
protocolPages[obj.protocol] = obj
console.debug("PPP " + obj.protocol + " " + file)
}
else {
pages[obj.page] = obj
console.debug("AAA " + obj.page + " " + file)
}
@ -246,30 +247,30 @@ Window {
Connections {
target: UiLogic
onGoToPage: {
function onGoToPage(page, reset, slide) {
console.debug("Connections onGoToPage " + page);
root.gotoPage(page, reset, slide)
}
onGoToProtocolPage: {
function onGoToProtocolPage(protocol, reset, slide) {
console.debug("Connections onGoToProtocolPage " + protocol);
root.gotoProtocolPage(protocol, reset, slide)
}
onClosePage: {
function onClosePage() {
root.close_page()
}
onSetStartPage: {
function onSetStartPage(page, slide) {
root.set_start_page(page, slide)
}
onShowPublicKeyWarning: {
function onShowPublicKeyWarning() {
publicKeyWarning.visible = true
}
onShowConnectErrorDialog: {
function onShowConnectErrorDialog() {
connectErrorDialog.visible = true
}
onShow: {
function onShow() {
root.show()
}
onHide: {
function onHide() {
root.hide()
}
}

View file

@ -61,6 +61,7 @@
#include "pages_logic/protocols/CloakLogic.h"
#include "pages_logic/protocols/OpenVpnLogic.h"
#include "pages_logic/protocols/ShadowSocksLogic.h"
#include "pages_logic/protocols/OtherProtocolsLogic.h"
using namespace amnezia;
@ -96,6 +97,10 @@ UiLogic::UiLogic(QObject *parent) :
m_protocolLogicMap.insert(Protocol::ShadowSocks, new ShadowSocksLogic(this));
m_protocolLogicMap.insert(Protocol::Cloak, new CloakLogic(this));
//m_protocolLogicMap->insert(Protocol::WireGuard, new WireguardLogic(this));
m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this));
m_protocolLogicMap.insert(Protocol::Sftp, new OtherProtocolsLogic(this));
}
void UiLogic::initalizeUiLogic()
@ -131,8 +136,9 @@ void UiLogic::initalizeUiLogic()
}
selectedServerIndex = m_settings.defaultServerIndex();
goToPage(Page::ServerContainers, true, false);
goToPage(Page::NewServerProtocols, true, false);
//goToPage(Page::ServerContainers, true, false);
//goToPage(Page::NewServerProtocols, true, false);
onGotoProtocolPage(Protocol::OpenVpn);
//ui->pushButton_general_settings_exit->hide();
@ -284,52 +290,53 @@ void UiLogic::showOnStartup()
}
//void UiLogic::keyPressEvent(QKeyEvent *event)
//{
// switch (event->key()) {
// case Qt::Key_L:
// if (!Debug::openLogsFolder()) {
// QMessageBox::warning(this, APPLICATION_NAME, tr("Cannot open logs folder!"));
// }
// break;
//#ifdef QT_DEBUG
// case Qt::Key_Q:
// qApp->quit();
// break;
// // case Qt::Key_0:
// // *((char*)-1) = 'x';
// // break;
// case Qt::Key_H:
// selectedServerIndex = m_settings.defaultServerIndex();
// selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
void UiLogic::keyPressEvent(Qt::Key key)
{
switch (key) {
case Qt::Key_L:
if (!Debug::openLogsFolder()) {
//QMessageBox::warning(this, APPLICATION_NAME, tr("Cannot open logs folder!"));
}
break;
#ifdef QT_DEBUG
case Qt::Key_Q:
qApp->quit();
break;
// case Qt::Key_0:
// *((char*)-1) = 'x';
// break;
case Qt::Key_H:
selectedServerIndex = m_settings.defaultServerIndex();
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
// updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
// goToPage(Page::ShareConnection);
// break;
//#endif
// case Qt::Key_C:
// qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
// //qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
// qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson();
// break;
// case Qt::Key_A:
// goToPage(Page::Start);
// break;
// case Qt::Key_S:
// selectedServerIndex = m_settings.defaultServerIndex();
// goToPage(Page::ServerSettings);
// break;
// case Qt::Key_P:
// selectedServerIndex = m_settings.defaultServerIndex();
// selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
// goToPage(Page::ServerContainers);
// break;
// case Qt::Key_T:
// SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex()));
// break;
// case Qt::Key_Escape:
// if (currentPage() == Page::Vpn) break;
// if (currentPage() == Page::ServerConfiguring) break;
//updateSharingPage(selectedServerIndex, m_settings.serverCredentials(selectedServerIndex), selectedDockerContainer);
emit goToPage(Page::ShareConnection);
break;
#endif
case Qt::Key_C:
qDebug().noquote() << "Def server" << m_settings.defaultServerIndex() << m_settings.defaultContainerName(m_settings.defaultServerIndex());
//qDebug().noquote() << QJsonDocument(m_settings.containerConfig(m_settings.defaultServerIndex(), m_settings.defaultContainer(m_settings.defaultServerIndex()))).toJson();
qDebug().noquote() << QJsonDocument(m_settings.defaultServer()).toJson();
break;
case Qt::Key_A:
emit goToPage(Page::Start);
break;
case Qt::Key_S:
selectedServerIndex = m_settings.defaultServerIndex();
emit goToPage(Page::ServerSettings);
break;
case Qt::Key_P:
selectedServerIndex = m_settings.defaultServerIndex();
selectedDockerContainer = m_settings.defaultContainer(selectedServerIndex);
emit goToPage(Page::ServerContainers);
break;
case Qt::Key_T:
SshConfigurator::openSshTerminal(m_settings.serverCredentials(m_settings.defaultServerIndex()));
break;
case Qt::Key_Escape:
case Qt::Key_Back:
if (currentPage() == Page::Vpn) break;
if (currentPage() == Page::ServerConfiguringProgress) break;
// if (currentPage() == Page::Start && pagesStack.size() < 2) break;
// if (currentPage() == Page::Sites &&
// ui->tableView_sites->selectionModel()->selection().indexes().size() > 0) {
@ -337,13 +344,13 @@ void UiLogic::showOnStartup()
// break;
// }
// if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) {
// closePage();
// }
// default:
// ;
// }
//}
//if (! ui->stackedWidget_main->isAnimationRunning() && ui->stackedWidget_main->currentWidget()->isEnabled()) {
emit closePage();
//}
default:
;
}
}
void UiLogic::onCloseWindow()
{
@ -651,6 +658,15 @@ void UiLogic::setTrayIcon(const QString &iconPath)
setTrayIconUrl(iconPath);
}
PageProtocolLogicBase *UiLogic::protocolLogic(Protocol p) {
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
if (logic) return logic;
else {
qDebug() << "UiLogic::protocolLogic Warning: logic missing for" << p;
return new PageProtocolLogicBase(this);
}
}
PageEnumNS::Page UiLogic::currentPage()
{
return static_cast<PageEnumNS::Page>(getCurrentPageValue());

View file

@ -4,6 +4,7 @@
#include <QRegExpValidator>
#include <QQmlEngine>
#include <functional>
#include <QKeyEvent>
#include "property_helper.h"
#include "pages.h"
@ -86,6 +87,8 @@ public:
Q_INVOKABLE void onGotoPage(PageEnumNS::Page p, bool reset = true, bool slide = true) { emit goToPage(p, reset, slide); }
Q_INVOKABLE void onGotoProtocolPage(Protocol p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); }
Q_INVOKABLE void keyPressEvent(Qt::Key key);
int getCurrentPageValue() const;
void setCurrentPageValue(int currentPageValue);
@ -181,7 +184,7 @@ public:
VpnLogic *vpnLogic() { return m_vpnLogic; }
WizardLogic *wizardLogic() { return m_wizardLogic; }
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p) { return m_protocolLogicMap.value(p); }
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p);
private:
AppSettingsLogic *m_appSettingsLogic;
@ -212,7 +215,6 @@ private:
// QPoint offset;
// bool needToHideCustomTitlebar = false;
// void keyPressEvent(QKeyEvent* event) override;
// void showEvent(QShowEvent *event) override;
// void hideEvent(QHideEvent *event) override;