added separation for read/write and readonly servers for pageSettingsServerProtocols, PageSettingsServerServices, PageSettingsServerData
- added fields validations for pageSetupWizardCredentials
This commit is contained in:
parent
249be451f7
commit
2ef53c6df9
22 changed files with 466 additions and 325 deletions
|
@ -1,29 +1,28 @@
|
||||||
#include "amnezia_application.h"
|
#include "amnezia_application.h"
|
||||||
|
|
||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
|
#include <QQuickStyle>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QTranslator>
|
#include <QTranslator>
|
||||||
#include <QQuickStyle>
|
|
||||||
|
|
||||||
#include "logger.h"
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
#include "platforms/ios/QRCodeReaderBase.h"
|
#include "platforms/ios/QRCodeReaderBase.h"
|
||||||
|
|
||||||
#include "ui/pages.h"
|
#include "ui/pages.h"
|
||||||
|
|
||||||
#if defined(Q_OS_IOS)
|
#if defined(Q_OS_IOS)
|
||||||
#include "platforms/ios/QtAppDelegate-C-Interface.h"
|
#include "platforms/ios/QtAppDelegate-C-Interface.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
|
||||||
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]):
|
AmneziaApplication::AmneziaApplication(int &argc, char *argv[]) : AMNEZIA_BASE_CLASS(argc, argv)
|
||||||
AMNEZIA_BASE_CLASS(argc, argv)
|
|
||||||
#else
|
#else
|
||||||
AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary,
|
AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecondary, SingleApplication::Options options,
|
||||||
SingleApplication::Options options, int timeout, const QString &userData):
|
int timeout, const QString &userData)
|
||||||
SingleApplication(argc, argv, allowSecondary, options, timeout, userData)
|
: SingleApplication(argc, argv, allowSecondary, options, timeout, userData)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
setQuitOnLastWindowClosed(false);
|
setQuitOnLastWindowClosed(false);
|
||||||
|
@ -51,12 +50,14 @@
|
||||||
AmneziaApplication::~AmneziaApplication()
|
AmneziaApplication::~AmneziaApplication()
|
||||||
{
|
{
|
||||||
if (m_engine) {
|
if (m_engine) {
|
||||||
QObject::disconnect(m_engine, 0,0,0);
|
QObject::disconnect(m_engine, 0, 0, 0);
|
||||||
delete m_engine;
|
delete m_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_protocolProps) delete m_protocolProps;
|
if (m_protocolProps)
|
||||||
if (m_containerProps) delete m_containerProps;
|
delete m_protocolProps;
|
||||||
|
if (m_containerProps)
|
||||||
|
delete m_containerProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmneziaApplication::init()
|
void AmneziaApplication::init()
|
||||||
|
@ -64,11 +65,13 @@ void AmneziaApplication::init()
|
||||||
m_engine = new QQmlApplicationEngine;
|
m_engine = new QQmlApplicationEngine;
|
||||||
|
|
||||||
const QUrl url(QStringLiteral("qrc:/ui/qml/main2.qml"));
|
const QUrl url(QStringLiteral("qrc:/ui/qml/main2.qml"));
|
||||||
QObject::connect(m_engine, &QQmlApplicationEngine::objectCreated,
|
QObject::connect(
|
||||||
this, [url](QObject *obj, const QUrl &objUrl) {
|
m_engine, &QQmlApplicationEngine::objectCreated, this,
|
||||||
if (!obj && url == objUrl)
|
[url](QObject *obj, const QUrl &objUrl) {
|
||||||
QCoreApplication::exit(-1);
|
if (!obj && url == objUrl)
|
||||||
}, Qt::QueuedConnection);
|
QCoreApplication::exit(-1);
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
|
|
||||||
m_engine->rootContext()->setContextProperty("Debug", &Logger::Instance());
|
m_engine->rootContext()->setContextProperty("Debug", &Logger::Instance());
|
||||||
|
|
||||||
|
@ -78,6 +81,8 @@ void AmneziaApplication::init()
|
||||||
|
|
||||||
m_serversModel.reset(new ServersModel(m_settings, this));
|
m_serversModel.reset(new ServersModel(m_settings, this));
|
||||||
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
|
||||||
|
connect(m_serversModel.get(), &ServersModel::currentlyProcessedServerIndexChanged, m_containersModel.get(),
|
||||||
|
&ContainersModel::setCurrentlyProcessedServerIndex);
|
||||||
|
|
||||||
m_configurator = std::shared_ptr<VpnConfigurator>(new VpnConfigurator(m_settings, this));
|
m_configurator = std::shared_ptr<VpnConfigurator>(new VpnConfigurator(m_settings, this));
|
||||||
m_vpnConnection.reset(new VpnConnection(m_settings, m_configurator));
|
m_vpnConnection.reset(new VpnConnection(m_settings, m_configurator));
|
||||||
|
@ -94,21 +99,19 @@ void AmneziaApplication::init()
|
||||||
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||||
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||||
|
|
||||||
m_exportController.reset(
|
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_settings, m_configurator));
|
||||||
new ExportController(m_serversModel, m_containersModel, m_settings, m_configurator));
|
|
||||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||||
|
|
||||||
m_settingsController.reset(
|
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_settings));
|
||||||
new SettingsController(m_serversModel, m_containersModel, m_settings));
|
|
||||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
m_engine->load(url);
|
m_engine->load(url);
|
||||||
|
|
||||||
// if (m_engine->rootObjects().size() > 0) {
|
// if (m_engine->rootObjects().size() > 0) {
|
||||||
// m_uiLogic->setQmlRoot(m_engine->rootObjects().at(0));
|
// m_uiLogic->setQmlRoot(m_engine->rootObjects().at(0));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (m_settings->isSaveLogs()) {
|
if (m_settings->isSaveLogs()) {
|
||||||
if (!Logger::init()) {
|
if (!Logger::init()) {
|
||||||
|
@ -116,24 +119,23 @@ void AmneziaApplication::init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#ifdef Q_OS_WIN
|
// #ifdef Q_OS_WIN
|
||||||
// if (m_parser.isSet("a")) m_uiLogic->showOnStartup();
|
// if (m_parser.isSet("a")) m_uiLogic->showOnStartup();
|
||||||
// else emit m_uiLogic->show();
|
// else emit m_uiLogic->show();
|
||||||
//#else
|
// #else
|
||||||
// m_uiLogic->showOnStartup();
|
// m_uiLogic->showOnStartup();
|
||||||
//#endif
|
// #endif
|
||||||
|
|
||||||
// // TODO - fix
|
|
||||||
//#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
|
||||||
// if (isPrimary()) {
|
|
||||||
// QObject::connect(this, &SingleApplication::instanceStarted, m_uiLogic, [this](){
|
|
||||||
// qDebug() << "Secondary instance started, showing this window instead";
|
|
||||||
// emit m_uiLogic->show();
|
|
||||||
// emit m_uiLogic->raise();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
|
// // TODO - fix
|
||||||
|
// #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||||
|
// if (isPrimary()) {
|
||||||
|
// QObject::connect(this, &SingleApplication::instanceStarted, m_uiLogic, [this](){
|
||||||
|
// qDebug() << "Secondary instance started, showing this window instead";
|
||||||
|
// emit m_uiLogic->show();
|
||||||
|
// emit m_uiLogic->raise();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmneziaApplication::registerTypes()
|
void AmneziaApplication::registerTypes()
|
||||||
|
@ -156,6 +158,9 @@ void AmneziaApplication::registerTypes()
|
||||||
m_protocolProps = new ProtocolProps;
|
m_protocolProps = new ProtocolProps;
|
||||||
qmlRegisterSingletonInstance("ProtocolProps", 1, 0, "ProtocolProps", m_protocolProps);
|
qmlRegisterSingletonInstance("ProtocolProps", 1, 0, "ProtocolProps", m_protocolProps);
|
||||||
|
|
||||||
|
qmlRegisterSingletonType(QUrl("qrc:/ui/qml/Filters/ContainersModelFilters.qml"), "ContainersModelFilters", 1, 0,
|
||||||
|
"ContainersModelFilters");
|
||||||
|
|
||||||
//
|
//
|
||||||
Vpn::declareQmlVpnConnectionStateEnum();
|
Vpn::declareQmlVpnConnectionStateEnum();
|
||||||
PageLoader::declareQmlPageEnum();
|
PageLoader::declareQmlPageEnum();
|
||||||
|
@ -182,19 +187,17 @@ bool AmneziaApplication::parseCommands()
|
||||||
m_parser.addHelpOption();
|
m_parser.addHelpOption();
|
||||||
m_parser.addVersionOption();
|
m_parser.addVersionOption();
|
||||||
|
|
||||||
QCommandLineOption c_autostart {{"a", "autostart"}, "System autostart"};
|
QCommandLineOption c_autostart { { "a", "autostart" }, "System autostart" };
|
||||||
m_parser.addOption(c_autostart);
|
m_parser.addOption(c_autostart);
|
||||||
|
|
||||||
QCommandLineOption c_cleanup {{"c", "cleanup"}, "Cleanup logs"};
|
QCommandLineOption c_cleanup { { "c", "cleanup" }, "Cleanup logs" };
|
||||||
m_parser.addOption(c_cleanup);
|
m_parser.addOption(c_cleanup);
|
||||||
|
|
||||||
m_parser.process(*this);
|
m_parser.process(*this);
|
||||||
|
|
||||||
if (m_parser.isSet(c_cleanup)) {
|
if (m_parser.isSet(c_cleanup)) {
|
||||||
Logger::cleanUp();
|
Logger::cleanUp();
|
||||||
QTimer::singleShot(100, this, [this]{
|
QTimer::singleShot(100, this, [this] { quit(); });
|
||||||
quit();
|
|
||||||
});
|
|
||||||
exec();
|
exec();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -205,4 +208,3 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
|
||||||
{
|
{
|
||||||
return m_engine;
|
return m_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,5 +269,6 @@
|
||||||
<file>images/controls/mail.svg</file>
|
<file>images/controls/mail.svg</file>
|
||||||
<file>images/controls/telegram.svg</file>
|
<file>images/controls/telegram.svg</file>
|
||||||
<file>ui/qml/Controls2/TextTypes/SmallTextType.qml</file>
|
<file>ui/qml/Controls2/TextTypes/SmallTextType.qml</file>
|
||||||
|
<file>ui/qml/Filters/ContainersModelFilters.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel,
|
ExportController::ExportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const std::shared_ptr<Settings> &settings,
|
const std::shared_ptr<Settings> &settings,
|
||||||
const std::shared_ptr<VpnConfigurator> &configurator,
|
const std::shared_ptr<VpnConfigurator> &configurator, QObject *parent)
|
||||||
QObject *parent)
|
: QObject(parent),
|
||||||
: QObject(parent)
|
m_serversModel(serversModel),
|
||||||
, m_serversModel(serversModel)
|
m_containersModel(containersModel),
|
||||||
, m_containersModel(containersModel)
|
m_settings(settings),
|
||||||
, m_settings(settings)
|
m_configurator(configurator)
|
||||||
, m_configurator(configurator)
|
{
|
||||||
{}
|
}
|
||||||
|
|
||||||
void ExportController::generateFullAccessConfig()
|
void ExportController::generateFullAccessConfig()
|
||||||
{
|
{
|
||||||
|
@ -33,8 +33,8 @@ void ExportController::generateFullAccessConfig()
|
||||||
QByteArray compressedConfig = QJsonDocument(config).toJson();
|
QByteArray compressedConfig = QJsonDocument(config).toJson();
|
||||||
compressedConfig = qCompress(compressedConfig, 8);
|
compressedConfig = qCompress(compressedConfig, 8);
|
||||||
m_amneziaCode = QString("vpn://%1")
|
m_amneziaCode = QString("vpn://%1")
|
||||||
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
|
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
|
||||||
| QByteArray::OmitTrailingEquals)));
|
| QByteArray::OmitTrailingEquals)));
|
||||||
|
|
||||||
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
|
@ -43,25 +43,21 @@ void ExportController::generateFullAccessConfig()
|
||||||
void ExportController::generateConnectionConfig()
|
void ExportController::generateConnectionConfig()
|
||||||
{
|
{
|
||||||
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||||
ServerCredentials credentials = qvariant_cast<ServerCredentials>(
|
ServerCredentials credentials =
|
||||||
m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||||
|
|
||||||
DockerContainer container = static_cast<DockerContainer>(
|
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
|
||||||
m_containersModel->getCurrentlyProcessedContainerIndex());
|
|
||||||
QModelIndex containerModelIndex = m_containersModel->index(container);
|
QModelIndex containerModelIndex = m_containersModel->index(container);
|
||||||
QJsonObject containerConfig = qvariant_cast<QJsonObject>(
|
QJsonObject containerConfig =
|
||||||
m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
|
qvariant_cast<QJsonObject>(m_containersModel->data(containerModelIndex, ContainersModel::Roles::ConfigRole));
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
|
||||||
|
|
||||||
ErrorCode errorCode = ErrorCode::NoError;
|
ErrorCode errorCode = ErrorCode::NoError;
|
||||||
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
for (Proto protocol : ContainerProps::protocolsForContainer(container)) {
|
||||||
QJsonObject protocolConfig = m_settings->protocolConfig(serverIndex, container, protocol);
|
QJsonObject protocolConfig = m_settings->protocolConfig(serverIndex, container, protocol);
|
||||||
|
|
||||||
QString vpnConfig = m_configurator->genVpnProtocolConfig(credentials,
|
QString vpnConfig =
|
||||||
container,
|
m_configurator->genVpnProtocolConfig(credentials, container, containerConfig, protocol, &errorCode);
|
||||||
containerConfig,
|
|
||||||
protocol,
|
|
||||||
&errorCode);
|
|
||||||
if (errorCode) {
|
if (errorCode) {
|
||||||
emit exportErrorOccurred(errorString(errorCode));
|
emit exportErrorOccurred(errorString(errorCode));
|
||||||
return;
|
return;
|
||||||
|
@ -75,7 +71,7 @@ void ExportController::generateConnectionConfig()
|
||||||
config.remove(config_key::userName);
|
config.remove(config_key::userName);
|
||||||
config.remove(config_key::password);
|
config.remove(config_key::password);
|
||||||
config.remove(config_key::port);
|
config.remove(config_key::port);
|
||||||
config.insert(config_key::containers, QJsonArray{containerConfig});
|
config.insert(config_key::containers, QJsonArray { containerConfig });
|
||||||
config.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
config.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||||
|
|
||||||
auto dns = m_configurator->getDnsForConfig(serverIndex);
|
auto dns = m_configurator->getDnsForConfig(serverIndex);
|
||||||
|
@ -86,8 +82,8 @@ void ExportController::generateConnectionConfig()
|
||||||
QByteArray compressedConfig = QJsonDocument(config).toJson();
|
QByteArray compressedConfig = QJsonDocument(config).toJson();
|
||||||
compressedConfig = qCompress(compressedConfig, 8);
|
compressedConfig = qCompress(compressedConfig, 8);
|
||||||
m_amneziaCode = QString("vpn://%1")
|
m_amneziaCode = QString("vpn://%1")
|
||||||
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
|
.arg(QString(compressedConfig.toBase64(QByteArray::Base64UrlEncoding
|
||||||
| QByteArray::OmitTrailingEquals)));
|
| QByteArray::OmitTrailingEquals)));
|
||||||
|
|
||||||
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
m_qrCodes = generateQrCodeImageSeries(compressedConfig);
|
||||||
emit exportConfigChanged();
|
emit exportConfigChanged();
|
||||||
|
@ -108,10 +104,8 @@ void ExportController::saveFile()
|
||||||
QString fileExtension = ".vpn";
|
QString fileExtension = ".vpn";
|
||||||
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
|
||||||
QUrl fileName;
|
QUrl fileName;
|
||||||
fileName = QFileDialog::getSaveFileUrl(nullptr,
|
fileName = QFileDialog::getSaveFileUrl(nullptr, tr("Save AmneziaVPN config"),
|
||||||
tr("Save AmneziaVPN config"),
|
QUrl::fromLocalFile(docDir + "/" + "amnezia_config"), "*" + fileExtension);
|
||||||
QUrl::fromLocalFile(docDir + "/" + "amnezia_config"),
|
|
||||||
"*" + fileExtension);
|
|
||||||
if (fileName.isEmpty())
|
if (fileName.isEmpty())
|
||||||
return;
|
return;
|
||||||
if (!fileName.toString().endsWith(fileExtension)) {
|
if (!fileName.toString().endsWith(fileExtension)) {
|
||||||
|
@ -139,10 +133,9 @@ QList<QString> ExportController::generateQrCodeImageSeries(const QByteArray &dat
|
||||||
for (int i = 0; i < data.size(); i = i + k) {
|
for (int i = 0; i < data.size(); i = i + k) {
|
||||||
QByteArray chunk;
|
QByteArray chunk;
|
||||||
QDataStream s(&chunk, QIODevice::WriteOnly);
|
QDataStream s(&chunk, QIODevice::WriteOnly);
|
||||||
s << amnezia::qrMagicCode << chunksCount << (quint8) std::round(i / k) << data.mid(i, k);
|
s << amnezia::qrMagicCode << chunksCount << (quint8)std::round(i / k) << data.mid(i, k);
|
||||||
|
|
||||||
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding
|
QByteArray ba = chunk.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||||
| QByteArray::OmitTrailingEquals);
|
|
||||||
|
|
||||||
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(ba, qrcodegen::QrCode::Ecc::LOW);
|
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(ba, qrcodegen::QrCode::Ecc::LOW);
|
||||||
QString svg = QString::fromStdString(toSvgString(qr, 0));
|
QString svg = QString::fromStdString(toSvgString(qr, 0));
|
||||||
|
|
|
@ -5,40 +5,42 @@
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
enum class ConfigTypes { Amnezia, OpenVpn, WireGuard };
|
|
||||||
|
|
||||||
ConfigTypes checkConfigFormat(const QString &config)
|
|
||||||
{
|
{
|
||||||
const QString openVpnConfigPatternCli = "client";
|
enum class ConfigTypes {
|
||||||
const QString openVpnConfigPatternProto1 = "proto tcp";
|
Amnezia,
|
||||||
const QString openVpnConfigPatternProto2 = "proto udp";
|
OpenVpn,
|
||||||
const QString openVpnConfigPatternDriver1 = "dev tun";
|
WireGuard
|
||||||
const QString openVpnConfigPatternDriver2 = "dev tap";
|
};
|
||||||
|
|
||||||
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
ConfigTypes checkConfigFormat(const QString &config)
|
||||||
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
{
|
||||||
|
const QString openVpnConfigPatternCli = "client";
|
||||||
|
const QString openVpnConfigPatternProto1 = "proto tcp";
|
||||||
|
const QString openVpnConfigPatternProto2 = "proto udp";
|
||||||
|
const QString openVpnConfigPatternDriver1 = "dev tun";
|
||||||
|
const QString openVpnConfigPatternDriver2 = "dev tap";
|
||||||
|
|
||||||
if (config.contains(openVpnConfigPatternCli)
|
const QString wireguardConfigPatternSectionInterface = "[Interface]";
|
||||||
&& (config.contains(openVpnConfigPatternProto1)
|
const QString wireguardConfigPatternSectionPeer = "[Peer]";
|
||||||
|| config.contains(openVpnConfigPatternProto2))
|
|
||||||
&& (config.contains(openVpnConfigPatternDriver1)
|
if (config.contains(openVpnConfigPatternCli)
|
||||||
|| config.contains(openVpnConfigPatternDriver2))) {
|
&& (config.contains(openVpnConfigPatternProto1) || config.contains(openVpnConfigPatternProto2))
|
||||||
return ConfigTypes::OpenVpn;
|
&& (config.contains(openVpnConfigPatternDriver1) || config.contains(openVpnConfigPatternDriver2))) {
|
||||||
} else if (config.contains(wireguardConfigPatternSectionInterface)
|
return ConfigTypes::OpenVpn;
|
||||||
&& config.contains(wireguardConfigPatternSectionPeer)) {
|
} else if (config.contains(wireguardConfigPatternSectionInterface)
|
||||||
return ConfigTypes::WireGuard;
|
&& config.contains(wireguardConfigPatternSectionPeer)) {
|
||||||
|
return ConfigTypes::WireGuard;
|
||||||
|
}
|
||||||
|
return ConfigTypes::Amnezia;
|
||||||
}
|
}
|
||||||
return ConfigTypes::Amnezia;
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel,
|
ImportController::ImportController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const std::shared_ptr<Settings> &settings,
|
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||||
QObject *parent) : QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportController::extractConfigFromFile(const QUrl &fileUrl)
|
void ImportController::extractConfigFromFile(const QUrl &fileUrl)
|
||||||
|
@ -88,8 +90,7 @@ void ImportController::importConfig()
|
||||||
m_serversModel->addServer(m_config);
|
m_serversModel->addServer(m_config);
|
||||||
|
|
||||||
if (!m_config.value(config_key::containers).toArray().isEmpty()) {
|
if (!m_config.value(config_key::containers).toArray().isEmpty()) {
|
||||||
auto newServerIndex = m_serversModel->index(m_serversModel->getServersCount() - 1);
|
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
|
||||||
m_serversModel->setData(newServerIndex, true, ServersModel::Roles::IsDefaultRole);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit importFinished();
|
emit importFinished();
|
||||||
|
@ -116,12 +117,12 @@ QJsonObject ImportController::extractAmneziaConfig(QString &data)
|
||||||
return QJsonDocument::fromJson(ba).object();
|
return QJsonDocument::fromJson(ba).object();
|
||||||
}
|
}
|
||||||
|
|
||||||
//bool ImportController::importConnectionFromQr(const QByteArray &data)
|
// bool ImportController::importConnectionFromQr(const QByteArray &data)
|
||||||
//{
|
//{
|
||||||
// QJsonObject dataObj = QJsonDocument::fromJson(data).object();
|
// QJsonObject dataObj = QJsonDocument::fromJson(data).object();
|
||||||
// if (!dataObj.isEmpty()) {
|
// if (!dataObj.isEmpty()) {
|
||||||
// return importConnection(dataObj);
|
// return importConnection(dataObj);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// QByteArray ba_uncompressed = qUncompress(data);
|
// QByteArray ba_uncompressed = qUncompress(data);
|
||||||
// if (!ba_uncompressed.isEmpty()) {
|
// if (!ba_uncompressed.isEmpty()) {
|
||||||
|
@ -159,7 +160,6 @@ QJsonObject ImportController::extractOpenVpnConfig(const QString &data)
|
||||||
config[config_key::defaultContainer] = "amnezia-openvpn";
|
config[config_key::defaultContainer] = "amnezia-openvpn";
|
||||||
config[config_key::description] = m_settings->nextAvailableServerName();
|
config[config_key::description] = m_settings->nextAvailableServerName();
|
||||||
|
|
||||||
|
|
||||||
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
const static QRegularExpression dnsRegExp("dhcp-option DNS (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
||||||
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(data);
|
QRegularExpressionMatchIterator dnsMatch = dnsRegExp.globalMatch(data);
|
||||||
if (dnsMatch.hasNext()) {
|
if (dnsMatch.hasNext()) {
|
||||||
|
@ -206,7 +206,9 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
|
||||||
config[config_key::defaultContainer] = "amnezia-wireguard";
|
config[config_key::defaultContainer] = "amnezia-wireguard";
|
||||||
config[config_key::description] = m_settings->nextAvailableServerName();
|
config[config_key::description] = m_settings->nextAvailableServerName();
|
||||||
|
|
||||||
const static QRegularExpression dnsRegExp("DNS = (\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b).*(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
const static QRegularExpression dnsRegExp(
|
||||||
|
"DNS = "
|
||||||
|
"(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b).*(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)");
|
||||||
QRegularExpressionMatch dnsMatch = dnsRegExp.match(data);
|
QRegularExpressionMatch dnsMatch = dnsRegExp.match(data);
|
||||||
if (dnsMatch.hasMatch()) {
|
if (dnsMatch.hasMatch()) {
|
||||||
config[config_key::dns1] = dnsMatch.captured(1);
|
config[config_key::dns1] = dnsMatch.captured(1);
|
||||||
|
|
|
@ -67,8 +67,7 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
|
||||||
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
|
||||||
|
|
||||||
m_serversModel->addServer(server);
|
m_serversModel->addServer(server);
|
||||||
auto newServerIndex = m_serversModel->index(m_serversModel->getServersCount() - 1);
|
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
|
||||||
m_serversModel->setData(newServerIndex, true, ServersModel::Roles::IsDefaultRole);
|
|
||||||
|
|
||||||
emit installServerFinished(isInstalledContainerFound);
|
emit installServerFinished(isInstalledContainerFound);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -78,7 +78,7 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContainersModel::setCurrentlyProcessedServerIndex(int index)
|
void ContainersModel::setCurrentlyProcessedServerIndex(const int index)
|
||||||
{
|
{
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_currentlyProcessedServerIndex = index;
|
m_currentlyProcessedServerIndex = index;
|
||||||
|
|
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <vector>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "settings.h"
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
class ContainersModel : public QAbstractListModel
|
class ContainersModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,7 @@ public slots:
|
||||||
DockerContainer getDefaultContainer();
|
DockerContainer getDefaultContainer();
|
||||||
QString getDefaultContainerName();
|
QString getDefaultContainerName();
|
||||||
|
|
||||||
void setCurrentlyProcessedServerIndex(int index);
|
void setCurrentlyProcessedServerIndex(const int index);
|
||||||
void setCurrentlyProcessedContainerIndex(int index);
|
void setCurrentlyProcessedContainerIndex(int index);
|
||||||
int getCurrentlyProcessedContainerIndex();
|
int getCurrentlyProcessedContainerIndex();
|
||||||
|
|
||||||
|
@ -57,7 +57,6 @@ protected:
|
||||||
private:
|
private:
|
||||||
QMap<DockerContainer, QJsonObject> m_containers;
|
QMap<DockerContainer, QJsonObject> m_containers;
|
||||||
|
|
||||||
|
|
||||||
int m_currentlyProcessedServerIndex;
|
int m_currentlyProcessedServerIndex;
|
||||||
int m_currentlyProcessedContainerIndex;
|
int m_currentlyProcessedContainerIndex;
|
||||||
DockerContainer m_defaultContainerIndex;
|
DockerContainer m_defaultContainerIndex;
|
||||||
|
|
|
@ -5,6 +5,7 @@ ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
|
||||||
{
|
{
|
||||||
m_servers = m_settings->serversArray();
|
m_servers = m_settings->serversArray();
|
||||||
m_defaultServerIndex = m_settings->defaultServerIndex();
|
m_defaultServerIndex = m_settings->defaultServerIndex();
|
||||||
|
m_currenlyProcessedServerIndex = m_defaultServerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ServersModel::rowCount(const QModelIndex &parent) const
|
int ServersModel::rowCount(const QModelIndex &parent) const
|
||||||
|
@ -28,10 +29,6 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int
|
||||||
m_servers.replace(index.row(), server);
|
m_servers.replace(index.row(), server);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IsDefaultRole: {
|
|
||||||
setDefaultServerIndex(index.row());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
default: {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -62,6 +59,10 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||||
case CredentialsLoginRole: return m_settings->serverCredentials(index.row()).userName;
|
case CredentialsLoginRole: return m_settings->serverCredentials(index.row()).userName;
|
||||||
case IsDefaultRole: return index.row() == m_defaultServerIndex;
|
case IsDefaultRole: return index.row() == m_defaultServerIndex;
|
||||||
case IsCurrentlyProcessedRole: return index.row() == m_currenlyProcessedServerIndex;
|
case IsCurrentlyProcessedRole: return index.row() == m_currenlyProcessedServerIndex;
|
||||||
|
case HasWriteAccess: {
|
||||||
|
auto credentials = m_settings->serverCredentials(index.row());
|
||||||
|
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -73,6 +74,13 @@ QVariant ServersModel::data(const int index, int role) const
|
||||||
return data(modelIndex, role);
|
return data(modelIndex, role);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServersModel::setDefaultServerIndex(const int index)
|
||||||
|
{
|
||||||
|
m_settings->setDefaultServer(index);
|
||||||
|
m_defaultServerIndex = m_settings->defaultServerIndex();
|
||||||
|
emit defaultServerIndexChanged();
|
||||||
|
}
|
||||||
|
|
||||||
const int ServersModel::getDefaultServerIndex()
|
const int ServersModel::getDefaultServerIndex()
|
||||||
{
|
{
|
||||||
return m_defaultServerIndex;
|
return m_defaultServerIndex;
|
||||||
|
@ -83,10 +91,10 @@ const int ServersModel::getServersCount()
|
||||||
return m_servers.count();
|
return m_servers.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServersModel::setCurrentlyProcessedServerIndex(int index)
|
void ServersModel::setCurrentlyProcessedServerIndex(const int index)
|
||||||
{
|
{
|
||||||
m_currenlyProcessedServerIndex = index;
|
m_currenlyProcessedServerIndex = index;
|
||||||
emit currentlyProcessedServerIndexChanged();
|
emit currentlyProcessedServerIndexChanged(m_currenlyProcessedServerIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ServersModel::getCurrentlyProcessedServerIndex()
|
int ServersModel::getCurrentlyProcessedServerIndex()
|
||||||
|
@ -101,8 +109,7 @@ bool ServersModel::isDefaultServerCurrentlyProcessed()
|
||||||
|
|
||||||
bool ServersModel::isCurrentlyProcessedServerHasWriteAccess()
|
bool ServersModel::isCurrentlyProcessedServerHasWriteAccess()
|
||||||
{
|
{
|
||||||
auto credentials = m_settings->serverCredentials(m_currenlyProcessedServerIndex);
|
return qvariant_cast<bool>(data(m_currenlyProcessedServerIndex, HasWriteAccess));
|
||||||
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServersModel::addServer(const QJsonObject &server)
|
void ServersModel::addServer(const QJsonObject &server)
|
||||||
|
@ -140,11 +147,6 @@ QHash<int, QByteArray> ServersModel::roleNames() const
|
||||||
roles[CredentialsLoginRole] = "credentialsLogin";
|
roles[CredentialsLoginRole] = "credentialsLogin";
|
||||||
roles[IsDefaultRole] = "isDefault";
|
roles[IsDefaultRole] = "isDefault";
|
||||||
roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed";
|
roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed";
|
||||||
|
roles[HasWriteAccess] = "hasWriteAccess";
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServersModel::setDefaultServerIndex(const int index)
|
|
||||||
{
|
|
||||||
m_settings->setDefaultServer(index);
|
|
||||||
m_defaultServerIndex = m_settings->defaultServerIndex();
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,13 +5,6 @@
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
struct ServerModelContent
|
|
||||||
{
|
|
||||||
QString desc;
|
|
||||||
QString address;
|
|
||||||
bool isDefault;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ServersModel : public QAbstractListModel
|
class ServersModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -22,7 +15,8 @@ public:
|
||||||
CredentialsRole,
|
CredentialsRole,
|
||||||
CredentialsLoginRole,
|
CredentialsLoginRole,
|
||||||
IsDefaultRole,
|
IsDefaultRole,
|
||||||
IsCurrentlyProcessedRole
|
IsCurrentlyProcessedRole,
|
||||||
|
HasWriteAccess
|
||||||
};
|
};
|
||||||
|
|
||||||
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
|
||||||
|
@ -33,14 +27,20 @@ public:
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
QVariant data(const int index, int role = Qt::DisplayRole) const;
|
QVariant data(const int index, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged)
|
||||||
|
Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex
|
||||||
|
NOTIFY currentlyProcessedServerIndexChanged)
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
void setDefaultServerIndex(const int index);
|
||||||
const int getDefaultServerIndex();
|
const int getDefaultServerIndex();
|
||||||
bool isDefaultServerCurrentlyProcessed();
|
bool isDefaultServerCurrentlyProcessed();
|
||||||
|
|
||||||
bool isCurrentlyProcessedServerHasWriteAccess();
|
bool isCurrentlyProcessedServerHasWriteAccess();
|
||||||
|
|
||||||
const int getServersCount();
|
const int getServersCount();
|
||||||
|
|
||||||
void setCurrentlyProcessedServerIndex(int index);
|
void setCurrentlyProcessedServerIndex(const int index);
|
||||||
int getCurrentlyProcessedServerIndex();
|
int getCurrentlyProcessedServerIndex();
|
||||||
|
|
||||||
void addServer(const QJsonObject &server);
|
void addServer(const QJsonObject &server);
|
||||||
|
@ -50,11 +50,10 @@ protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void currentlyProcessedServerIndexChanged();
|
void currentlyProcessedServerIndexChanged(const int index);
|
||||||
|
void defaultServerIndexChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setDefaultServerIndex(const int index);
|
|
||||||
|
|
||||||
QJsonArray m_servers;
|
QJsonArray m_servers;
|
||||||
|
|
||||||
std::shared_ptr<Settings> m_settings;
|
std::shared_ptr<Settings> m_settings;
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
#include "ServerListLogic.h"
|
#include "ServerListLogic.h"
|
||||||
|
|
||||||
#include "vpnconnection.h"
|
|
||||||
#include "../models/servers_model.h"
|
#include "../models/servers_model.h"
|
||||||
#include "../uilogic.h"
|
#include "../uilogic.h"
|
||||||
|
#include "vpnconnection.h"
|
||||||
|
|
||||||
ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent):
|
ServerListLogic::ServerListLogic(UiLogic *logic, QObject *parent)
|
||||||
PageLogicBase(logic, parent),
|
: PageLogicBase(logic, parent), m_serverListModel { new ServersModel(m_settings, this) }
|
||||||
m_serverListModel{new ServersModel(m_settings, this)}
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
|
void ServerListLogic::onServerListPushbuttonDefaultClicked(int index)
|
||||||
|
@ -31,19 +29,19 @@ int ServerListLogic::currServerIdx() const
|
||||||
|
|
||||||
void ServerListLogic::onUpdatePage()
|
void ServerListLogic::onUpdatePage()
|
||||||
{
|
{
|
||||||
const QJsonArray &servers = m_settings->serversArray();
|
// const QJsonArray &servers = m_settings->serversArray();
|
||||||
int defaultServer = m_settings->defaultServerIndex();
|
// int defaultServer = m_settings->defaultServerIndex();
|
||||||
QVector<ServerModelContent> serverListContent;
|
// QVector<ServerModelContent> serverListContent;
|
||||||
for(int i = 0; i < servers.size(); i++) {
|
// for(int i = 0; i < servers.size(); i++) {
|
||||||
ServerModelContent c;
|
// ServerModelContent c;
|
||||||
auto server = servers.at(i).toObject();
|
// auto server = servers.at(i).toObject();
|
||||||
c.desc = server.value(config_key::description).toString();
|
// c.desc = server.value(config_key::description).toString();
|
||||||
c.address = server.value(config_key::hostName).toString();
|
// c.address = server.value(config_key::hostName).toString();
|
||||||
if (c.desc.isEmpty()) {
|
// if (c.desc.isEmpty()) {
|
||||||
c.desc = c.address;
|
// c.desc = c.address;
|
||||||
}
|
// }
|
||||||
c.isDefault = (i == defaultServer);
|
// c.isDefault = (i == defaultServer);
|
||||||
serverListContent.push_back(c);
|
// serverListContent.push_back(c);
|
||||||
}
|
// }
|
||||||
// qobject_cast<ServersModel*>(m_serverListModel)->setContent(serverListContent);
|
// qobject_cast<ServersModel*>(m_serverListModel)->setContent(serverListContent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,96 +8,115 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string headerText
|
property string headerText
|
||||||
property string textFieldPlaceholderText
|
property alias errorText: errorField.text
|
||||||
property bool textFieldEditable: true
|
|
||||||
|
|
||||||
property string buttonText
|
property string buttonText
|
||||||
property var clickedFunc
|
property var clickedFunc
|
||||||
|
|
||||||
property alias textField: textField
|
property alias textField: textField
|
||||||
property alias textFieldText: textField.text
|
property alias textFieldText: textField.text
|
||||||
|
property string textFieldPlaceholderText
|
||||||
|
property bool textFieldEditable: true
|
||||||
|
|
||||||
implicitHeight: 74
|
implicitWidth: content.implicitWidth
|
||||||
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
Rectangle {
|
ColumnLayout {
|
||||||
id: backgroud
|
id: content
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "#1c1d21"
|
|
||||||
radius: 16
|
|
||||||
border.color: textField.focus ? "#d7d8db" : "#2C2D30"
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Behavior on border.color {
|
Rectangle {
|
||||||
PropertyAnimation { duration: 200 }
|
id: backgroud
|
||||||
}
|
Layout.fillWidth: true
|
||||||
}
|
Layout.preferredHeight: 74
|
||||||
|
color: "#1c1d21"
|
||||||
|
radius: 16
|
||||||
|
border.color: textField.focus ? "#d7d8db" : "#2C2D30"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
RowLayout {
|
Behavior on border.color {
|
||||||
anchors.fill: backgroud
|
PropertyAnimation { duration: 200 }
|
||||||
ColumnLayout {
|
|
||||||
|
|
||||||
LabelTextType {
|
|
||||||
text: root.headerText
|
|
||||||
color: "#878b91"
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.topMargin: 16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextField {
|
RowLayout {
|
||||||
id: textField
|
anchors.fill: backgroud
|
||||||
|
ColumnLayout {
|
||||||
|
LabelTextType {
|
||||||
|
text: root.headerText
|
||||||
|
color: "#878b91"
|
||||||
|
|
||||||
enabled: root.textFieldEditable
|
Layout.fillWidth: true
|
||||||
color: "#d7d8db"
|
Layout.rightMargin: 16
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.topMargin: 16
|
||||||
|
}
|
||||||
|
|
||||||
placeholderText: textFieldPlaceholderText
|
TextField {
|
||||||
placeholderTextColor: "#494B50"
|
id: textField
|
||||||
|
|
||||||
selectionColor: "#412102"
|
enabled: root.textFieldEditable
|
||||||
selectedTextColor: "#D7D8DB"
|
color: "#d7d8db"
|
||||||
|
|
||||||
font.pixelSize: 16
|
placeholderText: textFieldPlaceholderText
|
||||||
font.weight: 400
|
placeholderTextColor: "#494B50"
|
||||||
font.family: "PT Root UI VF"
|
|
||||||
|
|
||||||
height: 24
|
selectionColor: "#412102"
|
||||||
Layout.fillWidth: true
|
selectedTextColor: "#D7D8DB"
|
||||||
Layout.rightMargin: 16
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
Layout.bottomMargin: 16
|
|
||||||
topPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
leftPadding: 0
|
|
||||||
bottomPadding: 0
|
|
||||||
|
|
||||||
background: Rectangle {
|
font.pixelSize: 16
|
||||||
anchors.fill: parent
|
font.weight: 400
|
||||||
color: "#1c1d21"
|
font.family: "PT Root UI VF"
|
||||||
|
|
||||||
|
height: 24
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
topPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
leftPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "#1c1d21"
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
root.errorText = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
visible: root.buttonText !== ""
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
disabledColor: "#878B91"
|
||||||
|
textColor: "#D7D8DB"
|
||||||
|
borderWidth: 0
|
||||||
|
|
||||||
|
text: buttonText
|
||||||
|
|
||||||
|
Layout.rightMargin: 24
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (clickedFunc && typeof clickedFunc === "function") {
|
||||||
|
clickedFunc()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
SmallTextType {
|
||||||
visible: root.buttonText !== ""
|
id: errorField
|
||||||
|
|
||||||
defaultColor: "transparent"
|
text: root.errorText
|
||||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
visible: root.errorText !== ""
|
||||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
color: "#EB5757"
|
||||||
disabledColor: "#878B91"
|
|
||||||
textColor: "#D7D8DB"
|
|
||||||
borderWidth: 0
|
|
||||||
|
|
||||||
text: buttonText
|
|
||||||
|
|
||||||
Layout.rightMargin: 24
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (clickedFunc && typeof clickedFunc === "function") {
|
|
||||||
clickedFunc()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
47
client/ui/qml/Filters/ContainersModelFilters.qml
Normal file
47
client/ui/qml/Filters/ContainersModelFilters.qml
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
pragma Singleton
|
||||||
|
|
||||||
|
import QtQuick 2.15
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import ProtocolEnum 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
ValueFilter {
|
||||||
|
id: vpnTypeFilter
|
||||||
|
roleName: "serviceType"
|
||||||
|
value: ProtocolEnum.Vpn
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueFilter {
|
||||||
|
id: serviceTypeFilter
|
||||||
|
roleName: "serviceType"
|
||||||
|
value: ProtocolEnum.Other
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueFilter {
|
||||||
|
id: supportedFilter
|
||||||
|
roleName: "isSupported"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
|
||||||
|
ValueFilter {
|
||||||
|
id: installedFilter
|
||||||
|
roleName: "isInstalled"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWriteAccessProtocolsListFilters() {
|
||||||
|
return [vpnTypeFilter, supportedFilter]
|
||||||
|
}
|
||||||
|
function getReadAccessProtocolsListFilters() {
|
||||||
|
return [vpnTypeFilter, supportedFilter, installedFilter]
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWriteAccessServicesListFilters() {
|
||||||
|
return [serviceTypeFilter, supportedFilter]
|
||||||
|
}
|
||||||
|
function getReadAccessServicesListFilters() {
|
||||||
|
return [serviceTypeFilter, supportedFilter, installedFilter]
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import SortFilterProxyModel 0.2
|
||||||
import PageEnum 1.0
|
import PageEnum 1.0
|
||||||
import ProtocolEnum 1.0
|
import ProtocolEnum 1.0
|
||||||
import ContainerProps 1.0
|
import ContainerProps 1.0
|
||||||
|
import ContainersModelFilters 1.0
|
||||||
|
|
||||||
import "./"
|
import "./"
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
|
@ -161,10 +162,7 @@ PageType {
|
||||||
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
|
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
|
||||||
|
|
||||||
rootButtonClickedFunction: function() {
|
rootButtonClickedFunction: function() {
|
||||||
// todo check if server index changed before set Currently processed
|
ServersModel.currentlyProcessedIndex = serversMenuContent.currentIndex
|
||||||
// todo make signal slot for change server index in containersModel
|
|
||||||
ServersModel.setCurrentlyProcessedServerIndex(serversMenuContent.currentIndex)
|
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(serversMenuContent.currentIndex)
|
|
||||||
containersDropDown.menuVisible = true
|
containersDropDown.menuVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,39 +175,22 @@ PageType {
|
||||||
function onCurrentlyProcessedServerIndexChanged() {
|
function onCurrentlyProcessedServerIndexChanged() {
|
||||||
updateContainersModelFilters()
|
updateContainersModelFilters()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function updateContainersModelFilters() {
|
function updateContainersModelFilters() {
|
||||||
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
|
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
|
||||||
proxyContainersModel.filters = [serviceTypeFilter, supportedFilter]
|
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
|
||||||
} else {
|
} else {
|
||||||
proxyContainersModel.filters = installedFilter
|
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueFilter {
|
|
||||||
id: serviceTypeFilter
|
|
||||||
roleName: "serviceType"
|
|
||||||
value: ProtocolEnum.Vpn
|
|
||||||
}
|
|
||||||
ValueFilter {
|
|
||||||
id: supportedFilter
|
|
||||||
roleName: "isSupported"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
ValueFilter {
|
|
||||||
id: installedFilter
|
|
||||||
roleName: "isInstalled"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
|
|
||||||
model: SortFilterProxyModel {
|
model: SortFilterProxyModel {
|
||||||
id: proxyContainersModel
|
id: proxyContainersModel
|
||||||
sourceModel: ContainersModel
|
sourceModel: ContainersModel
|
||||||
|
|
||||||
Component.onCompleted: updateContainersModelFilters()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: updateContainersModelFilters()
|
||||||
currentIndex: ContainersModel.getDefaultContainer()
|
currentIndex: ContainersModel.getDefaultContainer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,7 +248,7 @@ PageType {
|
||||||
height: serversMenuContent.contentItem.height
|
height: serversMenuContent.contentItem.height
|
||||||
|
|
||||||
model: ServersModel
|
model: ServersModel
|
||||||
currentIndex: ServersModel.getDefaultServerIndex()
|
currentIndex: ServersModel.defaultIndex
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
@ -305,8 +286,8 @@ PageType {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
serversMenuContent.currentIndex = index
|
serversMenuContent.currentIndex = index
|
||||||
|
|
||||||
isDefault = true
|
ServersModel.currentlyProcessedIndex = index
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(index)
|
ServersModel.defaultIndex = index
|
||||||
|
|
||||||
root.currentServerName = name
|
root.currentServerName = name
|
||||||
root.currentServerHostName = hostName
|
root.currentServerHostName = hostName
|
||||||
|
@ -328,8 +309,7 @@ PageType {
|
||||||
z: 1
|
z: 1
|
||||||
|
|
||||||
onClicked: function() {
|
onClicked: function() {
|
||||||
ServersModel.setCurrentlyProcessedServerIndex(index)
|
ServersModel.currentlyProcessedIndex = index
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(index)
|
|
||||||
goToPage(PageEnum.PageSettingsServerInfo)
|
goToPage(PageEnum.PageSettingsServerInfo)
|
||||||
menu.visible = false
|
menu.visible = false
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,14 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ServersModel
|
||||||
|
|
||||||
|
function onCurrentlyProcessedServerIndexChanged() {
|
||||||
|
content.isServerWithWriteAccess = ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
@ -42,7 +50,10 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
property bool isServerWithWriteAccess: ServersModel.isCurrentlyProcessedServerHasWriteAccess() //todo make it property?
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
visible: content.isServerWithWriteAccess
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Clear Amnezia cache")
|
text: qsTr("Clear Amnezia cache")
|
||||||
|
@ -65,9 +76,12 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {
|
||||||
|
visible: content.isServerWithWriteAccess
|
||||||
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
visible: content.isServerWithWriteAccess
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Проверить сервер на наличие ранее установленных сервисов Amnezia")
|
text: qsTr("Проверить сервер на наличие ранее установленных сервисов Amnezia")
|
||||||
|
@ -78,12 +92,14 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {
|
||||||
|
visible: content.isServerWithWriteAccess
|
||||||
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: "Remove server from application"
|
text: qsTr("Remove server from application")
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
|
@ -115,9 +131,10 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
visible: content.isServerWithWriteAccess
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: "Clear server from Amnezia software"
|
text: qsTr("Clear server from Amnezia software")
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
|
@ -142,7 +159,9 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {
|
||||||
|
visible: content.isServerWithWriteAccess
|
||||||
|
}
|
||||||
|
|
||||||
QuestionDrawer {
|
QuestionDrawer {
|
||||||
id: questionDrawer
|
id: questionDrawer
|
||||||
|
|
|
@ -54,7 +54,13 @@ PageType {
|
||||||
actionButtonImage: "qrc:/images/controls/edit-3.svg"
|
actionButtonImage: "qrc:/images/controls/edit-3.svg"
|
||||||
|
|
||||||
headerText: name
|
headerText: name
|
||||||
descriptionText: credentialsLogin + " · " + hostName
|
descriptionText: {
|
||||||
|
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
|
||||||
|
return credentialsLogin + " · " + hostName
|
||||||
|
} else {
|
||||||
|
return hostName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actionButtonFunction: function() {
|
actionButtonFunction: function() {
|
||||||
serverNameEditDrawer.visible = true
|
serverNameEditDrawer.visible = true
|
||||||
|
@ -123,10 +129,14 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
TabButtonType {
|
TabButtonType {
|
||||||
|
visible: protocolsPage.installedProtocolsCount
|
||||||
|
width: protocolsPage.installedProtocolsCount ? undefined : 0
|
||||||
isSelected: tabBar.currentIndex === 0
|
isSelected: tabBar.currentIndex === 0
|
||||||
text: qsTr("Protocols")
|
text: qsTr("Protocols")
|
||||||
}
|
}
|
||||||
TabButtonType {
|
TabButtonType {
|
||||||
|
visible: servicesPage.installedServicesCount
|
||||||
|
width: servicesPage.installedServicesCount ? undefined : 0
|
||||||
isSelected: tabBar.currentIndex === 1
|
isSelected: tabBar.currentIndex === 1
|
||||||
text: qsTr("Services")
|
text: qsTr("Services")
|
||||||
}
|
}
|
||||||
|
@ -143,9 +153,11 @@ PageType {
|
||||||
currentIndex: tabBar.currentIndex
|
currentIndex: tabBar.currentIndex
|
||||||
|
|
||||||
PageSettingsServerProtocols {
|
PageSettingsServerProtocols {
|
||||||
|
id: protocolsPage
|
||||||
stackView: root.stackView
|
stackView: root.stackView
|
||||||
}
|
}
|
||||||
PageSettingsServerServices {
|
PageSettingsServerServices {
|
||||||
|
id: servicesPage
|
||||||
stackView: root.stackView
|
stackView: root.stackView
|
||||||
}
|
}
|
||||||
PageSettingsServerData {
|
PageSettingsServerData {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import SortFilterProxyModel 0.2
|
||||||
import PageEnum 1.0
|
import PageEnum 1.0
|
||||||
import ProtocolEnum 1.0
|
import ProtocolEnum 1.0
|
||||||
import ContainerProps 1.0
|
import ContainerProps 1.0
|
||||||
|
import ContainersModelFilters 1.0
|
||||||
|
|
||||||
import "./"
|
import "./"
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
|
@ -17,22 +18,31 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
SortFilterProxyModel {
|
property var installedProtocolsCount
|
||||||
id: containersProxyModel
|
|
||||||
sourceModel: ContainersModel
|
|
||||||
filters: [
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "serviceType"
|
|
||||||
value: ProtocolEnum.Vpn
|
|
||||||
},
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "isSupported"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsContainersListView {
|
SettingsContainersListView {
|
||||||
model: containersProxyModel
|
Connections {
|
||||||
|
target: ServersModel
|
||||||
|
|
||||||
|
function onCurrentlyProcessedServerIndexChanged() {
|
||||||
|
updateContainersModelFilters()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateContainersModelFilters() {
|
||||||
|
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
|
||||||
|
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
|
||||||
|
} else {
|
||||||
|
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
|
||||||
|
}
|
||||||
|
root.installedProtocolsCount = proxyContainersModel.count
|
||||||
|
}
|
||||||
|
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
id: proxyContainersModel
|
||||||
|
sourceModel: ContainersModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: updateContainersModelFilters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import SortFilterProxyModel 0.2
|
||||||
import PageEnum 1.0
|
import PageEnum 1.0
|
||||||
import ProtocolEnum 1.0
|
import ProtocolEnum 1.0
|
||||||
import ContainerProps 1.0
|
import ContainerProps 1.0
|
||||||
|
import ContainersModelFilters 1.0
|
||||||
|
|
||||||
import "./"
|
import "./"
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
|
@ -17,22 +18,31 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
SortFilterProxyModel {
|
property var installedServicesCount
|
||||||
id: containersProxyModel
|
|
||||||
sourceModel: ContainersModel
|
|
||||||
filters: [
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "serviceType"
|
|
||||||
value: ProtocolEnum.Other
|
|
||||||
},
|
|
||||||
ValueFilter {
|
|
||||||
roleName: "isSupported"
|
|
||||||
value: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsContainersListView {
|
SettingsContainersListView {
|
||||||
model: containersProxyModel
|
Connections {
|
||||||
|
target: ServersModel
|
||||||
|
|
||||||
|
function onCurrentlyProcessedServerIndexChanged() {
|
||||||
|
updateContainersModelFilters()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateContainersModelFilters() {
|
||||||
|
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
|
||||||
|
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessServicesListFilters()
|
||||||
|
} else {
|
||||||
|
proxyContainersModel.filters = ContainersModelFilters.getReadAccessServicesListFilters()
|
||||||
|
}
|
||||||
|
root.installedServicesCount = proxyContainersModel.count
|
||||||
|
}
|
||||||
|
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
id: proxyContainersModel
|
||||||
|
sourceModel: ContainersModel
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: updateContainersModelFilters()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,8 +89,7 @@ PageType {
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
ServersModel.setCurrentlyProcessedServerIndex(index)
|
ServersModel.currentlyProcessedIndex = index
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(index)
|
|
||||||
goToPage(PageEnum.PageSettingsServerInfo)
|
goToPage(PageEnum.PageSettingsServerInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,10 @@ PageType {
|
||||||
text: qsTr("Set up a server the easy way")
|
text: qsTr("Set up a server the easy way")
|
||||||
|
|
||||||
onClicked: function() {
|
onClicked: function() {
|
||||||
|
if (!isCredentialsFilled()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
InstallController.setShouldCreateServer(true)
|
InstallController.setShouldCreateServer(true)
|
||||||
InstallController.setCurrentlyInstalledServerCredentials(hostname.textField.text, username.textField.text, secretData.textField.text)
|
InstallController.setCurrentlyInstalledServerCredentials(hostname.textField.text, username.textField.text, secretData.textField.text)
|
||||||
|
|
||||||
|
@ -100,6 +104,10 @@ PageType {
|
||||||
text: qsTr("Select protocol to install")
|
text: qsTr("Select protocol to install")
|
||||||
|
|
||||||
onClicked: function() {
|
onClicked: function() {
|
||||||
|
if (!isCredentialsFilled()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
InstallController.setShouldCreateServer(true)
|
InstallController.setShouldCreateServer(true)
|
||||||
InstallController.setCurrentlyInstalledServerCredentials(hostname.textField.text, username.textField.text, secretData.textField.text)
|
InstallController.setCurrentlyInstalledServerCredentials(hostname.textField.text, username.textField.text, secretData.textField.text)
|
||||||
|
|
||||||
|
@ -108,4 +116,25 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCredentialsFilled() {
|
||||||
|
var hasEmptyField = false
|
||||||
|
|
||||||
|
if (hostname.textFieldText === "") {
|
||||||
|
hostname.errorText = qsTr("ip address cannot be empty")
|
||||||
|
hasEmptyField = true
|
||||||
|
} else if (!hostname.textField.acceptableInput) {
|
||||||
|
hostname.errorText = qsTr("Enter the address in the format 255.255.255.255:88")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (username.textFieldText === "") {
|
||||||
|
username.errorText = qsTr("login cannot be empty")
|
||||||
|
hasEmptyField = true
|
||||||
|
}
|
||||||
|
if (secretData.textFieldText === "") {
|
||||||
|
secretData.errorText = qsTr("password/private key cannot be empty")
|
||||||
|
hasEmptyField = true
|
||||||
|
}
|
||||||
|
return !hasEmptyField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ PageType {
|
||||||
|
|
||||||
function onServerAlreadyExists(serverIndex) {
|
function onServerAlreadyExists(serverIndex) {
|
||||||
goToStartPage()
|
goToStartPage()
|
||||||
ServersModel.setCurrentlyProcessedServerIndex(serverIndex)
|
ServersModel.currentlyProcessedIndex = serverIndex
|
||||||
goToPage(PageEnum.PageSettingsServerInfo, false)
|
goToPage(PageEnum.PageSettingsServerInfo, false)
|
||||||
|
|
||||||
PageController.showErrorMessage(qsTr("The server has already been added to the application"))
|
PageController.showErrorMessage(qsTr("The server has already been added to the application"))
|
||||||
|
|
|
@ -147,18 +147,28 @@ PageType {
|
||||||
|
|
||||||
imageSource: "qrc:/images/controls/chevron-right.svg"
|
imageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
model: ServersModel
|
model: SortFilterProxyModel {
|
||||||
currentIndex: ServersModel.getDefaultServerIndex()
|
id: proxyServersModel
|
||||||
|
sourceModel: ServersModel
|
||||||
|
filters: [
|
||||||
|
ValueFilter {
|
||||||
|
roleName: "hasWriteAccess"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex: 0
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
serverSelector.text = selectedText
|
serverSelector.text = selectedText
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(currentIndex)
|
ServersModel.currentlyProcessedIndex = currentIndex
|
||||||
protocolSelector.visible = true
|
protocolSelector.visible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
serverSelector.text = selectedText
|
serverSelector.text = selectedText
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(currentIndex)
|
ServersModel.currentlyProcessedIndex = currentIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +179,7 @@ PageType {
|
||||||
height: parent.height * 0.5
|
height: parent.height * 0.5
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: header
|
id: protocolSelectorHeader
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
@ -187,12 +197,12 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
anchors.top: header.bottom
|
anchors.top: protocolSelectorHeader.bottom
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
contentHeight: col.implicitHeight
|
contentHeight: protocolSelectorContent.implicitHeight
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: col
|
id: protocolSelectorContent
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
@ -265,7 +275,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
id: connectionTypeSelector
|
id: exportTypeSelector
|
||||||
|
|
||||||
property int currentIndex
|
property int currentIndex
|
||||||
|
|
||||||
|
@ -283,8 +293,6 @@ PageType {
|
||||||
headerText: qsTr("Connection format")
|
headerText: qsTr("Connection format")
|
||||||
|
|
||||||
listView: ListViewType {
|
listView: ListViewType {
|
||||||
id: connectionTypeSelectorListView
|
|
||||||
|
|
||||||
rootWidth: root.width
|
rootWidth: root.width
|
||||||
dividerVisible: true
|
dividerVisible: true
|
||||||
|
|
||||||
|
@ -294,14 +302,14 @@ PageType {
|
||||||
currentIndex: 0
|
currentIndex: 0
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
connectionTypeSelector.text = selectedText
|
exportTypeSelector.text = selectedText
|
||||||
connectionTypeSelector.currentIndex = currentIndex
|
exportTypeSelector.currentIndex = currentIndex
|
||||||
connectionTypeSelector.menuVisible = false
|
exportTypeSelector.menuVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
connectionTypeSelector.text = selectedText
|
exportTypeSelector.text = selectedText
|
||||||
connectionTypeSelector.currentIndex = currentIndex
|
exportTypeSelector.currentIndex = currentIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,7 @@ PageType {
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
var pagePath = PageController.getPagePath(PageEnum.PageHome)
|
var pagePath = PageController.getPagePath(PageEnum.PageHome)
|
||||||
ServersModel.setCurrentlyProcessedServerIndex(ServersModel.getDefaultServerIndex())
|
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(ServersModel.getDefaultServerIndex())
|
|
||||||
tabBarStackView.push(pagePath, { "objectName" : pagePath })
|
tabBarStackView.push(pagePath, { "objectName" : pagePath })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,8 +64,8 @@ PageType {
|
||||||
|
|
||||||
topPadding: 8
|
topPadding: 8
|
||||||
bottomPadding: 8//34
|
bottomPadding: 8//34
|
||||||
leftPadding: 96
|
leftPadding: shareTabButton.visible ? 96 : 128
|
||||||
rightPadding: 96
|
rightPadding: shareTabButton.visible ? 96 : 128
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
border.width: 1
|
border.width: 1
|
||||||
|
@ -78,11 +77,25 @@ PageType {
|
||||||
isSelected: tabBar.currentIndex === 0
|
isSelected: tabBar.currentIndex === 0
|
||||||
image: "qrc:/images/controls/home.svg"
|
image: "qrc:/images/controls/home.svg"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
ContainersModel.setCurrentlyProcessedServerIndex(ServersModel.getDefaultServerIndex())
|
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex
|
||||||
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
|
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TabImageButtonType {
|
TabImageButtonType {
|
||||||
|
id: shareTabButton
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ServersModel
|
||||||
|
|
||||||
|
function onDefaultServerIndexChanged() {
|
||||||
|
shareTabButton.visible = ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||||
|
shareTabButton.width = ServersModel.isCurrentlyProcessedServerHasWriteAccess() ? undefined : 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||||
|
width: visible ? undefined : 0
|
||||||
|
|
||||||
isSelected: tabBar.currentIndex === 1
|
isSelected: tabBar.currentIndex === 1
|
||||||
image: "qrc:/images/controls/share-2.svg"
|
image: "qrc:/images/controls/share-2.svg"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -100,8 +113,8 @@ PageType {
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: tabBar
|
anchors.fill: tabBar
|
||||||
anchors.leftMargin: 96
|
anchors.leftMargin: shareTabButton.visible ? 96 : 128
|
||||||
anchors.rightMargin: 96
|
anchors.rightMargin: shareTabButton.visible ? 96 : 128
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue