Merge branch 'dev' of https://github.com/amnezia-vpn/desktop-client into linux_v2
This commit is contained in:
commit
40ab540179
117 changed files with 1971 additions and 3419 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -24,7 +24,7 @@ enum class Page {Start = 0, NewServer, NewServerProtocols, Vpn,
|
|||
Wizard, WizardLow, WizardMedium, WizardHigh, WizardVpnMode, ServerConfiguringProgress,
|
||||
GeneralSettings, AppSettings, NetworkSettings, ServerSettings,
|
||||
ServerContainers, ServersList, ShareConnection, Sites,
|
||||
ProtocolSettings, ProtocolShare, QrDecoder};
|
||||
ProtocolSettings, ProtocolShare, QrDecoder, About};
|
||||
Q_ENUM_NS(Page)
|
||||
|
||||
static void declareQmlPageEnum() {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@
|
|||
#include "debug.h"
|
||||
#include "defines.h"
|
||||
#include "ui/qautostart.h"
|
||||
#include "ui/uilogic.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QFileDialog>
|
||||
#include <QStandardPaths>
|
||||
|
||||
using namespace amnezia;
|
||||
using namespace PageEnumNS;
|
||||
|
|
@ -11,7 +16,8 @@ AppSettingsLogic::AppSettingsLogic(UiLogic *logic, QObject *parent):
|
|||
PageLogicBase(logic, parent),
|
||||
m_checkBoxAutostartChecked{false},
|
||||
m_checkBoxAutoConnectChecked{false},
|
||||
m_checkBoxStartMinimizedChecked{false}
|
||||
m_checkBoxStartMinimizedChecked{false},
|
||||
m_checkBoxSaveLogsChecked{false}
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -21,6 +27,7 @@ void AppSettingsLogic::onUpdatePage()
|
|||
set_checkBoxAutostartChecked(Autostart::isAutostart());
|
||||
set_checkBoxAutoConnectChecked(m_settings.isAutoConnect());
|
||||
set_checkBoxStartMinimizedChecked(m_settings.isStartMinimized());
|
||||
set_checkBoxSaveLogsChecked(m_settings.isSaveLogs());
|
||||
|
||||
QString ver = QString("%1: %2 (%3)")
|
||||
.arg(tr("Software version"))
|
||||
|
|
@ -47,7 +54,23 @@ void AppSettingsLogic::onCheckBoxStartMinimizedToggled(bool checked)
|
|||
m_settings.setStartMinimized(checked);
|
||||
}
|
||||
|
||||
void AppSettingsLogic::onCheckBoxSaveLogsCheckedToggled(bool checked)
|
||||
{
|
||||
m_settings.setSaveLogs(checked);
|
||||
}
|
||||
|
||||
void AppSettingsLogic::onPushButtonOpenLogsClicked()
|
||||
{
|
||||
Debug::openLogsFolder();
|
||||
}
|
||||
|
||||
void AppSettingsLogic::onPushButtonExportLogsClicked()
|
||||
{
|
||||
uiLogic()->saveTextFile(tr("Save log"), "AmneziaVPN.log", ".log", Debug::getLogFile());
|
||||
}
|
||||
|
||||
void AppSettingsLogic::onPushButtonClearLogsClicked()
|
||||
{
|
||||
Debug::clearLogs();
|
||||
Debug::clearServiceLogs();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class AppSettingsLogic : public PageLogicBase
|
|||
AUTO_PROPERTY(bool, checkBoxAutostartChecked)
|
||||
AUTO_PROPERTY(bool, checkBoxAutoConnectChecked)
|
||||
AUTO_PROPERTY(bool, checkBoxStartMinimizedChecked)
|
||||
AUTO_PROPERTY(bool, checkBoxSaveLogsChecked)
|
||||
AUTO_PROPERTY(QString, labelVersionText)
|
||||
|
||||
public:
|
||||
|
|
@ -19,7 +20,10 @@ public:
|
|||
Q_INVOKABLE void onCheckBoxAutostartToggled(bool checked);
|
||||
Q_INVOKABLE void onCheckBoxAutoconnectToggled(bool checked);
|
||||
Q_INVOKABLE void onCheckBoxStartMinimizedToggled(bool checked);
|
||||
Q_INVOKABLE void onCheckBoxSaveLogsCheckedToggled(bool checked);
|
||||
Q_INVOKABLE void onPushButtonOpenLogsClicked();
|
||||
Q_INVOKABLE void onPushButtonExportLogsClicked();
|
||||
Q_INVOKABLE void onPushButtonClearLogsClicked();
|
||||
|
||||
public:
|
||||
explicit AppSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
|
||||
PageLogicBase(logic, parent),
|
||||
m_checkBoxUseAmneziaDnsChecked{false},
|
||||
m_ipAddressRegex{Utils::ipAddressRegExp()}
|
||||
{
|
||||
|
||||
|
|
@ -12,6 +13,8 @@ NetworkSettingsLogic::NetworkSettingsLogic(UiLogic *logic, QObject *parent):
|
|||
|
||||
void NetworkSettingsLogic::onUpdatePage()
|
||||
{
|
||||
set_checkBoxUseAmneziaDnsChecked(m_settings.useAmneziaDns());
|
||||
|
||||
set_lineEditDns1Text(m_settings.primaryDns());
|
||||
set_lineEditDns2Text(m_settings.secondaryDns());
|
||||
}
|
||||
|
|
@ -41,3 +44,8 @@ void NetworkSettingsLogic::onPushButtonResetDns2Clicked()
|
|||
m_settings.setSecondaryDns(m_settings.cloudFlareNs2);
|
||||
onUpdatePage();
|
||||
}
|
||||
|
||||
void NetworkSettingsLogic::onCheckBoxUseAmneziaDnsToggled(bool checked)
|
||||
{
|
||||
m_settings.setUseAmneziaDns(checked);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ class NetworkSettingsLogic : public PageLogicBase
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
AUTO_PROPERTY(bool, checkBoxUseAmneziaDnsChecked)
|
||||
|
||||
AUTO_PROPERTY(QString, lineEditDns1Text)
|
||||
AUTO_PROPERTY(QString, lineEditDns2Text)
|
||||
READONLY_PROPERTY(QRegExp, ipAddressRegex)
|
||||
|
|
@ -21,6 +23,8 @@ public:
|
|||
Q_INVOKABLE void onPushButtonResetDns1Clicked();
|
||||
Q_INVOKABLE void onPushButtonResetDns2Clicked();
|
||||
|
||||
Q_INVOKABLE void onCheckBoxUseAmneziaDnsToggled(bool checked);
|
||||
|
||||
public:
|
||||
explicit NetworkSettingsLogic(UiLogic *uiLogic, QObject *parent = nullptr);
|
||||
~NetworkSettingsLogic() = default;
|
||||
|
|
|
|||
|
|
@ -38,8 +38,6 @@ void QrDecoderLogic::onDetectedQrCode(const QString &code)
|
|||
|
||||
|
||||
if (magic == amnezia::qrMagicCode) {
|
||||
qDebug() << "QrDecoderLogic::onDetectedQrCode magic code detected" << magic << ba.size();
|
||||
|
||||
quint8 chunksCount; s >> chunksCount;
|
||||
if (totalChunksCount() != chunksCount) {
|
||||
m_chunks.clear();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@
|
|||
#include <functional>
|
||||
|
||||
#include "../uilogic.h"
|
||||
#include "../pages_logic/VpnLogic.h"
|
||||
#include "vpnconnection.h"
|
||||
|
||||
|
||||
ServerContainersLogic::ServerContainersLogic(UiLogic *logic, QObject *parent):
|
||||
PageLogicBase(logic, parent)
|
||||
|
|
@ -42,8 +45,17 @@ void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c,
|
|||
|
||||
void ServerContainersLogic::onPushButtonDefaultClicked(DockerContainer c)
|
||||
{
|
||||
if (m_settings.defaultContainer(uiLogic()->selectedServerIndex) == c) return;
|
||||
|
||||
m_settings.setDefaultContainer(uiLogic()->selectedServerIndex, c);
|
||||
uiLogic()->onUpdateAllPages();
|
||||
|
||||
if (uiLogic()->selectedServerIndex != m_settings.defaultServerIndex()) return;
|
||||
if (!uiLogic()->m_vpnConnection) return;
|
||||
if (!uiLogic()->m_vpnConnection->isConnected()) return;
|
||||
|
||||
uiLogic()->vpnLogic()->onDisconnect();
|
||||
uiLogic()->vpnLogic()->onConnect();
|
||||
}
|
||||
|
||||
void ServerContainersLogic::onPushButtonShareClicked(DockerContainer c)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "core/errorstrings.h"
|
||||
#include <core/servercontroller.h>
|
||||
#include <QTimer>
|
||||
|
||||
ServerSettingsLogic::ServerSettingsLogic(UiLogic *logic, QObject *parent):
|
||||
PageLogicBase(logic, parent),
|
||||
|
|
@ -28,8 +29,8 @@ void ServerSettingsLogic::onUpdatePage()
|
|||
set_pushButtonClearVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex));
|
||||
set_pushButtonClearClientCacheVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex));
|
||||
set_pushButtonShareFullVisible(m_settings.haveAuthData(uiLogic()->selectedServerIndex));
|
||||
QJsonObject server = m_settings.server(uiLogic()->selectedServerIndex);
|
||||
QString port = server.value(config_key::port).toString();
|
||||
const QJsonObject &server = m_settings.server(uiLogic()->selectedServerIndex);
|
||||
const QString &port = server.value(config_key::port).toString();
|
||||
set_labelServerText(QString("%1@%2%3%4")
|
||||
.arg(server.value(config_key::userName).toString())
|
||||
.arg(server.value(config_key::hostName).toString())
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
#include <QBuffer>
|
||||
#include <QImage>
|
||||
#include <QDataStream>
|
||||
#include <QZXing>
|
||||
//#include <QZXing>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "QZXing.h"
|
||||
#include "QZXingImageProvider.h"
|
||||
#include "QZXingFilter.h"
|
||||
|
||||
#include "ShareConnectionLogic.h"
|
||||
|
||||
#include "configurators/cloak_configurator.h"
|
||||
|
|
@ -60,21 +64,24 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
|||
set_shareAmneziaQrCodeTextSeriesLength(0);
|
||||
|
||||
QJsonObject serverConfig;
|
||||
int serverIndex = uiLogic()->selectedServerIndex;
|
||||
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||
|
||||
// Full access
|
||||
if (shareFullAccess()) {
|
||||
serverConfig = m_settings.server(uiLogic()->selectedServerIndex);
|
||||
serverConfig = m_settings.server(serverIndex);
|
||||
}
|
||||
// Container share
|
||||
else {
|
||||
ServerCredentials credentials = m_settings.serverCredentials(uiLogic()->selectedServerIndex);
|
||||
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(uiLogic()->selectedDockerContainer));
|
||||
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||
QJsonObject containerConfig = m_settings.containerConfig(serverIndex, container);
|
||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
for (Proto p: ContainerProps::protocolsForContainer(uiLogic()->selectedDockerContainer)) {
|
||||
QJsonObject protoConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p);
|
||||
for (Proto p: ContainerProps::protocolsForContainer(container)) {
|
||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, p);
|
||||
|
||||
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, p, &e);
|
||||
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, container, containerConfig, p, &e);
|
||||
if (e) {
|
||||
cfg = "Error generating config";
|
||||
break;
|
||||
|
|
@ -85,12 +92,17 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
|||
|
||||
QByteArray ba;
|
||||
if (!e) {
|
||||
serverConfig = m_settings.server(uiLogic()->selectedServerIndex);
|
||||
serverConfig = m_settings.server(serverIndex);
|
||||
serverConfig.remove(config_key::userName);
|
||||
serverConfig.remove(config_key::password);
|
||||
serverConfig.remove(config_key::port);
|
||||
serverConfig.insert(config_key::containers, QJsonArray {containerConfig});
|
||||
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(uiLogic()->selectedDockerContainer));
|
||||
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||
|
||||
auto dns = VpnConfigurator::getDnsForConfig(serverIndex);
|
||||
serverConfig.insert(config_key::dns1, dns.first);
|
||||
serverConfig.insert(config_key::dns2, dns.second);
|
||||
|
||||
}
|
||||
else {
|
||||
set_textEditShareAmneziaCodeText(tr("Error while generating connection profile"));
|
||||
|
|
@ -111,12 +123,15 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
|||
|
||||
void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
|
||||
{
|
||||
ServerCredentials credentials = m_settings.serverCredentials(uiLogic()->selectedServerIndex);
|
||||
const QJsonObject &containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||
int serverIndex = uiLogic()->selectedServerIndex;
|
||||
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||
|
||||
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
|
||||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, &e);
|
||||
cfg = VpnConfigurator::processConfigWithExportSettings(uiLogic()->selectedDockerContainer, Proto::OpenVpn, cfg);
|
||||
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, container, containerConfig, &e);
|
||||
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::OpenVpn, cfg);
|
||||
|
||||
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
|
||||
}
|
||||
|
|
@ -202,7 +217,7 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
|
|||
errorString(e));
|
||||
return;
|
||||
}
|
||||
cfg = VpnConfigurator::processConfigWithExportSettings(container, Proto::WireGuard, cfg);
|
||||
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::WireGuard, cfg);
|
||||
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();
|
||||
|
||||
set_textEditShareWireGuardCodeText(cfg);
|
||||
|
|
@ -223,7 +238,7 @@ void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
|
|||
Ikev2Configurator::ConnectionData connData = Ikev2Configurator::prepareIkev2Config(credentials, container);
|
||||
|
||||
QString cfg = Ikev2Configurator::genIkev2Config(connData);
|
||||
cfg = VpnConfigurator::processConfigWithExportSettings(container, Proto::Ikev2, cfg);
|
||||
cfg = VpnConfigurator::processConfigWithExportSettings(serverIndex, container, Proto::Ikev2, cfg);
|
||||
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString();
|
||||
|
||||
set_textEditShareIkev2CertText(cfg);
|
||||
|
|
|
|||
|
|
@ -206,6 +206,6 @@ void SitesLogic::onPushButtonSitesExportClicked()
|
|||
for (auto s : sites.keys()) {
|
||||
data += s + "\t" + sites.value(s).toString() + "\n";
|
||||
}
|
||||
uiLogic()->saveTextFile("Sites", ".txt", data);
|
||||
uiLogic()->saveTextFile("Export Sites", "sites.txt", ".txt", data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
#include <QApplication>
|
||||
|
||||
#include "VpnLogic.h"
|
||||
|
||||
#include "core/errorstrings.h"
|
||||
#include "vpnconnection.h"
|
||||
#include <QTimer>
|
||||
#include <functional>
|
||||
#include "../uilogic.h"
|
||||
#include "defines.h"
|
||||
#include <configurators/vpn_configurator.h>
|
||||
|
||||
|
||||
VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
|
||||
|
|
@ -18,6 +22,8 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
|
|||
m_labelSpeedReceivedText{tr("0 Mbps")},
|
||||
m_labelSpeedSentText{tr("0 Mbps")},
|
||||
m_labelStateText{},
|
||||
m_isContainerHaveAuthData{false},
|
||||
m_isContainerSupportedByCurrentPlatform{false},
|
||||
m_widgetVpnModeEnabled{false}
|
||||
{
|
||||
connect(uiLogic()->m_vpnConnection, &VpnConnection::bytesChanged, this, &VpnLogic::onBytesChanged);
|
||||
|
|
@ -48,6 +54,8 @@ void VpnLogic::onUpdatePage()
|
|||
selectedContainer == DockerContainer::ShadowSocks||
|
||||
selectedContainer == DockerContainer::Cloak);
|
||||
|
||||
set_isContainerHaveAuthData(m_settings.haveAuthData(m_settings.defaultServerIndex()));
|
||||
|
||||
set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites || !isCustomRoutesSupported());
|
||||
set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites && isCustomRoutesSupported());
|
||||
set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites && isCustomRoutesSupported());
|
||||
|
|
@ -61,8 +69,18 @@ void VpnLogic::onUpdatePage()
|
|||
QString selectedContainerName = ContainerProps::containerHumanNames().value(selectedContainer);
|
||||
set_labelCurrentService(selectedContainerName);
|
||||
|
||||
set_isContainerWorkingOnPlatform(ContainerProps::isWorkingOnPlatform(selectedContainer));
|
||||
if (!isContainerWorkingOnPlatform()) {
|
||||
auto dns = VpnConfigurator::getDnsForConfig(m_settings.defaultServerIndex());
|
||||
set_amneziaDnsEnabled(dns.first == protocols::dns::amneziaDnsIp);
|
||||
if (dns.first == protocols::dns::amneziaDnsIp) {
|
||||
set_labelCurrentDns("On your server");
|
||||
}
|
||||
else {
|
||||
set_labelCurrentDns(dns.first + ", " + dns.second);
|
||||
}
|
||||
|
||||
|
||||
set_isContainerSupportedByCurrentPlatform(ContainerProps::isSupportedByCurrentPlatform(selectedContainer));
|
||||
if (!isContainerSupportedByCurrentPlatform()) {
|
||||
set_labelErrorText(tr("AmneziaVPN not supporting selected protocol on this device. Select another protocol."));
|
||||
}
|
||||
else {
|
||||
|
|
@ -224,6 +242,6 @@ void VpnLogic::onConnectWorker(int serverIndex, const ServerCredentials &credent
|
|||
|
||||
void VpnLogic::onDisconnect()
|
||||
{
|
||||
set_pushButtonConnectChecked(false);
|
||||
onConnectionStateChanged(VpnProtocol::Disconnected);
|
||||
emit disconnectFromVpn();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,14 @@ class VpnLogic : public PageLogicBase
|
|||
AUTO_PROPERTY(QString, labelStateText)
|
||||
AUTO_PROPERTY(QString, labelCurrentServer)
|
||||
AUTO_PROPERTY(QString, labelCurrentService)
|
||||
AUTO_PROPERTY(QString, labelCurrentDns)
|
||||
AUTO_PROPERTY(bool, amneziaDnsEnabled)
|
||||
|
||||
AUTO_PROPERTY(bool, pushButtonConnectEnabled)
|
||||
AUTO_PROPERTY(bool, pushButtonConnectVisible)
|
||||
AUTO_PROPERTY(bool, widgetVpnModeEnabled)
|
||||
AUTO_PROPERTY(bool, isContainerWorkingOnPlatform)
|
||||
AUTO_PROPERTY(bool, isContainerSupportedByCurrentPlatform)
|
||||
AUTO_PROPERTY(bool, isContainerHaveAuthData)
|
||||
|
||||
AUTO_PROPERTY(QString, labelErrorText)
|
||||
AUTO_PROPERTY(QString, labelVersionText)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ using namespace amnezia;
|
|||
using namespace PageEnumNS;
|
||||
|
||||
OtherProtocolsLogic::OtherProtocolsLogic(UiLogic *logic, QObject *parent):
|
||||
PageProtocolLogicBase(logic, parent)
|
||||
PageProtocolLogicBase(logic, parent),
|
||||
m_checkBoxSftpRestoreChecked{false}
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@ import QtQuick.Controls 2.12
|
|||
|
||||
CheckBox {
|
||||
id: root
|
||||
property int imageWidth : 20
|
||||
property int imageHeight : 20
|
||||
indicator: Image {
|
||||
// y: 5
|
||||
id: indicator
|
||||
anchors.verticalCenter: root.verticalCenter
|
||||
height: 20
|
||||
width: 20
|
||||
height: imageHeight
|
||||
width: imageWidth
|
||||
source: root.checked ? "qrc:/images/controls/check_on.png"
|
||||
: "qrc:/images/controls/check_off.png"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ BasicButtonType {
|
|||
id: root
|
||||
property alias iconMargin: img.anchors.margins
|
||||
property alias img: img
|
||||
property int imgMargin: 4
|
||||
property int imgMarginHover: 3
|
||||
background: Item {}
|
||||
contentItem: Image {
|
||||
id: img
|
||||
source: root.icon.source
|
||||
anchors.fill: root
|
||||
anchors.margins: root.containsMouse ? 3 : 4
|
||||
anchors.margins: root.containsMouse ? imgMarginHover : imgMargin
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
client/ui/qml/Controls/RichLabelType.qml
Normal file
17
client/ui/qml/Controls/RichLabelType.qml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import QtQuick 2.12
|
||||
|
||||
LabelType {
|
||||
id: label_connection_code
|
||||
width: parent.width - 60
|
||||
x: 30
|
||||
font.pixelSize: 14
|
||||
textFormat: Text.RichText
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4,14 +4,18 @@ import QtQuick.Controls 2.12
|
|||
BasicButtonType {
|
||||
id: root
|
||||
property alias textItem: textItem
|
||||
height: 30
|
||||
|
||||
background: Item {}
|
||||
contentItem: Item {
|
||||
anchors.fill: parent
|
||||
Image {
|
||||
source: root.icon.source
|
||||
SvgImageType {
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
svg.source: root.icon.source
|
||||
color: "#100A44"
|
||||
width: 25
|
||||
height: 25
|
||||
}
|
||||
Text {
|
||||
id: textItem
|
||||
|
|
|
|||
16
client/ui/qml/Controls/SvgButtonType.qml
Normal file
16
client/ui/qml/Controls/SvgButtonType.qml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import "."
|
||||
|
||||
BasicButtonType {
|
||||
id: root
|
||||
icon.color: "#181922"
|
||||
|
||||
background: Item {}
|
||||
contentItem: SvgImageType {
|
||||
svg.source: icon.source
|
||||
color: icon.color
|
||||
anchors.fill: parent
|
||||
anchors.margins: parent.containsMouse ? 0 : 1
|
||||
}
|
||||
}
|
||||
23
client/ui/qml/Controls/SvgImageType.qml
Normal file
23
client/ui/qml/Controls/SvgImageType.qml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtGraphicalEffects 1.15
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property color color: "#181922"
|
||||
property alias svg: image
|
||||
Image {
|
||||
anchors.fill: parent
|
||||
id: image
|
||||
sourceSize: Qt.size(root.width, root.height)
|
||||
|
||||
antialiasing: true
|
||||
visible: false
|
||||
}
|
||||
|
||||
ColorOverlay {
|
||||
anchors.fill: image
|
||||
source: image
|
||||
color: root.color
|
||||
}
|
||||
}
|
||||
90
client/ui/qml/Pages/PageAbout.qml
Normal file
90
client/ui/qml/Pages/PageAbout.qml
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
import "../Config"
|
||||
|
||||
PageBase {
|
||||
id: root
|
||||
page: PageEnum.About
|
||||
|
||||
BackButton {
|
||||
id: back_from_start
|
||||
}
|
||||
|
||||
Caption {
|
||||
id: caption
|
||||
font.pixelSize: 22
|
||||
text: qsTr("About Amnezia")
|
||||
}
|
||||
|
||||
RichLabelType {
|
||||
id: label_about
|
||||
anchors.top: caption.bottom
|
||||
|
||||
text: qsTr("AmneziaVPN is opensource software, it's free forever. Our goal is to make the best VPN client in the world.
|
||||
<ul>
|
||||
<li>Sources on <a href=\"https://github.com/amnezia-vpn/desktop-client\">GitHub</a></li>
|
||||
<li><a href=\"https://amnezia.org/\">Web Site</a></li>
|
||||
<li><a href=\"https://t.me/amnezia_vpn_en\">Telegram group</a></li>
|
||||
<li><a href=\"https://signal.group/#CjQKIB2gUf8QH_IXnOJMGQWMDjYz9cNfmRQipGWLFiIgc4MwEhAKBONrSiWHvoUFbbD0xwdh\">Signal group</a></li>
|
||||
</ul>
|
||||
")
|
||||
}
|
||||
|
||||
Caption {
|
||||
id: caption2
|
||||
anchors.topMargin: 20
|
||||
font.pixelSize: 22
|
||||
text: qsTr("Support")
|
||||
anchors.top: label_about.bottom
|
||||
}
|
||||
|
||||
RichLabelType {
|
||||
id: label_support
|
||||
anchors.top: caption2.bottom
|
||||
|
||||
text: qsTr("Have questions? You can get support by:
|
||||
<ul>
|
||||
<li><a href=\"https://t.me/amnezia_vpn_en\">Telegram group</a> (preferred way)</li>
|
||||
<li>Create issue on <a href=\"https://github.com/amnezia-vpn/desktop-client/issues\">GitHub</a></li>
|
||||
<li>Email to: <a href=\"support@amnezia.org\">support@amnezia.org</a></li>
|
||||
</ul>")
|
||||
}
|
||||
|
||||
Caption {
|
||||
id: caption3
|
||||
anchors.topMargin: 20
|
||||
font.pixelSize: 22
|
||||
text: qsTr("Donate")
|
||||
width: undefined
|
||||
anchors.top: label_support.bottom
|
||||
}
|
||||
|
||||
LabelType {
|
||||
anchors.bottom: caption3.bottom
|
||||
anchors.left: caption3.right
|
||||
anchors.leftMargin: 5
|
||||
font.pixelSize: 24
|
||||
text: "♥"
|
||||
color: "red"
|
||||
}
|
||||
|
||||
RichLabelType {
|
||||
id: label_donate
|
||||
anchors.top: caption3.bottom
|
||||
|
||||
text: qsTr("Please support Amnezia project by donation, we really need it now more than ever.
|
||||
<ul>
|
||||
<li>By credit card on <a href=\"https://www.patreon.com/amneziavpn\">Patreon</a> (starting from $1)</li>
|
||||
<li>Send some coins to addresses listed <a href=\"https://github.com/amnezia-vpn/desktop-client/blob/master/README.md\">on GitHub page</a></li>
|
||||
</ul>
|
||||
")
|
||||
}
|
||||
|
||||
Logo {
|
||||
id: logo
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
|
@ -14,75 +15,131 @@ PageBase {
|
|||
id: back
|
||||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Application Settings")
|
||||
}
|
||||
CheckBoxType {
|
||||
x: 30
|
||||
y: 140
|
||||
width: 211
|
||||
height: 31
|
||||
text: qsTr("Auto connect")
|
||||
checked: AppSettingsLogic.checkBoxAutoConnectChecked
|
||||
onCheckedChanged: {
|
||||
AppSettingsLogic.checkBoxAutoConnectChecked = checked
|
||||
AppSettingsLogic.onCheckBoxAutoconnectToggled(checked)
|
||||
}
|
||||
}
|
||||
CheckBoxType {
|
||||
x: 30
|
||||
y: 100
|
||||
width: 211
|
||||
height: 31
|
||||
text: qsTr("Auto start")
|
||||
checked: AppSettingsLogic.checkBoxAutostartChecked
|
||||
onCheckedChanged: {
|
||||
AppSettingsLogic.checkBoxAutostartChecked = checked
|
||||
AppSettingsLogic.onCheckBoxAutostartToggled(checked)
|
||||
}
|
||||
}
|
||||
CheckBoxType {
|
||||
x: 30
|
||||
y: 180
|
||||
width: 211
|
||||
height: 31
|
||||
text: qsTr("Start minimized")
|
||||
checked: AppSettingsLogic.checkBoxStartMinimizedChecked
|
||||
onCheckedChanged: {
|
||||
AppSettingsLogic.checkBoxStartMinimizedChecked = checked
|
||||
AppSettingsLogic.onCheckBoxStartMinimizedToggled(checked)
|
||||
}
|
||||
}
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 240
|
||||
width: 281
|
||||
height: 21
|
||||
text: AppSettingsLogic.labelVersionText
|
||||
}
|
||||
BlueButtonType {
|
||||
x: 30
|
||||
y: 280
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - 40
|
||||
height: 41
|
||||
text: qsTr("Check for updates")
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||
}
|
||||
}
|
||||
BlueButtonType {
|
||||
x: 30
|
||||
y: 340
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: parent.width - 40
|
||||
height: 41
|
||||
text: qsTr("Open logs folder")
|
||||
onClicked: {
|
||||
AppSettingsLogic.onPushButtonOpenLogsClicked()
|
||||
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: caption.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.bottom: logo.top
|
||||
anchors.bottomMargin: 20
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
enabled: logic.pageEnabled
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
CheckBoxType {
|
||||
visible: !GC.isMobile()
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Auto connect")
|
||||
checked: AppSettingsLogic.checkBoxAutoConnectChecked
|
||||
onCheckedChanged: {
|
||||
AppSettingsLogic.checkBoxAutoConnectChecked = checked
|
||||
AppSettingsLogic.onCheckBoxAutoconnectToggled(checked)
|
||||
}
|
||||
}
|
||||
CheckBoxType {
|
||||
visible: !GC.isMobile()
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Auto start")
|
||||
checked: AppSettingsLogic.checkBoxAutostartChecked
|
||||
onCheckedChanged: {
|
||||
AppSettingsLogic.checkBoxAutostartChecked = checked
|
||||
AppSettingsLogic.onCheckBoxAutostartToggled(checked)
|
||||
}
|
||||
}
|
||||
CheckBoxType {
|
||||
visible: !GC.isMobile()
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Start minimized")
|
||||
checked: AppSettingsLogic.checkBoxStartMinimizedChecked
|
||||
onCheckedChanged: {
|
||||
AppSettingsLogic.checkBoxStartMinimizedChecked = checked
|
||||
AppSettingsLogic.onCheckBoxStartMinimizedToggled(checked)
|
||||
}
|
||||
}
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
text: AppSettingsLogic.labelVersionText
|
||||
}
|
||||
BlueButtonType {
|
||||
visible: !GC.isMobile()
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Check for updates")
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||
}
|
||||
}
|
||||
|
||||
CheckBoxType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
text: qsTr("Keep logs")
|
||||
checked: AppSettingsLogic.checkBoxSaveLogsChecked
|
||||
onCheckedChanged: {
|
||||
AppSettingsLogic.checkBoxSaveLogsChecked = checked
|
||||
AppSettingsLogic.onCheckBoxSaveLogsCheckedToggled(checked)
|
||||
}
|
||||
}
|
||||
BlueButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Open logs folder")
|
||||
onClicked: {
|
||||
AppSettingsLogic.onPushButtonOpenLogsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
BlueButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Export logs")
|
||||
onClicked: {
|
||||
AppSettingsLogic.onPushButtonExportLogsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
BlueButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
Layout.preferredHeight: 41
|
||||
|
||||
property string start_text: qsTr("Clear logs")
|
||||
property string end_text: qsTr("Cleared")
|
||||
text: start_text
|
||||
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 1000; running: false; repeat: false
|
||||
onTriggered: parent.text = parent.start_text
|
||||
}
|
||||
onClicked: {
|
||||
text = end_text
|
||||
timer.running = true
|
||||
AppSettingsLogic.onPushButtonClearLogsClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Logo {
|
||||
id: logo
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.15
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
|
@ -12,176 +14,155 @@ PageBase {
|
|||
|
||||
BackButton {
|
||||
id: back
|
||||
z: -1
|
||||
}
|
||||
|
||||
// ---------- App settings ------------
|
||||
Rectangle {
|
||||
id: l1
|
||||
visible: !GC.isMobile()
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: back.bottom
|
||||
x: 20
|
||||
width: parent.width - 40
|
||||
height: GC.isMobile() ? 0: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
anchors.topMargin: 0
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 10
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
SettingButtonType {
|
||||
id: b1
|
||||
visible: !GC.isMobile()
|
||||
anchors.top: l1.bottom
|
||||
anchors.topMargin: GC.isMobile() ? 0: 15
|
||||
x: 30
|
||||
width: parent.width - 40
|
||||
height: GC.isMobile() ? 0: 30
|
||||
icon.source: "qrc:/images/settings.png"
|
||||
text: qsTr("App settings")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.AppSettings)
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
enabled: logic.pageEnabled
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 10
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 15
|
||||
|
||||
|
||||
// ---------- App settings ------------
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30
|
||||
icon.source: "qrc:/images/svg/settings_black_24dp.svg"
|
||||
text: qsTr("App settings")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.AppSettings)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Network settings ------------
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30
|
||||
icon.source: "qrc:/images/svg/settings_suggest_black_24dp.svg"
|
||||
text: qsTr("Network settings")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.NetworkSettings)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Server settings ------------
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30
|
||||
icon.source: "qrc:/images/svg/vpn_key_black_24dp.svg"
|
||||
text: qsTr("Server Settings")
|
||||
onClicked: {
|
||||
GeneralSettingsLogic.onPushButtonGeneralSettingsServerSettingsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Share connection ------------
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30
|
||||
icon.source: "qrc:/images/svg/share_black_24dp.svg"
|
||||
text: qsTr("Share connection")
|
||||
enabled: GeneralSettingsLogic.pushButtonGeneralSettingsShareConnectionEnable
|
||||
onClicked: {
|
||||
GeneralSettingsLogic.onPushButtonGeneralSettingsShareConnectionClicked()
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Servers ------------
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30
|
||||
icon.source: "qrc:/images/svg/format_list_bulleted_black_24dp.svg"
|
||||
text: qsTr("Servers")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.ServersList)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Add server ------------
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30
|
||||
icon.source: "qrc:/images/svg/control_point_black_24dp.svg"
|
||||
text: qsTr("Add server")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.Start)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: fl.height > (75+1) * 6 ? fl.height - (75+1) * 6 : 0
|
||||
}
|
||||
|
||||
SettingButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 30
|
||||
Layout.bottomMargin: 20
|
||||
icon.source: "qrc:/images/svg/logout_black_24dp.svg"
|
||||
text: qsTr("Exit")
|
||||
onClicked: {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Network settings ------------
|
||||
Rectangle {
|
||||
id: l2
|
||||
anchors.top: b1.bottom
|
||||
anchors.topMargin: 15
|
||||
x: 20
|
||||
width: parent.width - 40
|
||||
height: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
id: b2
|
||||
x: 30
|
||||
anchors.top: l2.bottom
|
||||
anchors.topMargin: 15
|
||||
width: parent.width - 40
|
||||
height: 30
|
||||
icon.source: "qrc:/images/settings.png"
|
||||
text: qsTr("Network settings")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.NetworkSettings)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Server settings ------------
|
||||
Rectangle {
|
||||
id: l3
|
||||
anchors.top: b2.bottom
|
||||
anchors.topMargin: 15
|
||||
x: 20
|
||||
width: parent.width - 40
|
||||
height: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
id: b3
|
||||
x: 30
|
||||
anchors.top: l3.bottom
|
||||
anchors.topMargin: 15
|
||||
width: 330
|
||||
height: 30
|
||||
icon.source: "qrc:/images/server_settings.png"
|
||||
text: qsTr("Server Settings")
|
||||
onClicked: {
|
||||
GeneralSettingsLogic.onPushButtonGeneralSettingsServerSettingsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Share connection ------------
|
||||
Rectangle {
|
||||
id: l4
|
||||
anchors.top: b3.bottom
|
||||
anchors.topMargin: 15
|
||||
x: 20
|
||||
width: parent.width - 40
|
||||
height: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
id: b4
|
||||
x: 30
|
||||
anchors.top: l4.bottom
|
||||
anchors.topMargin: 15
|
||||
width: 330
|
||||
height: 30
|
||||
icon.source: "qrc:/images/share.png"
|
||||
text: qsTr("Share connection")
|
||||
enabled: GeneralSettingsLogic.pushButtonGeneralSettingsShareConnectionEnable
|
||||
onClicked: {
|
||||
GeneralSettingsLogic.onPushButtonGeneralSettingsShareConnectionClicked()
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Servers ------------
|
||||
Rectangle {
|
||||
id: l5
|
||||
anchors.top: b4.bottom
|
||||
anchors.topMargin: 15
|
||||
x: 20
|
||||
width: parent.width - 40
|
||||
height: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
id: b5
|
||||
x: 30
|
||||
anchors.top: l5.bottom
|
||||
anchors.topMargin: 15
|
||||
width: 330
|
||||
height: 30
|
||||
icon.source: "qrc:/images/server_settings.png"
|
||||
text: qsTr("Servers")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.ServersList)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- Add server ------------
|
||||
Rectangle {
|
||||
id: l6
|
||||
anchors.top: b5.bottom
|
||||
anchors.topMargin: 15
|
||||
x: 20
|
||||
width: parent.width - 40
|
||||
height: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
SettingButtonType {
|
||||
id: b6
|
||||
x: 30
|
||||
anchors.top: l6.bottom
|
||||
anchors.topMargin: 15
|
||||
width: 330
|
||||
height: 30
|
||||
icon.source: "qrc:/images/plus.png"
|
||||
text: qsTr("Add server")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.Start)
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: l7
|
||||
anchors.top: b6.bottom
|
||||
anchors.topMargin: 15
|
||||
x: 20
|
||||
width: parent.width - 40
|
||||
height: 1
|
||||
color: "#DDDDDD"
|
||||
}
|
||||
|
||||
|
||||
SettingButtonType {
|
||||
x: 30
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 20
|
||||
width: 330
|
||||
height: 30
|
||||
icon.source: "qrc:/images/settings.png"
|
||||
text: qsTr("Exit")
|
||||
onClicked: {
|
||||
Qt.quit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,17 +17,42 @@ PageBase {
|
|||
id: caption
|
||||
text: qsTr("DNS Servers")
|
||||
}
|
||||
|
||||
CheckBoxType {
|
||||
id: cb_amnezia_dns
|
||||
anchors.top: caption.bottom
|
||||
x: 30
|
||||
width: parent.width - 60
|
||||
text: qsTr("Use AmneziaDNS service (recommended)")
|
||||
checked: NetworkSettingsLogic.checkBoxUseAmneziaDnsChecked
|
||||
onCheckedChanged: {
|
||||
NetworkSettingsLogic.checkBoxUseAmneziaDnsChecked = checked
|
||||
NetworkSettingsLogic.onCheckBoxUseAmneziaDnsToggled(checked)
|
||||
UiLogic.onUpdateAllPages()
|
||||
}
|
||||
}
|
||||
|
||||
LabelType {
|
||||
id: lb_amnezia_dns
|
||||
x: 30
|
||||
anchors.top: cb_amnezia_dns.bottom
|
||||
width: parent.width - 60
|
||||
text: qsTr("Use AmneziaDNS container on your server, when it installed.\n
|
||||
Your AmneziaDNS server available only when it installed and VPN connected, it has internal IP address 172.29.172.254\n
|
||||
If AmneziaDNS service is not installed on the same server, or this option is unchecked, the following DNS servers will be used:")
|
||||
}
|
||||
|
||||
LabelType {
|
||||
id: l1
|
||||
x: 40
|
||||
anchors.top: caption.bottom
|
||||
width: parent.width - 40
|
||||
x: 30
|
||||
anchors.top: lb_amnezia_dns.bottom
|
||||
width: parent.width - 30
|
||||
height: 21
|
||||
text: qsTr("Primary DNS server")
|
||||
}
|
||||
TextFieldType {
|
||||
id: dns1
|
||||
x: 40
|
||||
x: 30
|
||||
anchors.top: l1.bottom
|
||||
width: parent.width - 90
|
||||
height: 40
|
||||
|
|
@ -35,36 +60,38 @@ PageBase {
|
|||
onEditingFinished: {
|
||||
NetworkSettingsLogic.lineEditDns1Text = text
|
||||
NetworkSettingsLogic.onLineEditDns1EditFinished(text)
|
||||
UiLogic.onUpdateAllPages()
|
||||
}
|
||||
validator: RegExpValidator {
|
||||
regExp: NetworkSettingsLogic.ipAddressRegex
|
||||
}
|
||||
}
|
||||
ImageButtonType {
|
||||
SvgButtonType {
|
||||
id: resetDNS1
|
||||
anchors. left: dns1.right
|
||||
anchors.leftMargin: 10
|
||||
anchors.verticalCenter: dns1.verticalCenter
|
||||
width: 24
|
||||
height: 24
|
||||
icon.source: "qrc:/images/reload.png"
|
||||
icon.source: "qrc:/images/svg/refresh_black_24dp.svg"
|
||||
onClicked: {
|
||||
NetworkSettingsLogic.onPushButtonResetDns1Clicked()
|
||||
UiLogic.onUpdateAllPages()
|
||||
}
|
||||
}
|
||||
|
||||
LabelType {
|
||||
id: l2
|
||||
x: 40
|
||||
x: 30
|
||||
anchors.top: dns1.bottom
|
||||
anchors.topMargin: 20
|
||||
width: parent.width - 40
|
||||
width: parent.width - 60
|
||||
height: 21
|
||||
text: qsTr("Secondray DNS server")
|
||||
}
|
||||
TextFieldType {
|
||||
id: dns2
|
||||
x: 40
|
||||
x: 30
|
||||
anchors.top: l2.bottom
|
||||
width: parent.width - 90
|
||||
height: 40
|
||||
|
|
@ -72,21 +99,23 @@ PageBase {
|
|||
onEditingFinished: {
|
||||
NetworkSettingsLogic.lineEditDns2Text = text
|
||||
NetworkSettingsLogic.onLineEditDns2EditFinished(text)
|
||||
UiLogic.onUpdateAllPages()
|
||||
}
|
||||
validator: RegExpValidator {
|
||||
regExp: NetworkSettingsLogic.ipAddressRegex
|
||||
}
|
||||
}
|
||||
ImageButtonType {
|
||||
SvgButtonType {
|
||||
id: resetDNS2
|
||||
anchors. left: dns2.right
|
||||
anchors.leftMargin: 10
|
||||
anchors.verticalCenter: dns2.verticalCenter
|
||||
width: 24
|
||||
height: 24
|
||||
icon.source: "qrc:/images/reload.png"
|
||||
icon.source: "qrc:/images/svg/refresh_black_24dp.svg"
|
||||
onClicked: {
|
||||
NetworkSettingsLogic.onPushButtonResetDns2Clicked()
|
||||
UiLogic.onUpdateAllPages()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,10 @@ PageBase {
|
|||
|
||||
SelectContainer {
|
||||
id: container_selector
|
||||
onAboutToHide: {
|
||||
pageLoader.focus = true
|
||||
}
|
||||
|
||||
onContainerSelected: {
|
||||
var containerProto = ContainerProps.defaultProtocol(c_index)
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ PageBase {
|
|||
SelectContainer {
|
||||
id: container_selector
|
||||
|
||||
onAboutToHide: {
|
||||
pageLoader.focus = true
|
||||
}
|
||||
|
||||
onContainerSelected: {
|
||||
var containerProto = ContainerProps.defaultProtocol(c_index)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,20 +16,23 @@ PageBase {
|
|||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Servers list")
|
||||
text: qsTr("Servers")
|
||||
width: undefined
|
||||
}
|
||||
ImageButtonType {
|
||||
anchors.bottom: caption.bottom
|
||||
|
||||
SvgButtonType {
|
||||
anchors.verticalCenter: caption.verticalCenter
|
||||
anchors.leftMargin: 10
|
||||
anchors.left: caption.right
|
||||
width: 24
|
||||
height: 24
|
||||
icon.source: "qrc:/images/plus.png"
|
||||
width: 27
|
||||
height: 27
|
||||
|
||||
icon.source: "qrc:/images/svg/control_point_black_24dp.svg"
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.Start);
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listWidget_servers
|
||||
x: 20
|
||||
|
|
@ -124,13 +127,13 @@ PageBase {
|
|||
checked: is_default
|
||||
enabled: !is_default
|
||||
}
|
||||
ImageButtonType {
|
||||
SvgButtonType {
|
||||
id: pushButtonSetting
|
||||
x: parent.width - 70
|
||||
y: 15
|
||||
width: 30
|
||||
height: 30
|
||||
icon.source: "qrc:/images/settings.png"
|
||||
icon.source: "qrc:/images/svg/settings_black_24dp.svg"
|
||||
opacity: 0
|
||||
|
||||
OpacityAnimator {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,16 @@ PageBase {
|
|||
horizontalAlignment: Text.AlignHCenter
|
||||
text: ServerSettingsLogic.labelCurrentVpnProtocolText
|
||||
}
|
||||
LabelType {
|
||||
// LabelType {
|
||||
// anchors.horizontalCenter: parent.horizontalCenter
|
||||
// y: 120
|
||||
// width: 341
|
||||
// height: 31
|
||||
// font.pixelSize: 20
|
||||
// horizontalAlignment: Text.AlignHCenter
|
||||
// text: ServerSettingsLogic.labelServerText
|
||||
// }
|
||||
TextFieldType {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: 120
|
||||
width: 341
|
||||
|
|
@ -36,7 +45,10 @@ PageBase {
|
|||
font.pixelSize: 20
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: ServerSettingsLogic.labelServerText
|
||||
readOnly: true
|
||||
background: Item {}
|
||||
}
|
||||
|
||||
LabelType {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: 530
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
|
@ -14,93 +15,99 @@ PageBase {
|
|||
id: back_from_setup_wizard
|
||||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Setup your server to use VPN")
|
||||
}
|
||||
Item {
|
||||
x: 10
|
||||
y: 70
|
||||
width: 361
|
||||
height: 561
|
||||
LabelType {
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("I'm living in country with high censorship level. Many of foreign web sites and VPNs blocked by my government. I want to setup reliable VPN, which is invisible for government.")
|
||||
wrapMode: Text.Wrap
|
||||
x: 30
|
||||
y: 40
|
||||
width: 321
|
||||
height: 121
|
||||
}
|
||||
LabelType {
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("I'm living in country with medium censorship level. Some web sites blocked by my government, but VPNs are not blocked at all. I want to setup flexible solution.")
|
||||
wrapMode: Text.Wrap
|
||||
x: 30
|
||||
y: 210
|
||||
width: 321
|
||||
height: 121
|
||||
}
|
||||
LabelType {
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("I just want to improve my privacy in internet.")
|
||||
wrapMode: Text.Wrap
|
||||
x: 30
|
||||
y: 360
|
||||
width: 321
|
||||
height: 121
|
||||
}
|
||||
BlueButtonType {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
y: 490
|
||||
width: 321
|
||||
height: 40
|
||||
text: qsTr("Next")
|
||||
onClicked: {
|
||||
if (radioButton_setup_wizard_high.checked) {
|
||||
UiLogic.goToPage(PageEnum.WizardHigh);
|
||||
} else if (radioButton_setup_wizard_medium.checked) {
|
||||
UiLogic.goToPage(PageEnum.WizardMedium);
|
||||
} else if (radioButton_setup_wizard_low.checked) {
|
||||
UiLogic.goToPage(PageEnum.WizardLow);
|
||||
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: caption.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 20
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
enabled: logic.pageEnabled
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
RadioButtonType {
|
||||
id: radioButton_setup_wizard_high
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("High censorship level")
|
||||
checked: WizardLogic.radioButtonHighChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.radioButtonHighChecked = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
RadioButtonType {
|
||||
id: radioButton_setup_wizard_high
|
||||
x: 10
|
||||
y: 10
|
||||
width: 331
|
||||
height: 25
|
||||
text: qsTr("High censorship level")
|
||||
checked: WizardLogic.radioButtonHighChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.radioButtonHighChecked = checked
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 25
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("I'm living in a country with a high censorship level. Many of the foreign websites and VPNs are blocked by my government. I want to setup a reliable VPN, which can not be detected by my internet provider and my government.
|
||||
OpenVPN and ShadowSocks over Cloak (VPN obfuscation) profiles will be installed.\n")
|
||||
}
|
||||
}
|
||||
RadioButtonType {
|
||||
id: radioButton_setup_wizard_medium
|
||||
x: 10
|
||||
y: 330
|
||||
width: 331
|
||||
height: 25
|
||||
text: qsTr("Low censorship level")
|
||||
checked: WizardLogic.radioButtonLowChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.radioButtonLowChecked = checked
|
||||
|
||||
|
||||
RadioButtonType {
|
||||
id: radioButton_setup_wizard_medium
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Medium censorship level")
|
||||
checked: WizardLogic.radioButtonMediumChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.radioButtonMediumChecked = checked
|
||||
}
|
||||
}
|
||||
}
|
||||
RadioButtonType {
|
||||
id: radioButton_setup_wizard_low
|
||||
x: 10
|
||||
y: 180
|
||||
width: 331
|
||||
height: 25
|
||||
text: qsTr("Medium censorship level")
|
||||
checked: WizardLogic.radioButtonMediumChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.radioButtonMediumChecked = checked
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 25
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("I'm living in a country with a medium censorship level. Some websites are blocked by my government, but VPNs are not blocked at all. I want to setup a flexible solution.
|
||||
OpenVPN over ShadowSocks profile will be installed.\n")
|
||||
}
|
||||
|
||||
|
||||
RadioButtonType {
|
||||
id: radioButton_setup_wizard_low
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Low censorship level")
|
||||
checked: WizardLogic.radioButtonLowChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.radioButtonLowChecked = checked
|
||||
}
|
||||
}
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 25
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("I want to improve my privacy on the internet.
|
||||
OpenVPN profile will be installed.\n")
|
||||
}
|
||||
|
||||
|
||||
BlueButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Next")
|
||||
onClicked: {
|
||||
if (radioButton_setup_wizard_high.checked) {
|
||||
UiLogic.goToPage(PageEnum.WizardHigh, false);
|
||||
} else if (radioButton_setup_wizard_medium.checked) {
|
||||
UiLogic.goToPage(PageEnum.WizardMedium, false);
|
||||
} else if (radioButton_setup_wizard_low.checked) {
|
||||
UiLogic.goToPage(PageEnum.WizardLow, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
|
@ -14,69 +15,90 @@ PageBase {
|
|||
id: back_from_setup_wizard
|
||||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Setup Wizard")
|
||||
}
|
||||
Item {
|
||||
x: 10
|
||||
y: 70
|
||||
width: 361
|
||||
height: 561
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 10
|
||||
width: 321
|
||||
height: 321
|
||||
text: qsTr("AmneziaVPN will install VPN protocol which is not visible for your internet provider and government firewall. Your VPN connection will be detected by your provider as regular web traffic to particular web site.\n\nYou SHOULD set this web site address to some foreign web site which is updatesnot blocked by your internet provider. Other words you need to type below some foreign web site address which is accessible without VPN.\n\nPlease note, this protocol still does not support export connection profile to mobile devices. Keep for updates.")
|
||||
}
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 400
|
||||
width: 321
|
||||
height: 71
|
||||
text: qsTr("OpenVPN over Cloak (VPN obfuscation) profile will be installed")
|
||||
}
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 330
|
||||
width: 291
|
||||
height: 21
|
||||
text: qsTr("Type web site address for mask")
|
||||
}
|
||||
TextFieldType {
|
||||
id: website_masking
|
||||
x: 30
|
||||
y: 360
|
||||
width: 301
|
||||
height: 41
|
||||
text: WizardLogic.lineEditHighWebsiteMaskingText
|
||||
onEditingFinished: {
|
||||
let _text = website_masking.text
|
||||
_text.replace("http://", "");
|
||||
_text.replace("https://", "");
|
||||
if (!_text) {
|
||||
return
|
||||
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: caption.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 20
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
enabled: logic.pageEnabled
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("AmneziaVPN will install a VPN protocol which is not visible to your internet provider and government firewall. Your VPN connection will be seen by your internet provider as regular web traffic to a particular website.
|
||||
|
||||
You SHOULD set this website address to some foreign website which is not blocked by your internet provider. In other words, you need to type some foreign website address which is accessible to you without a VPN.")
|
||||
}
|
||||
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("Type another web site address for masking or keep it by default. Your internet provider will think you working on this web site when you connected to VPN.")
|
||||
}
|
||||
|
||||
TextFieldType {
|
||||
id: website_masking
|
||||
Layout.fillWidth: true
|
||||
text: WizardLogic.lineEditHighWebsiteMaskingText
|
||||
onEditingFinished: {
|
||||
let _text = website_masking.text
|
||||
_text.replace("http://", "");
|
||||
_text.replace("https://", "");
|
||||
if (!_text) {
|
||||
return
|
||||
}
|
||||
_text = _text.split("/").first();
|
||||
WizardLogic.lineEditHighWebsiteMaskingText = _text
|
||||
}
|
||||
_text = _text.split("/").first();
|
||||
WizardLogic.lineEditHighWebsiteMaskingText = _text
|
||||
}
|
||||
onAccepted: {
|
||||
next_button.clicked()
|
||||
}
|
||||
}
|
||||
BlueButtonType {
|
||||
id: next_button
|
||||
x: 30
|
||||
y: 490
|
||||
width: 301
|
||||
height: 40
|
||||
text: qsTr("Next")
|
||||
onClicked: {
|
||||
let domain = website_masking.text;
|
||||
if (!domain || !domain.includes(".")) {
|
||||
return
|
||||
onAccepted: {
|
||||
next_button.clicked()
|
||||
}
|
||||
UiLogic.goToPage(PageEnum.WizardVpnMode)
|
||||
}
|
||||
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr("OpenVPN and ShadowSocks over Cloak (VPN obfuscation) profiles will be installed.
|
||||
|
||||
This protocol support exporting connection profiles to mobile devices by exporting ShadowSocks and Cloak configs (you should launch the 3rd party open source VPN client - ShadowSocks VPN and install Cloak plugin).")
|
||||
}
|
||||
BlueButtonType {
|
||||
id: next_button
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Next")
|
||||
onClicked: {
|
||||
let domain = website_masking.text;
|
||||
if (!domain || !domain.includes(".")) {
|
||||
return
|
||||
}
|
||||
UiLogic.goToPage(PageEnum.WizardVpnMode, false)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
|
@ -14,38 +15,56 @@ PageBase {
|
|||
id: back_from_setup_wizard
|
||||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Setup Wizard")
|
||||
}
|
||||
Item {
|
||||
x: 10
|
||||
y: 70
|
||||
width: 361
|
||||
height: 561
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 10
|
||||
width: 321
|
||||
height: 341
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr('AmneziaVPN will install OpenVPN protocol with public/private key pairs generated on server and client sides. You can also configure connection on your mobile device by copying exported ".ovpn" file to your device and setting up official OpenVPN client. We recommend do not use messengers for sending connection profile - it contains VPN private keys.')
|
||||
}
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 400
|
||||
width: 321
|
||||
height: 71
|
||||
text: qsTr('OpenVPN profile will be installed')
|
||||
verticalAlignment: Text.AlignBottom
|
||||
}
|
||||
BlueButtonType {
|
||||
id: next_button
|
||||
x: 30
|
||||
y: 490
|
||||
width: 301
|
||||
height: 40
|
||||
text: qsTr("Start configuring")
|
||||
onClicked: {
|
||||
WizardLogic.onPushButtonLowFinishClicked()
|
||||
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: caption.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 20
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
enabled: logic.pageEnabled
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr('AmneziaVPN will install the OpenVPN protocol with public/private key pairs generated on both server and client sides.
|
||||
|
||||
You can also configure the connection on your mobile device by copying the exported ".ovpn" file to your device, and setting up the official OpenVPN client.
|
||||
|
||||
We recommend not to use messaging applications for sending the connection profile - it contains VPN private keys.')
|
||||
}
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
text: qsTr('OpenVPN profile will be installed')
|
||||
verticalAlignment: Text.AlignBottom
|
||||
}
|
||||
BlueButtonType {
|
||||
id: next_button
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Start configuring")
|
||||
onClicked: {
|
||||
WizardLogic.onPushButtonLowFinishClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
|
@ -14,38 +15,51 @@ PageBase {
|
|||
id: back_from_setup_wizard
|
||||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Setup Wizard")
|
||||
}
|
||||
Item {
|
||||
x: 10
|
||||
y: 70
|
||||
width: 361
|
||||
height: 561
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 10
|
||||
width: 321
|
||||
height: 341
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr('AmneziaVPN will install VPN protocol which is difficult to detect by your internet provider and government firewall (but possible). In most cases, this is the most suitable protocol. This protocol is faster compared to the VPN protocols with "web traffic masking".\n\nThis protocol support export connection profile to mobile devices using QR code (you should launch 3rd party opensource VPN client - ShadowSocks VPN).')
|
||||
}
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 400
|
||||
width: 321
|
||||
height: 71
|
||||
text: qsTr('OpenVPN over ShadowSocks profile will be installed')
|
||||
verticalAlignment: Text.AlignBottom
|
||||
}
|
||||
BlueButtonType {
|
||||
id: next_button
|
||||
x: 30
|
||||
y: 490
|
||||
width: 301
|
||||
height: 40
|
||||
text: qsTr("Next")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.WizardVpnMode)
|
||||
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: caption.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 20
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
enabled: logic.pageEnabled
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr('AmneziaVPN will install a VPN protocol which is difficult to detect by your internet provider and government firewall (but possible). In most cases, this is the most suitable protocol. This protocol is faster compared to the VPN protocols with "VPN masking".\n\nThis protocol supports exporting connection profiles to mobile devices by using QR codes (you should launch the 3rd party open source VPN client - ShadowSocks VPN).')
|
||||
}
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
text: qsTr('OpenVPN over ShadowSocks profile will be installed')
|
||||
}
|
||||
BlueButtonType {
|
||||
id: next_button
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Next")
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.WizardVpnMode, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import PageEnum 1.0
|
||||
import "./"
|
||||
import "../Controls"
|
||||
|
|
@ -14,40 +15,57 @@ PageBase {
|
|||
id: back_from_setup_wizard
|
||||
}
|
||||
Caption {
|
||||
id: caption
|
||||
text: qsTr("Setup Wizard")
|
||||
}
|
||||
Item {
|
||||
x: 10
|
||||
y: 70
|
||||
width: 361
|
||||
height: 561
|
||||
CheckBoxType {
|
||||
x: 30
|
||||
y: 350
|
||||
width: 301
|
||||
height: 71
|
||||
text: qsTr('Turn on mode "VPN for selected sites"')
|
||||
checked: WizardLogic.checkBoxVpnModeChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.checkBoxVpnModeChecked = checked
|
||||
|
||||
Flickable {
|
||||
id: fl
|
||||
width: root.width
|
||||
anchors.top: caption.bottom
|
||||
anchors.topMargin: 20
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: 20
|
||||
anchors.left: root.left
|
||||
anchors.leftMargin: 30
|
||||
anchors.right: root.right
|
||||
anchors.rightMargin: 30
|
||||
|
||||
contentHeight: content.height
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
enabled: logic.pageEnabled
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
LabelType {
|
||||
Layout.fillWidth: true
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: qsTr('Optional.\n
|
||||
You can enable VPN mode "For selected sites" and add blocked sites you need to visit manually. If you will choose this option, you will need add every bloked site you want to visit to the access list. You may switch between modes later.\n\nPlease note, you should add addresses to the list after VPN connection established. You may add any domain, URL or IP address, it will be resolved to IP address.')
|
||||
}
|
||||
}
|
||||
LabelType {
|
||||
x: 30
|
||||
y: 10
|
||||
width: 321
|
||||
height: 341
|
||||
text: qsTr('Optional.\n\nWe recommend to enable VPN mode "For selected sites" and add blocked sites you need to visit manually. If you will choose this option, you will need add every bloked site you want to visit to the access list. You may switch between modes later.\n\nPlease note, you should add addresses to the list after VPN connection established. You may add any domain, URL or IP address, it will be resolved to IP address.')
|
||||
}
|
||||
BlueButtonType {
|
||||
id: vpn_mode_finish
|
||||
x: 30
|
||||
y: 490
|
||||
width: 301
|
||||
height: 40
|
||||
text: qsTr("Start configuring")
|
||||
onClicked: {
|
||||
WizardLogic.onPushButtonVpnModeFinishClicked()
|
||||
|
||||
CheckBoxType {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr('Turn on mode "VPN for selected sites"')
|
||||
checked: WizardLogic.checkBoxVpnModeChecked
|
||||
onCheckedChanged: {
|
||||
WizardLogic.checkBoxVpnModeChecked = checked
|
||||
}
|
||||
}
|
||||
|
||||
BlueButtonType {
|
||||
id: vpn_mode_finish
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 15
|
||||
Layout.preferredHeight: 41
|
||||
text: qsTr("Start configuring")
|
||||
onClicked: {
|
||||
WizardLogic.onPushButtonVpnModeFinishClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,8 +240,7 @@ PageBase {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
height: 71
|
||||
echoMode: TextInput.Password
|
||||
font.pixelSize: 9
|
||||
font.pixelSize: 10
|
||||
verticalAlignment: Text.AlignTop
|
||||
text: StartPageLogic.textEditSshKeyText
|
||||
onEditingFinished: {
|
||||
|
|
@ -264,6 +263,7 @@ PageBase {
|
|||
id: new_sever_connect
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: new_server_ssh_key.bottom
|
||||
anchors.topMargin: 10
|
||||
|
||||
text: StartPageLogic.pushButtonConnectText
|
||||
visible: StartPageLogic.pushButtonConnectVisible
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ PageBase {
|
|||
|
||||
LabelType {
|
||||
x: 10
|
||||
y: 5
|
||||
y: 10
|
||||
width: 100
|
||||
height: 21
|
||||
text: VpnLogic.labelVersionText
|
||||
|
|
@ -30,11 +30,40 @@ PageBase {
|
|||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
y: 10
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: 21
|
||||
background: Item {}
|
||||
|
||||
|
||||
contentItem: Text {
|
||||
anchors.fill: parent
|
||||
font.family: "Lato"
|
||||
font.styleName: "normal"
|
||||
font.pixelSize: 18
|
||||
font.underline: true
|
||||
|
||||
text: qsTr("Donate")
|
||||
color: "#D4D4D4"
|
||||
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.About)
|
||||
}
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
x: parent.width - 40
|
||||
y: 10
|
||||
width: 31
|
||||
height: 31
|
||||
y: 0
|
||||
width: 41
|
||||
height: 41
|
||||
imgMarginHover: 8
|
||||
imgMargin: 9
|
||||
icon.source: "qrc:/images/settings_grey.png"
|
||||
onClicked: {
|
||||
UiLogic.goToPage(PageEnum.GeneralSettings)
|
||||
|
|
@ -71,7 +100,7 @@ PageBase {
|
|||
}
|
||||
contentItem: Item {}
|
||||
antialiasing: true
|
||||
enabled: VpnLogic.pushButtonConnectEnabled && VpnLogic.isContainerWorkingOnPlatform
|
||||
enabled: VpnLogic.pushButtonConnectEnabled && VpnLogic.isContainerSupportedByCurrentPlatform
|
||||
opacity: VpnLogic.pushButtonConnectVisible ? 1 : 0
|
||||
|
||||
// transitions: Transition {
|
||||
|
|
@ -101,14 +130,14 @@ PageBase {
|
|||
LabelType {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
height: 21
|
||||
text: qsTr("Server") + ": "
|
||||
text: ( VpnLogic.isContainerHaveAuthData ? qsTr("Server") : qsTr("Profile")) + ": "
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
height: 21
|
||||
background: Item {}
|
||||
text: VpnLogic.labelCurrentServer + " →"
|
||||
text: VpnLogic.labelCurrentServer + (VpnLogic.isContainerHaveAuthData ? " →" : "")
|
||||
font.family: "Lato"
|
||||
font.styleName: "normal"
|
||||
font.pixelSize: 16
|
||||
|
|
@ -129,27 +158,63 @@ PageBase {
|
|||
LabelType {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
height: 21
|
||||
text: qsTr("Service") + ": "
|
||||
text: qsTr("Proto") + ": "
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
height: 21
|
||||
background: Item {}
|
||||
text: VpnLogic.labelCurrentService + " →"
|
||||
text: VpnLogic.labelCurrentService + (VpnLogic.isContainerHaveAuthData ? " →" : "")
|
||||
font.family: "Lato"
|
||||
font.styleName: "normal"
|
||||
font.pixelSize: 16
|
||||
onClicked: {
|
||||
UiLogic.onGotoCurrentProtocolsPage()
|
||||
if (VpnLogic.isContainerHaveAuthData) UiLogic.onGotoCurrentProtocolsPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: layout3
|
||||
anchors.top: layout2.bottom
|
||||
anchors.topMargin: 5
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
height: 21
|
||||
|
||||
|
||||
LabelType {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
height: 21
|
||||
text: qsTr("DNS") + ": "
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
height: 21
|
||||
implicitWidth: implicitContentWidth > root.width * 0.6 ? root.width * 0.6 : implicitContentWidth + leftPadding + rightPadding
|
||||
background: Item {}
|
||||
text: VpnLogic.labelCurrentDns + (VpnLogic.isContainerHaveAuthData ? " →" : "")
|
||||
font.family: "Lato"
|
||||
font.styleName: "normal"
|
||||
font.pixelSize: 16
|
||||
onClicked: {
|
||||
if (VpnLogic.isContainerHaveAuthData) UiLogic.goToPage(PageEnum.NetworkSettings)
|
||||
}
|
||||
}
|
||||
|
||||
SvgImageType {
|
||||
svg.source: VpnLogic.amneziaDnsEnabled ? "qrc:/images/svg/gpp_good_black_24dp.svg" : "qrc:/images/svg/gpp_maybe_black_24dp.svg"
|
||||
color: VpnLogic.amneziaDnsEnabled ? "#22aa33" : "orange"
|
||||
width: 25
|
||||
height: 25
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LabelType {
|
||||
id: error_text
|
||||
anchors.top: layout2.bottom
|
||||
anchors.top: layout3.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.topMargin: 20
|
||||
width: parent.width - 20
|
||||
|
|
|
|||
|
|
@ -77,24 +77,12 @@ PageProtocolBase {
|
|||
}
|
||||
}
|
||||
|
||||
LabelType {
|
||||
RichLabelType {
|
||||
anchors.bottom: check_persist.top
|
||||
anchors.bottomMargin: 10
|
||||
width: parent.width - 60
|
||||
x: 30
|
||||
font.pixelSize: 14
|
||||
textFormat: Text.RichText
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
|
||||
// text: "In order to mount remote SFTP folder as local drive, perform following steps:
|
||||
//- Install the latest version of WinFsp [https://github.com/billziss-gh/winfsp/releases/latest].
|
||||
//- Install the latest version of SSHFS-Win. Choose the x64 or x86 installer according to your computer's architecture [https://github.com/billziss-gh/sshfs-win/releases]"
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
|
||||
readonly property string windows_text: "In order to mount remote SFTP folder as local drive, perform following steps:
|
||||
<ul>
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ New encryption keys pair will be generated.")
|
|||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
onClicked: {
|
||||
UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "*.vpn", tfShareCode.textArea.text)
|
||||
UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "amnezia_config.vpn", "*.vpn", tfShareCode.textArea.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ PageShareProtocolBase {
|
|||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
onClicked: {
|
||||
UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "*.json", tfShareCode.textArea.text)
|
||||
UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "amnezia_config_cloak.json", "*.json", tfShareCode.textArea.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ PageShareProtocolBase {
|
|||
visible: tfCert.textArea.length > 0
|
||||
|
||||
onClicked: {
|
||||
UiLogic.saveTextFile(qsTr("Export p12 certificate"), "*.p12", tfCert.textArea.text)
|
||||
UiLogic.saveTextFile(qsTr("Export p12 certificate"), "amnezia_ikev2_cert_for_windows.p12", "*.p12", tfCert.textArea.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ PageShareProtocolBase {
|
|||
visible: tfMobileConfig.textArea.length > 0
|
||||
|
||||
onClicked: {
|
||||
UiLogic.saveTextFile(qsTr("Export config for Apple"), "*.plist", tfMobileConfig.textArea.text)
|
||||
UiLogic.saveTextFile(qsTr("Export config for Apple"), "amnezia_for_apple.plist", "*.plist", tfMobileConfig.textArea.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +132,7 @@ PageShareProtocolBase {
|
|||
visible: tfStrongSwanConfig.textArea.length > 0
|
||||
|
||||
onClicked: {
|
||||
UiLogic.saveTextFile(qsTr("Export config for StrongSwan"), "*.profile", tfStrongSwanConfig.textArea.text)
|
||||
UiLogic.saveTextFile(qsTr("Export config for StrongSwan"), "amnezia_for_StrongSwan.profile", "*.profile", tfStrongSwanConfig.textArea.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ PageShareProtocolBase {
|
|||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
onClicked: {
|
||||
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "*.ovpn", tfShareCode.textArea.text)
|
||||
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "amnezia_for_openvpn.ovpn", "*.ovpn", tfShareCode.textArea.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ PageShareProtocolBase {
|
|||
visible: tfShareCode.textArea.length > 0
|
||||
|
||||
onClicked: {
|
||||
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "*.conf", tfShareCode.textArea.text)
|
||||
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "amnezia_for_wireguard.conf", "*.conf", tfShareCode.textArea.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Window 2.14
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls.Material 2.12
|
||||
import PageEnum 1.0
|
||||
import PageType 1.0
|
||||
|
|
@ -8,6 +9,7 @@ import Qt.labs.platform 1.1
|
|||
import Qt.labs.folderlistmodel 2.12
|
||||
import QtQuick.Dialogs 1.1
|
||||
import "./"
|
||||
import "Controls"
|
||||
import "Pages"
|
||||
import "Pages/Protocols"
|
||||
import "Pages/Share"
|
||||
|
|
@ -22,7 +24,8 @@ Window {
|
|||
visible: true
|
||||
width: GC.screenWidth
|
||||
height: GC.isDesktop() ? GC.screenHeight + titleBar.height : GC.screenHeight
|
||||
Keys.enabled: true
|
||||
minimumWidth: 360
|
||||
minimumHeight: GC.isDesktop() ? 640 : 0
|
||||
onClosing: {
|
||||
console.debug("QML onClosing signal")
|
||||
UiLogic.onCloseWindow()
|
||||
|
|
@ -38,7 +41,7 @@ Window {
|
|||
else if (type === PageType.ShareProto) p_obj = sharePages[page]
|
||||
else return
|
||||
|
||||
console.debug("QML gotoPage " + type + " " + page + " " + p_obj)
|
||||
//console.debug("QML gotoPage " + type + " " + page + " " + p_obj)
|
||||
|
||||
if (pageLoader.depth > 0) {
|
||||
pageLoader.currentItem.deactivated()
|
||||
|
|
@ -118,7 +121,7 @@ Window {
|
|||
focus: true
|
||||
|
||||
onCurrentItemChanged: {
|
||||
console.debug("QML onCurrentItemChanged " + pageLoader.currentItem)
|
||||
//console.debug("QML onCurrentItemChanged " + pageLoader.currentItem)
|
||||
UiLogic.currentPageValue = currentItem.page
|
||||
}
|
||||
|
||||
|
|
@ -213,15 +216,15 @@ Window {
|
|||
Connections {
|
||||
target: UiLogic
|
||||
function onGoToPage(page, reset, slide) {
|
||||
console.debug("Qml Connections onGoToPage " + page);
|
||||
//console.debug("Qml Connections onGoToPage " + page);
|
||||
root.gotoPage(PageType.Basic, page, reset, slide)
|
||||
}
|
||||
function onGoToProtocolPage(protocol, reset, slide) {
|
||||
console.debug("Qml Connections onGoToProtocolPage " + protocol);
|
||||
//console.debug("Qml Connections onGoToProtocolPage " + protocol);
|
||||
root.gotoPage(PageType.Proto, protocol, reset, slide)
|
||||
}
|
||||
function onGoToShareProtocolPage(protocol, reset, slide) {
|
||||
console.debug("Qml Connections onGoToShareProtocolPage " + protocol);
|
||||
//console.debug("Qml Connections onGoToShareProtocolPage " + protocol);
|
||||
root.gotoPage(PageType.ShareProto, protocol, reset, slide)
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +252,9 @@ Window {
|
|||
root.raise()
|
||||
root.requestActivate()
|
||||
}
|
||||
function onToggleLogPanel() {
|
||||
drawer_log.visible = !drawer_log.visible
|
||||
}
|
||||
}
|
||||
|
||||
MessageDialog {
|
||||
|
|
@ -275,4 +281,114 @@ Window {
|
|||
text: UiLogic.dialogConnectErrorText
|
||||
visible: false
|
||||
}
|
||||
|
||||
Drawer {
|
||||
id: drawer_log
|
||||
|
||||
z: -3
|
||||
y: 0
|
||||
x: 0
|
||||
edge: Qt.BottomEdge
|
||||
width: parent.width
|
||||
height: parent.height * 0.85
|
||||
|
||||
modal: true
|
||||
//interactive: activeFocus
|
||||
|
||||
onAboutToHide: {
|
||||
pageLoader.focus = true
|
||||
}
|
||||
onAboutToShow: {
|
||||
tfSshLog.focus = true
|
||||
}
|
||||
|
||||
Item {
|
||||
id: itemLog
|
||||
anchors.fill: parent
|
||||
|
||||
Keys.onPressed: {
|
||||
UiLogic.keyPressEvent(event.key)
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
RadioButtonType {
|
||||
id: rbSshLog
|
||||
focus: false
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 2
|
||||
|
||||
height: 25
|
||||
text: qsTr("Ssh log")
|
||||
}
|
||||
RadioButtonType {
|
||||
id: rbAllLog
|
||||
focus: false
|
||||
checked: true
|
||||
anchors.left: rbSshLog.right
|
||||
anchors.bottom: rbSshLog.bottom
|
||||
anchors.top: rbSshLog.top
|
||||
height: rbSshLog.height
|
||||
text: qsTr("App log")
|
||||
}
|
||||
CheckBoxType {
|
||||
id: cbLogWrap
|
||||
text: qsTr("Wrap words")
|
||||
checked: true
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: rbAllLog.bottom
|
||||
anchors.top: rbAllLog.top
|
||||
height: 15
|
||||
imageHeight: 15
|
||||
imageWidth: 15
|
||||
|
||||
onCheckedChanged: {
|
||||
tfSshLog
|
||||
}
|
||||
}
|
||||
|
||||
TextAreaType {
|
||||
id: tfSshLog
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: rbSshLog.top
|
||||
|
||||
flickableDirection: Flickable.AutoFlickIfNeeded
|
||||
|
||||
textArea.readOnly: true
|
||||
textArea.selectByMouse: true
|
||||
|
||||
textArea.verticalAlignment: Text.AlignTop
|
||||
textArea.text: {
|
||||
if (!drawer_log.visible) return ""
|
||||
else if (rbSshLog.checked ) return Debug.sshLog
|
||||
else return Debug.allLog
|
||||
}
|
||||
textArea.wrapMode: cbLogWrap.checked ? TextEdit.WordWrap: TextEdit.NoWrap
|
||||
|
||||
Keys.onPressed: {
|
||||
UiLogic.keyPressEvent(event.key)
|
||||
event.accepted = true
|
||||
}
|
||||
|
||||
textArea.onTextChanged: {
|
||||
textArea.cursorPosition = textArea.length-1
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
enabled: GC.isDesktop()
|
||||
acceptedButtons: Qt.RightButton
|
||||
onClicked: contextMenu.open()
|
||||
}
|
||||
|
||||
ContextMenu {
|
||||
id: contextMenu
|
||||
textObj: tfSshLog.textArea
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QRegularExpression>
|
||||
#include <QQmlFile>
|
||||
|
||||
#include "configurators/cloak_configurator.h"
|
||||
#include "configurators/vpn_configurator.h"
|
||||
|
|
@ -29,7 +30,6 @@
|
|||
#include "core/errorstrings.h"
|
||||
|
||||
#include "containers/containers_defs.h"
|
||||
#include "protocols/shadowsocksvpnprotocol.h"
|
||||
|
||||
#include "ui/qautostart.h"
|
||||
|
||||
|
|
@ -112,6 +112,7 @@ UiLogic::~UiLogic()
|
|||
{
|
||||
emit hide();
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
if (m_vpnConnection->connectionState() != VpnProtocol::VpnConnectionState::Disconnected) {
|
||||
m_vpnConnection->disconnectFromVpn();
|
||||
for (int i = 0; i < 50; i++) {
|
||||
|
|
@ -122,6 +123,7 @@ UiLogic::~UiLogic()
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_vpnConnection->deleteLater();
|
||||
m_vpnConnectionThread.quit();
|
||||
|
|
@ -133,6 +135,11 @@ UiLogic::~UiLogic()
|
|||
void UiLogic::initalizeUiLogic()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
connect(AndroidController::instance(), &AndroidController::initialized, [this](bool status, bool connected, const QDateTime& connectionDate) {
|
||||
if (connected) {
|
||||
vpnLogic()->onConnectionStateChanged(VpnProtocol::Connected);
|
||||
}
|
||||
});
|
||||
if (!AndroidController::instance()->initialize()) {
|
||||
qDebug() << QString("Init failed") ;
|
||||
emit VpnProtocol::Error;
|
||||
|
|
@ -214,6 +221,9 @@ void UiLogic::onUpdateAllPages()
|
|||
void UiLogic::keyPressEvent(Qt::Key key)
|
||||
{
|
||||
switch (key) {
|
||||
case Qt::Key_AsciiTilde:
|
||||
case Qt::Key_QuoteLeft: emit toggleLogPanel();
|
||||
break;
|
||||
case Qt::Key_L: Debug::openLogsFolder();
|
||||
break;
|
||||
case Qt::Key_K: Debug::openServiceLogsFolder();
|
||||
|
|
@ -600,27 +610,60 @@ PageEnumNS::Page UiLogic::currentPage()
|
|||
return static_cast<PageEnumNS::Page>(currentPageValue());
|
||||
}
|
||||
|
||||
void UiLogic::saveTextFile(const QString& desc, const QString& ext, const QString& data)
|
||||
void UiLogic::saveTextFile(const QString& desc, const QString& suggestedName, QString ext, const QString& data)
|
||||
{
|
||||
QString fileName = QFileDialog::getSaveFileName(nullptr, desc,
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), ext);
|
||||
// ext.replace("*", "");
|
||||
// QString fileName = QFileDialog::getSaveFileName(nullptr, desc,
|
||||
// QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*" + ext);
|
||||
|
||||
// if (fileName.isEmpty()) return;
|
||||
// if (!fileName.endsWith(ext)) fileName.append(ext);
|
||||
|
||||
// QFile save(fileName);
|
||||
// save.open(QIODevice::WriteOnly);
|
||||
// save.write(data.toUtf8());
|
||||
// save.close();
|
||||
|
||||
// QFileInfo fi(fileName);
|
||||
// QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
||||
|
||||
|
||||
ext.replace("*", "");
|
||||
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||
QUrl fileName;
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
fileName = QFileDialog::getSaveFileUrl(nullptr, desc,
|
||||
QUrl::fromLocalFile(docDir + "/" + suggestedName), "*" + ext);
|
||||
if (fileName.isEmpty()) return;
|
||||
if (!fileName.endsWith(ext)) fileName.append(ext);
|
||||
if (!fileName.toString().endsWith(ext)) fileName = QUrl(fileName.toString() + ext);
|
||||
#elif defined Q_OS_ANDROID
|
||||
fileName = QFileDialog::getSaveFileUrl(nullptr, suggestedName,
|
||||
QUrl::fromLocalFile(docDir), "*" + ext);
|
||||
#endif
|
||||
|
||||
qDebug() << "UiLogic::saveTextFile" << fileName;
|
||||
if (fileName.isEmpty()) return;
|
||||
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
QFile save(fileName.toLocalFile());
|
||||
#else
|
||||
qDebug() << "UiLogic::saveTextFile" << QQmlFile::urlToLocalFileOrQrc(fileName);
|
||||
QFile save(QQmlFile::urlToLocalFileOrQrc(fileName));
|
||||
#endif
|
||||
|
||||
QFile save(fileName);
|
||||
save.open(QIODevice::WriteOnly);
|
||||
save.write(data.toUtf8());
|
||||
save.close();
|
||||
|
||||
QFileInfo fi(fileName);
|
||||
QFileInfo fi(fileName.toLocalFile());
|
||||
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
|
||||
}
|
||||
|
||||
void UiLogic::saveBinaryFile(const QString &desc, const QString &ext, const QString &data)
|
||||
void UiLogic::saveBinaryFile(const QString &desc, QString ext, const QString &data)
|
||||
{
|
||||
ext.replace("*", "");
|
||||
QString fileName = QFileDialog::getSaveFileName(nullptr, desc,
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), ext);
|
||||
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*" + ext);
|
||||
|
||||
if (fileName.isEmpty()) return;
|
||||
if (!fileName.endsWith(ext)) fileName.append(ext);
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ public:
|
|||
|
||||
Q_INVOKABLE void keyPressEvent(Qt::Key key);
|
||||
|
||||
Q_INVOKABLE void saveTextFile(const QString& desc, const QString& ext, const QString& data);
|
||||
Q_INVOKABLE void saveBinaryFile(const QString& desc, const QString& ext, const QString& data);
|
||||
Q_INVOKABLE void saveTextFile(const QString& desc, const QString &suggestedName, QString ext, const QString& data);
|
||||
Q_INVOKABLE void saveBinaryFile(const QString& desc, QString ext, const QString& data);
|
||||
Q_INVOKABLE void copyToClipboard(const QString& text);
|
||||
|
||||
QString getDialogConnectErrorText() const;
|
||||
|
|
@ -121,6 +121,7 @@ signals:
|
|||
void show();
|
||||
void hide();
|
||||
void raise();
|
||||
void toggleLogPanel();
|
||||
|
||||
private:
|
||||
QString m_dialogConnectErrorText;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue