added output of notifications/errors after installation/import

This commit is contained in:
vladimir.kuznetsov 2023-07-31 00:13:08 +09:00
parent 0411792ca5
commit 1092abe776
39 changed files with 488 additions and 303 deletions

View file

@ -136,7 +136,7 @@ void IOSVpnProtocol::stop()
[m_controller disconnect]; [m_controller disconnect];
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
[m_controller dealloc]; [m_controller dealloc];
m_controller = nullptr; m_controller = nullptr;
@ -264,7 +264,7 @@ void IOSVpnProtocol::setupWireguardProtocol(const QJsonObject& rawConfig)
[m_controller dealloc]; [m_controller dealloc];
m_controller = nullptr; m_controller = nullptr;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Error); emit connectionStateChanged(Vpn::ConnectionState::Error);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -272,7 +272,7 @@ void IOSVpnProtocol::setupWireguardProtocol(const QJsonObject& rawConfig)
case ConnectionStateConnected: { case ConnectionStateConnected: {
Q_ASSERT(date); Q_ASSERT(date);
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -280,7 +280,7 @@ void IOSVpnProtocol::setupWireguardProtocol(const QJsonObject& rawConfig)
case ConnectionStateDisconnected: case ConnectionStateDisconnected:
[m_controller disconnect]; [m_controller disconnect];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -294,13 +294,13 @@ void IOSVpnProtocol::setupWireguardProtocol(const QJsonObject& rawConfig)
qDebug() << "State changed: " << a_connected; qDebug() << "State changed: " << a_connected;
if (a_connected) { if (a_connected) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
} }
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];
@ -325,7 +325,7 @@ void IOSVpnProtocol::setupCloakProtocol(const QJsonObject &rawConfig)
[m_controller dealloc]; [m_controller dealloc];
m_controller = nullptr; m_controller = nullptr;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Error); emit connectionStateChanged(Vpn::ConnectionState::Error);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -333,7 +333,7 @@ void IOSVpnProtocol::setupCloakProtocol(const QJsonObject &rawConfig)
case ConnectionStateConnected: { case ConnectionStateConnected: {
Q_ASSERT(date); Q_ASSERT(date);
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -341,7 +341,7 @@ void IOSVpnProtocol::setupCloakProtocol(const QJsonObject &rawConfig)
case ConnectionStateDisconnected: case ConnectionStateDisconnected:
// Just in case we are connecting, let's call disconnect. // Just in case we are connecting, let's call disconnect.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -355,13 +355,13 @@ void IOSVpnProtocol::setupCloakProtocol(const QJsonObject &rawConfig)
qDebug() << "VPN State changed: " << a_connected; qDebug() << "VPN State changed: " << a_connected;
if (a_connected) { if (a_connected) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
} }
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];
@ -388,7 +388,7 @@ void IOSVpnProtocol::setupOpenVPNProtocol(const QJsonObject &rawConfig)
[m_controller dealloc]; [m_controller dealloc];
m_controller = nullptr; m_controller = nullptr;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Error); emit connectionStateChanged(Vpn::ConnectionState::Error);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -396,7 +396,7 @@ void IOSVpnProtocol::setupOpenVPNProtocol(const QJsonObject &rawConfig)
case ConnectionStateConnected: { case ConnectionStateConnected: {
Q_ASSERT(date); Q_ASSERT(date);
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -404,7 +404,7 @@ void IOSVpnProtocol::setupOpenVPNProtocol(const QJsonObject &rawConfig)
case ConnectionStateDisconnected: case ConnectionStateDisconnected:
// Just in case we are connecting, let's call disconnect. // Just in case we are connecting, let's call disconnect.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -418,13 +418,13 @@ void IOSVpnProtocol::setupOpenVPNProtocol(const QJsonObject &rawConfig)
qDebug() << "VPN State changed: " << a_connected; qDebug() << "VPN State changed: " << a_connected;
if (a_connected) { if (a_connected) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
} }
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];
@ -452,7 +452,7 @@ void IOSVpnProtocol::setupShadowSocksProtocol(const QJsonObject &rawConfig)
[m_controller dealloc]; [m_controller dealloc];
m_controller = nullptr; m_controller = nullptr;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Error); emit connectionStateChanged(Vpn::ConnectionState::Error);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -460,7 +460,7 @@ void IOSVpnProtocol::setupShadowSocksProtocol(const QJsonObject &rawConfig)
case ConnectionStateConnected: { case ConnectionStateConnected: {
Q_ASSERT(date); Q_ASSERT(date);
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -468,7 +468,7 @@ void IOSVpnProtocol::setupShadowSocksProtocol(const QJsonObject &rawConfig)
case ConnectionStateDisconnected: case ConnectionStateDisconnected:
// Just in case we are connecting, let's call disconnect. // Just in case we are connecting, let's call disconnect.
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(VpnConnectionState::Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
@ -482,13 +482,13 @@ void IOSVpnProtocol::setupShadowSocksProtocol(const QJsonObject &rawConfig)
qDebug() << "SS State changed: " << a_connected; qDebug() << "SS State changed: " << a_connected;
if (a_connected) { if (a_connected) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Connected); emit connectionStateChanged(Vpn::ConnectionState::Connected);
m_isChangingState = false; m_isChangingState = false;
}); });
return; return;
} }
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];
@ -539,7 +539,7 @@ void IOSVpnProtocol::launchWireguardTunnel(const QJsonObject &rawConfig)
failureCallback:^() { failureCallback:^() {
qDebug() << "Wireguard Protocol - connection failed"; qDebug() << "Wireguard Protocol - connection failed";
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];
@ -590,7 +590,7 @@ void IOSVpnProtocol::launchCloakTunnel(const QJsonObject &rawConfig)
failureCallback:^{ failureCallback:^{
qDebug() << "IOSVPNProtocol (OpenVPN Cloak) - connection failed"; qDebug() << "IOSVPNProtocol (OpenVPN Cloak) - connection failed";
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];
@ -607,7 +607,7 @@ void IOSVpnProtocol::launchOpenVPNTunnel(const QJsonObject &rawConfig)
failureCallback:^{ failureCallback:^{
qDebug() << "IOSVPNProtocol (OpenVPN) - connection failed"; qDebug() << "IOSVPNProtocol (OpenVPN) - connection failed";
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];
@ -624,7 +624,7 @@ void IOSVpnProtocol::launchShadowSocksTunnel(const QJsonObject &rawConfig) {
failureCallback:^{ failureCallback:^{
qDebug() << "IOSVPNProtocol (ShadowSocks) - connection failed"; qDebug() << "IOSVPNProtocol (ShadowSocks) - connection failed";
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
emit connectionStateChanged(Disconnected); emit connectionStateChanged(Vpn::ConnectionState::Disconnected);
m_isChangingState = false; m_isChangingState = false;
}); });
}]; }];

View file

@ -204,25 +204,25 @@ QList<QString> ExportController::getQrCodes()
void ExportController::saveFile() void ExportController::saveFile()
{ {
#if defined Q_OS_IOS #if defined Q_OS_IOS
ext.replace("*", ""); // ext.replace("*", "");
QString fileName = QDir::tempPath() + "/" + suggestedName; // QString fileName = QDir::tempPath() + "/" + suggestedName;
//
if (fileName.isEmpty()) // if (fileName.isEmpty())
return; // return;
if (!fileName.endsWith(ext)) // if (!fileName.endsWith(ext))
fileName.append(ext); // fileName.append(ext);
//
QFile::remove(fileName); // QFile::remove(fileName);
//
QFile save(fileName); // QFile save(fileName);
save.open(QIODevice::WriteOnly); // save.open(QIODevice::WriteOnly);
save.write(data.toUtf8()); // save.write(data.toUtf8());
save.close(); // save.close();
//
QStringList filesToSend; // QStringList filesToSend;
filesToSend.append(fileName); // filesToSend.append(fileName);
MobileUtils::shareText(filesToSend); // MobileUtils::shareText(filesToSend);
return; // return;
#endif #endif
#if defined Q_OS_ANDROID #if defined Q_OS_ANDROID
AndroidController::instance()->shareConfig(m_config, "amnezia_config"); AndroidController::instance()->shareConfig(m_config, "amnezia_config");

View file

@ -149,9 +149,7 @@ void ImportController::importConfig()
if (credentials.isValid() || m_config.contains(config_key::containers)) { if (credentials.isValid() || m_config.contains(config_key::containers)) {
m_serversModel->addServer(m_config); m_serversModel->addServer(m_config);
if (!m_config.value(config_key::containers).toArray().isEmpty()) { m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
}
emit importFinished(); emit importFinished();
} else { } else {

View file

@ -88,14 +88,20 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
QMap<DockerContainer, QJsonObject> installedContainers; QMap<DockerContainer, QJsonObject> installedContainers;
ErrorCode errorCode = ErrorCode errorCode =
serverController.getAlreadyInstalledContainers(m_currentlyInstalledServerCredentials, installedContainers); serverController.getAlreadyInstalledContainers(m_currentlyInstalledServerCredentials, installedContainers);
QString finishMessage = "";
if (!installedContainers.contains(container)) { if (!installedContainers.contains(container)) {
errorCode = serverController.setupContainer(m_currentlyInstalledServerCredentials, container, config); errorCode = serverController.setupContainer(m_currentlyInstalledServerCredentials, container, config);
installedContainers.insert(container, config); installedContainers.insert(container, config);
finishMessage = ContainerProps::containerHumanNames().value(container) + tr(" installed successfully. ");
} else {
finishMessage =
ContainerProps::containerHumanNames().value(container) + tr(" is already installed on the server. ");
} }
if (installedContainers.size() > 1) {
bool isInstalledContainerFound = false; finishMessage += tr("\nAlready installed containers were found on the server. "
if (!installedContainers.isEmpty()) { "All installed containers have been added to the application");
isInstalledContainerFound = true;
} }
if (errorCode == ErrorCode::NoError) { if (errorCode == ErrorCode::NoError) {
@ -117,7 +123,7 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
m_serversModel->addServer(server); m_serversModel->addServer(server);
m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1); m_serversModel->setDefaultServerIndex(m_serversModel->getServersCount() - 1);
emit installServerFinished(false); // todo incorrect notification about found containers emit installServerFinished(finishMessage);
return; return;
} }
@ -135,16 +141,19 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
QMap<DockerContainer, QJsonObject> installedContainers; QMap<DockerContainer, QJsonObject> installedContainers;
ErrorCode errorCode = serverController.getAlreadyInstalledContainers(serverCredentials, installedContainers); ErrorCode errorCode = serverController.getAlreadyInstalledContainers(serverCredentials, installedContainers);
bool isInstalledContainerFound = false; QString finishMessage = "";
if (!installedContainers.isEmpty()) {
isInstalledContainerFound = true;
}
if (!installedContainers.contains(container)) { if (!installedContainers.contains(container)) {
errorCode = serverController.setupContainer(serverCredentials, container, config); errorCode = serverController.setupContainer(serverCredentials, container, config);
installedContainers.insert(container, config); installedContainers.insert(container, config);
finishMessage = ContainerProps::containerHumanNames().value(container) + tr(" installed successfully. ");
} else {
finishMessage =
ContainerProps::containerHumanNames().value(container) + tr(" is already installed on the server. ");
} }
bool isInstalledContainerAddedToGui = false;
if (errorCode == ErrorCode::NoError) { if (errorCode == ErrorCode::NoError) {
for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) { for (auto iterator = installedContainers.begin(); iterator != installedContainers.end(); iterator++) {
auto modelIndex = m_containersModel->index(iterator.key()); auto modelIndex = m_containersModel->index(iterator.key());
@ -153,10 +162,17 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
if (containerConfig.isEmpty()) { if (containerConfig.isEmpty()) {
m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(), m_containersModel->setData(m_containersModel->index(iterator.key()), iterator.value(),
ContainersModel::Roles::ConfigRole); ContainersModel::Roles::ConfigRole);
if (container != iterator.key()) { // skip the newly installed container
isInstalledContainerAddedToGui = true;
}
} }
} }
if (isInstalledContainerAddedToGui) {
finishMessage += tr("\nAlready installed containers were found on the server. "
"All installed containers have been added to the application");
}
emit installContainerFinished(false); // todo incorrect notification about found containers emit installContainerFinished(finishMessage);
return; return;
} }
@ -233,11 +249,55 @@ void InstallController::updateContainer(QJsonObject config)
emit installationErrorOccurred(errorString(errorCode)); emit installationErrorOccurred(errorString(errorCode));
} }
void InstallController::removeCurrentlyProcessedServer()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->removeServer();
emit removeCurrentlyProcessedServerFinished(tr("Server '") + serverName + tr("' was removed"));
}
void InstallController::removeAllContainers()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
ErrorCode errorCode = m_containersModel->removeAllContainers();
if (errorCode == ErrorCode::NoError) {
emit removeAllContainersFinished(tr("All containers from server '") + serverName + ("' have been removed"));
return;
}
emit installationErrorOccurred(errorString(errorCode));
}
void InstallController::removeCurrentlyProcessedContainer()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
int container = m_containersModel->getCurrentlyProcessedContainerIndex();
QString containerName = m_containersModel->data(container, ContainersModel::Roles::NameRole).toString();
ErrorCode errorCode = m_containersModel->removeCurrentlyProcessedContainer();
if (errorCode == ErrorCode::NoError) {
emit removeCurrentlyProcessedContainerFinished(containerName + tr(" has been removed from the server '")
+ serverName + "'");
return;
}
emit installationErrorOccurred(errorString(errorCode));
}
QRegularExpression InstallController::ipAddressPortRegExp() QRegularExpression InstallController::ipAddressPortRegExp()
{ {
return Utils::ipAddressPortRegExp(); return Utils::ipAddressPortRegExp();
} }
QRegularExpression InstallController::ipAddressRegExp()
{
return Utils::ipAddressRegExp();
}
void InstallController::setCurrentlyInstalledServerCredentials(const QString &hostName, const QString &userName, void InstallController::setCurrentlyInstalledServerCredentials(const QString &hostName, const QString &userName,
const QString &secretData) const QString &secretData)
{ {

View file

@ -28,18 +28,27 @@ public slots:
void updateContainer(QJsonObject config); void updateContainer(QJsonObject config);
void removeCurrentlyProcessedServer();
void removeAllContainers();
void removeCurrentlyProcessedContainer();
QRegularExpression ipAddressPortRegExp(); QRegularExpression ipAddressPortRegExp();
QRegularExpression ipAddressRegExp();
void mountSftpDrive(const QString &port, const QString &password, const QString &username); void mountSftpDrive(const QString &port, const QString &password, const QString &username);
signals: signals:
void installContainerFinished(bool isInstalledContainerFound); void installContainerFinished(QString finishMessage);
void installServerFinished(bool isInstalledContainerFound); void installServerFinished(QString finishMessage);
void updateContainerFinished(); void updateContainerFinished();
void scanServerFinished(bool isInstalledContainerFound); void scanServerFinished(bool isInstalledContainerFound);
void removeCurrentlyProcessedServerFinished(QString finishedMessage);
void removeAllContainersFinished(QString finishedMessage);
void removeCurrentlyProcessedContainerFinished(QString finishedMessage);
void installationErrorOccurred(QString errorMessage); void installationErrorOccurred(QString errorMessage);
void serverAlreadyExists(int serverIndex); void serverAlreadyExists(int serverIndex);
@ -57,7 +66,9 @@ private:
bool m_shouldCreateServer; bool m_shouldCreateServer;
#ifndef Q_OS_IOS
QList<QSharedPointer<QProcess>> m_sftpMountProcesses; QList<QSharedPointer<QProcess>> m_sftpMountProcesses;
#endif
}; };
#endif // INSTALLCONTROLLER_H #endif // INSTALLCONTROLLER_H

View file

@ -84,7 +84,7 @@ signals:
void replaceStartPage(); void replaceStartPage();
void showErrorMessage(QString errorMessage); void showErrorMessage(QString errorMessage);
void showInfoMessage(QString message); void showNotificationMessage(QString message);
void showBusyIndicator(bool visible); void showBusyIndicator(bool visible);

View file

@ -1,15 +0,0 @@
#include "protocolSettingsController.h"
ProtocolSettingsController::ProtocolSettingsController(const QSharedPointer<ServersModel> &serversModel,
const QSharedPointer<ContainersModel> &containersModel,
const std::shared_ptr<Settings> &settings, QObject *parent)
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
{
}
QByteArray ProtocolSettingsController::getOpenVpnConfig()
{
auto containerIndex = m_containersModel->index(m_containersModel->getCurrentlyProcessedContainerIndex());
auto config = m_containersModel->data(containerIndex, ContainersModel::Roles::ConfigRole);
return QByteArray();
}

View file

@ -1,31 +0,0 @@
#ifndef PROTOCOLSETTINGSCONTROLLER_H
#define PROTOCOLSETTINGSCONTROLLER_H
#include <QObject>
#include "containers/containers_defs.h"
#include "core/defs.h"
#include "ui/models/containers_model.h"
#include "ui/models/servers_model.h"
class ProtocolSettingsController : public QObject
{
Q_OBJECT
public:
explicit ProtocolSettingsController(const QSharedPointer<ServersModel> &serversModel,
const QSharedPointer<ContainersModel> &containersModel,
const std::shared_ptr<Settings> &settings,
QObject *parent = nullptr);
public slots:
QByteArray getOpenVpnConfig();
signals:
private:
QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<ContainersModel> m_containersModel;
std::shared_ptr<Settings> m_settings;
};
#endif // PROTOCOLSETTINGSCONTROLLER_H

View file

@ -84,9 +84,10 @@ void SettingsController::restoreAppConfig()
Utils::getFileName(Q_NULLPTR, tr("Open backup"), Utils::getFileName(Q_NULLPTR, tr("Open backup"),
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.backup"); QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*.backup");
// todo error processing if (fileName.isEmpty()) {
if (fileName.isEmpty()) emit changeSettingsErrorOccurred(tr("Backup file is empty"));
return; return;
}
QFile file(fileName); QFile file(fileName);
file.open(QIODevice::ReadOnly); file.open(QIODevice::ReadOnly);
@ -94,7 +95,10 @@ void SettingsController::restoreAppConfig()
bool ok = m_settings->restoreAppConfig(data); bool ok = m_settings->restoreAppConfig(data);
if (ok) { if (ok) {
// emit uiLogic()->showWarningMessage(tr("Can't import config, file is corrupted.")); m_serversModel->resetModel();
emit restoreBackupFinished();
} else {
emit changeSettingsErrorOccurred(tr("Backup file is corrupted"));
} }
} }
@ -106,4 +110,5 @@ QString SettingsController::getAppVersion()
void SettingsController::clearSettings() void SettingsController::clearSettings()
{ {
m_settings->clearSettings(); m_settings->clearSettings();
m_serversModel->resetModel();
} }

View file

@ -47,6 +47,9 @@ signals:
void secondaryDnsChanged(); void secondaryDnsChanged();
void loggingStateChanged(); void loggingStateChanged();
void restoreBackupFinished();
void changeSettingsErrorOccurred(QString errorMessage);
private: private:
QSharedPointer<ServersModel> m_serversModel; QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<ContainersModel> m_containersModel; QSharedPointer<ContainersModel> m_containersModel;

View file

@ -83,6 +83,12 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
return QVariant(); return QVariant();
} }
QVariant ContainersModel::data(const int index, int role) const
{
QModelIndex modelIndex = this->index(index);
return data(modelIndex, role);
}
void ContainersModel::setCurrentlyProcessedServerIndex(const int index) void ContainersModel::setCurrentlyProcessedServerIndex(const int index)
{ {
beginResetModel(); beginResetModel();
@ -123,11 +129,12 @@ QJsonObject ContainersModel::getCurrentlyProcessedContainerConfig()
return qvariant_cast<QJsonObject>(data(index(m_currentlyProcessedContainerIndex), ConfigRole)); return qvariant_cast<QJsonObject>(data(index(m_currentlyProcessedContainerIndex), ConfigRole));
} }
void ContainersModel::removeAllContainers() ErrorCode ContainersModel::removeAllContainers()
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
auto errorCode = serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex)); ErrorCode errorCode =
serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex));
if (errorCode == ErrorCode::NoError) { if (errorCode == ErrorCode::NoError) {
beginResetModel(); beginResetModel();
@ -138,30 +145,32 @@ void ContainersModel::removeAllContainers()
setData(index(DockerContainer::None, 0), true, IsDefaultRole); setData(index(DockerContainer::None, 0), true, IsDefaultRole);
endResetModel(); endResetModel();
} }
return errorCode;
// todo process errors
} }
void ContainersModel::removeCurrentlyProcessedContainer() ErrorCode ContainersModel::removeCurrentlyProcessedContainer()
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex); auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex);
auto dockerContainer = static_cast<DockerContainer>(m_currentlyProcessedContainerIndex); auto dockerContainer = static_cast<DockerContainer>(m_currentlyProcessedContainerIndex);
ErrorCode e = serverController.removeContainer(credentials, dockerContainer); ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer);
beginResetModel(); // todo change to begin remove rows? if (errorCode == ErrorCode::NoError) {
m_settings->removeContainerConfig(m_currentlyProcessedServerIndex, dockerContainer); beginResetModel(); // todo change to begin remove rows?
m_containers = m_settings->containers(m_currentlyProcessedServerIndex); m_settings->removeContainerConfig(m_currentlyProcessedServerIndex, dockerContainer);
m_containers = m_settings->containers(m_currentlyProcessedServerIndex);
if (m_defaultContainerIndex == m_currentlyProcessedContainerIndex) { if (m_defaultContainerIndex == m_currentlyProcessedContainerIndex) {
if (m_containers.isEmpty()) { if (m_containers.isEmpty()) {
setData(index(DockerContainer::None, 0), true, IsDefaultRole); setData(index(DockerContainer::None, 0), true, IsDefaultRole);
} else { } else {
setData(index(m_containers.begin().key(), 0), true, IsDefaultRole); setData(index(m_containers.begin().key(), 0), true, IsDefaultRole);
}
} }
endResetModel();
} }
endResetModel(); return errorCode;
} }
void ContainersModel::clearCachedProfiles() void ContainersModel::clearCachedProfiles()

View file

@ -36,9 +36,9 @@ public:
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
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) const;
signals: Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged)
void defaultContainerChanged();
public slots: public slots:
DockerContainer getDefaultContainer(); DockerContainer getDefaultContainer();
@ -52,8 +52,8 @@ public slots:
QString getCurrentlyProcessedContainerName(); QString getCurrentlyProcessedContainerName();
QJsonObject getCurrentlyProcessedContainerConfig(); QJsonObject getCurrentlyProcessedContainerConfig();
void removeAllContainers(); ErrorCode removeAllContainers();
void removeCurrentlyProcessedContainer(); ErrorCode removeCurrentlyProcessedContainer();
void clearCachedProfiles(); void clearCachedProfiles();
bool isAmneziaDnsContainerInstalled(); bool isAmneziaDnsContainerInstalled();
@ -62,6 +62,9 @@ public slots:
protected: protected:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
signals:
void defaultContainerChanged();
private: private:
QMap<DockerContainer, QJsonObject> m_containers; QMap<DockerContainer, QJsonObject> m_containers;

View file

@ -17,6 +17,7 @@ QHash<int, QByteArray> ProtocolsModel::roleNames() const
roles[ProtocolNameRole] = "protocolName"; roles[ProtocolNameRole] = "protocolName";
roles[ProtocolPageRole] = "protocolPage"; roles[ProtocolPageRole] = "protocolPage";
roles[ProtocolIndexRole] = "protocolIndex";
roles[RawConfigRole] = "rawConfig"; roles[RawConfigRole] = "rawConfig";
return roles; return roles;
@ -35,6 +36,7 @@ QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
} }
case ProtocolPageRole: case ProtocolPageRole:
return static_cast<int>(protocolPage(ProtocolProps::protoFromString(m_content.keys().at(index.row())))); return static_cast<int>(protocolPage(ProtocolProps::protoFromString(m_content.keys().at(index.row()))));
case ProtocolIndexRole: return ProtocolProps::protoFromString(m_content.keys().at(index.row()));
case RawConfigRole: { case RawConfigRole: {
auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject(); auto protocolConfig = m_content.value(ContainerProps::containerTypeToString(m_container)).toObject();
auto lastConfigJsonDoc = auto lastConfigJsonDoc =

View file

@ -14,6 +14,7 @@ public:
enum Roles { enum Roles {
ProtocolNameRole = Qt::UserRole + 1, ProtocolNameRole = Qt::UserRole + 1,
ProtocolPageRole, ProtocolPageRole,
ProtocolIndexRole,
RawConfigRole RawConfigRole
}; };

View file

@ -78,6 +78,15 @@ QVariant ServersModel::data(const int index, int role) const
return data(modelIndex, role); return data(modelIndex, role);
} }
void ServersModel::resetModel()
{
beginResetModel();
m_servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex();
m_currentlyProcessedServerIndex = m_defaultServerIndex;
endResetModel();
}
void ServersModel::setDefaultServerIndex(const int index) void ServersModel::setDefaultServerIndex(const int index)
{ {
m_settings->setDefaultServer(index); m_settings->setDefaultServer(index);
@ -90,11 +99,31 @@ const int ServersModel::getDefaultServerIndex()
return m_defaultServerIndex; return m_defaultServerIndex;
} }
const QString ServersModel::getDefaultServerName()
{
return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole));
}
const QString ServersModel::getDefaultServerHostName()
{
return qvariant_cast<QString>(data(m_defaultServerIndex, HostNameRole));
}
const int ServersModel::getServersCount() const int ServersModel::getServersCount()
{ {
return m_servers.count(); return m_servers.count();
} }
bool ServersModel::hasServerWithWriteAccess()
{
for (size_t i = 0; i < getServersCount(); i++) {
if (qvariant_cast<bool>(data(i, HasWriteAccessRole))) {
return true;
}
}
return false;
}
void ServersModel::setCurrentlyProcessedServerIndex(const int index) void ServersModel::setCurrentlyProcessedServerIndex(const int index)
{ {
m_currentlyProcessedServerIndex = index; m_currentlyProcessedServerIndex = index;
@ -123,7 +152,7 @@ bool ServersModel::isCurrentlyProcessedServerHasWriteAccess()
bool ServersModel::isDefaultServerHasWriteAccess() bool ServersModel::isDefaultServerHasWriteAccess()
{ {
return qvariant_cast<bool>(data(m_currentlyProcessedServerIndex, HasWriteAccessRole)); return qvariant_cast<bool>(data(m_defaultServerIndex, HasWriteAccessRole));
} }
void ServersModel::addServer(const QJsonObject &server) void ServersModel::addServer(const QJsonObject &server)

View file

@ -28,17 +28,24 @@ 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;
void resetModel();
Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged) Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged)
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerIndexChanged)
Q_PROPERTY(QString defaultServerHostName READ getDefaultServerHostName NOTIFY defaultServerIndexChanged)
Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex
NOTIFY currentlyProcessedServerIndexChanged) NOTIFY currentlyProcessedServerIndexChanged)
public slots: public slots:
void setDefaultServerIndex(const int index); void setDefaultServerIndex(const int index);
const int getDefaultServerIndex(); const int getDefaultServerIndex();
const QString getDefaultServerName();
const QString getDefaultServerHostName();
bool isDefaultServerCurrentlyProcessed(); bool isDefaultServerCurrentlyProcessed();
bool isCurrentlyProcessedServerHasWriteAccess(); bool isCurrentlyProcessedServerHasWriteAccess();
bool isDefaultServerHasWriteAccess(); bool isDefaultServerHasWriteAccess();
bool hasServerWithWriteAccess();
const int getServersCount(); const int getServersCount();

View file

@ -78,11 +78,5 @@ ListView {
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
Component.onCompleted: {
if (isDefault) {
root.currentContainerName = name
}
}
} }
} }

View file

@ -67,7 +67,7 @@ DrawerType {
delegate: Item { delegate: Item {
implicitWidth: root.width implicitWidth: root.width
implicitHeight: content.implicitHeight implicitHeight: delegateContent.implicitHeight
ColumnLayout { ColumnLayout {
id: delegateContent id: delegateContent

View file

@ -9,6 +9,11 @@ CheckBox {
id: root id: root
property string descriptionText property string descriptionText
property string descriptionTextColor: "#878B91"
property string descriptionTextDisabledColor: "#494B50"
property string textColor: "#D7D8DB"
property string textDisabledColor: "#878B91"
property string hoveredColor: Qt.rgba(1, 1, 1, 0.05) property string hoveredColor: Qt.rgba(1, 1, 1, 0.05)
property string defaultColor: "transparent" property string defaultColor: "transparent"
@ -16,14 +21,16 @@ CheckBox {
property string defaultBorderColor: "#D7D8DB" property string defaultBorderColor: "#D7D8DB"
property string checkedBorderColor: "#FBB26A" property string checkedBorderColor: "#FBB26A"
property string checkedBorderDisabledColor: "#5A330C"
property string checkedImageColor: "#FBB26A" property string checkedImageColor: "#FBB26A"
property string pressedImageColor: "#A85809" property string pressedImageColor: "#A85809"
property string defaultImageColor: "transparent" property string defaultImageColor: "transparent"
property string checkedDisabledImageColor: "#84603D"
property string imageSource: "qrc:/images/controls/check.svg" property string imageSource: "qrc:/images/controls/check.svg"
hoverEnabled: true hoverEnabled: enabled ? true : false
indicator: Rectangle { indicator: Rectangle {
id: background id: background
@ -52,7 +59,7 @@ CheckBox {
width: 24 width: 24
height: 24 height: 24
color: "transparent" color: "transparent"
border.color: root.checked ? checkedBorderColor : defaultBorderColor border.color: root.checked ? (root.enabled ? checkedBorderColor : checkedBorderDisabledColor) : defaultBorderColor
border.width: 1 border.width: 1
radius: 4 radius: 4
@ -63,7 +70,19 @@ CheckBox {
layer { layer {
enabled: true enabled: true
effect: ColorOverlay { effect: ColorOverlay {
color: root.pressed ? pressedImageColor : root.checked ? checkedImageColor : defaultImageColor color: {
if (root.pressed) {
return root.pressedImageColor
} else if (root.checked) {
if (root.enabled) {
return root.checkedImageColor
} else {
return root.checkedDisabledImageColor
}
} else {
return root.defaultImageColor
}
}
} }
} }
} }
@ -90,6 +109,7 @@ CheckBox {
Layout.fillWidth: true Layout.fillWidth: true
text: root.text text: root.text
color: root.enabled ? root.textColor : root.textDisabledColor
} }
CaptionTextType { CaptionTextType {
@ -98,7 +118,7 @@ CheckBox {
Layout.fillWidth: true Layout.fillWidth: true
text: root.descriptionText text: root.descriptionText
color: "#878b91" color: root.enabled ? root.descriptionTextColor : root.descriptionTextDisabledColor
visible: root.descriptionText !== "" visible: root.descriptionText !== ""
} }

View file

@ -9,14 +9,16 @@ RadioButton {
property string hoveredColor: Qt.rgba(1, 1, 1, 0.05) property string hoveredColor: Qt.rgba(1, 1, 1, 0.05)
property string defaultColor: Qt.rgba(1, 1, 1, 0) property string defaultColor: Qt.rgba(1, 1, 1, 0)
property string disabledColor: Qt.rgba(1, 1, 1, 0) property string checkedColor: Qt.rgba(1, 1, 1, 0)
property string selectedColor: Qt.rgba(1, 1, 1, 0) property string disabledColor: "transparent"
property string textColor: "#0E0E11" property string textColor: "#D7D8DB"
property string textDisabledColor: "#878B91"
property string pressedBorderColor: "#494B50" property string pressedBorderColor: "#494B50"
property string selectedBorderColor: "#FBB26A" property string checkedBorderColor: "#FBB26A"
property string defaultBodredColor: "transparent" property string defaultBodredColor: "transparent"
property string checkedDisabledBorderColor: "#84603D"
property int borderWidth: 0 property int borderWidth: 0
implicitWidth: content.implicitWidth implicitWidth: content.implicitWidth
@ -27,39 +29,39 @@ RadioButton {
radius: 16 radius: 16
color: { color: {
// if (root.enabled) { if (root.enabled) {
if (root.hovered) { if (root.hovered) {
return hoveredColor return root.hoveredColor
} else if (root.checked) { } else if (root.checked) {
return selectedColor return root.checkedColor
} }
return defaultColor return root.defaultColor
// } else { } else {
// return disabledColor return root.disabledColor
// } }
} }
border.color: { border.color: {
// if (root.enabled) { if (root.enabled) {
if (root.pressed) { if (root.pressed) {
return pressedBorderColor return root.pressedBorderColor
} else if (root.checked) { } else if (root.checked) {
return selectedBorderColor return root.checkedBorderColor
} }
return defaultBodredColor return root.defaultBodredColor
// } } else {
// return defaultBodredColor if (root.checked) {
return root.checkedDisabledBorderColor
}
return root.defaultBodredColor
}
} }
border.width: { border.width: {
// if (root.enabled) { if(root.checked) {
if(root.checked) { return 1
return 1 }
} return root.pressed ? 1 : 0
return root.pressed ? 1 : 0
// } else {
// return 0
// }
} }
Behavior on color { Behavior on color {
@ -77,6 +79,7 @@ RadioButton {
ButtonTextType { ButtonTextType {
text: root.text text: root.text
color: root.enabled ? root.textColor : root.textDisabledColor
Layout.fillWidth: true Layout.fillWidth: true
Layout.rightMargin: 16 Layout.rightMargin: 16

View file

@ -7,7 +7,7 @@ import "TextTypes"
Popup { Popup {
id: root id: root
property string popupErrorMessageText property string text
property bool closeButtonVisible: true property bool closeButtonVisible: true
leftMargin: 25 leftMargin: 25
@ -17,46 +17,56 @@ Popup {
width: parent.width - leftMargin - rightMargin width: parent.width - leftMargin - rightMargin
anchors.centerIn: parent anchors.centerIn: parent
modal: true modal: root.closeButtonVisible
closePolicy: Popup.CloseOnEscape closePolicy: Popup.CloseOnEscape
Overlay.modal: Rectangle { Overlay.modal: Rectangle {
visible: root.closeButtonVisible
color: Qt.rgba(14/255, 14/255, 17/255, 0.8) color: Qt.rgba(14/255, 14/255, 17/255, 0.8)
} }
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
color: "white"//Qt.rgba(215/255, 216/255, 219/255, 0.95) color: "white"
radius: 4 radius: 4
} }
contentItem: RowLayout { contentItem: Item {
implicitWidth: content.implicitWidth
implicitHeight: content.implicitHeight
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 16
anchors.rightMargin: 16
CaptionTextType { RowLayout {
horizontalAlignment: Text.AlignLeft id: content
Layout.fillWidth: true
text: root.popupErrorMessageText anchors.fill: parent
} anchors.leftMargin: 16
anchors.rightMargin: 16
BasicButtonType { CaptionTextType {
visible: closeButtonVisible horizontalAlignment: Text.AlignLeft
Layout.fillWidth: true
defaultColor: "white"//"transparent"//Qt.rgba(215/255, 216/255, 219/255, 0.95) text: root.text
hoveredColor: "#C1C2C5" }
pressedColor: "#AEB0B7"
disabledColor: "#494B50"
textColor: "#0E0E11" BasicButtonType {
borderWidth: 0 visible: closeButtonVisible
text: qsTr("Close") defaultColor: "white"
onClicked: { hoveredColor: "#C1C2C5"
root.close() pressedColor: "#AEB0B7"
disabledColor: "#494B50"
textColor: "#0E0E11"
borderWidth: 0
text: qsTr("Close")
onClicked: {
root.close()
}
} }
} }
} }

View file

@ -8,14 +8,24 @@ Switch {
id: root id: root
property alias descriptionText: description.text property alias descriptionText: description.text
property string descriptionTextColor: "#878B91"
property string descriptionTextDisabledColor: "#494B50"
property string textColor: "#D7D8DB"
property string textDisabledColor: "#878B91"
property string checkedIndicatorColor: "#412102" property string checkedIndicatorColor: "#412102"
property string defaultIndicatorColor: "transparent" property string defaultIndicatorColor: "transparent"
property string checkedDisabledIndicatorColor: "#5A330C"
property string checkedIndicatorBorderColor: "#412102" property string checkedIndicatorBorderColor: "#412102"
property string defaultIndicatorBorderColor: "#494B50" property string defaultIndicatorBorderColor: "#494B50"
property string checkedDisabledIndicatorBorderColor: "#5A330C"
property string checkedInnerCircleColor: "#FBB26A" property string checkedInnerCircleColor: "#FBB26A"
property string defaultInnerCircleColor: "#D7D8DB" property string defaultInnerCircleColor: "#D7D8DB"
property string checkedDisabledInnerCircleColor: "#84603D"
property string defaultDisabledInnerCircleColor: "#494B50"
property string hoveredIndicatorBackgroundColor: Qt.rgba(1, 1, 1, 0.08) property string hoveredIndicatorBackgroundColor: Qt.rgba(1, 1, 1, 0.08)
property string defaultIndicatorBackgroundColor: "transparent" property string defaultIndicatorBackgroundColor: "transparent"
@ -23,6 +33,8 @@ Switch {
implicitWidth: content.implicitWidth + switcher.implicitWidth implicitWidth: content.implicitWidth + switcher.implicitWidth
implicitHeight: content.implicitHeight implicitHeight: content.implicitHeight
hoverEnabled: enabled ? true : false
indicator: Rectangle { indicator: Rectangle {
id: switcher id: switcher
@ -33,8 +45,10 @@ Switch {
implicitHeight: 32 implicitHeight: 32
radius: 16 radius: 16
color: root.checked ? checkedIndicatorColor : defaultIndicatorColor color: root.checked ? (root.enabled ? root.checkedIndicatorColor : root.checkedDisabledIndicatorColor)
border.color: root.checked ? checkedIndicatorBorderColor : defaultIndicatorBorderColor : root.defaultIndicatorColor
border.color: root.checked ? (root.enabled ? root.checkedIndicatorBorderColor : root.checkedDisabledIndicatorBorderColor)
: root.defaultIndicatorBorderColor
Behavior on color { Behavior on color {
PropertyAnimation { duration: 200 } PropertyAnimation { duration: 200 }
@ -51,7 +65,8 @@ Switch {
width: root.checked ? 24 : 16 width: root.checked ? 24 : 16
height: root.checked ? 24 : 16 height: root.checked ? 24 : 16
radius: 23 radius: 23
color: root.checked ? checkedInnerCircleColor : defaultInnerCircleColor color: root.checked ? (root.enabled ? root.checkedInnerCircleColor : root.checkedDisabledInnerCircleColor)
: (root.enabled ? root.defaultInnerCircleColor : root.defaultDisabledInnerCircleColor)
Behavior on x { Behavior on x {
PropertyAnimation { duration: 200 } PropertyAnimation { duration: 200 }
@ -63,7 +78,7 @@ Switch {
width: 40 width: 40
height: 40 height: 40
radius: 23 radius: 23
color: hovered ? hoveredIndicatorBackgroundColor : defaultIndicatorBackgroundColor color: root.hovered ? root.hoveredIndicatorBackgroundColor : root.defaultIndicatorBackgroundColor
Behavior on color { Behavior on color {
PropertyAnimation { duration: 200 } PropertyAnimation { duration: 200 }
@ -81,6 +96,7 @@ Switch {
Layout.fillWidth: true Layout.fillWidth: true
text: root.text text: root.text
color: root.enabled ? root.textColor : root.textDisabledColor
} }
CaptionTextType { CaptionTextType {
@ -88,7 +104,7 @@ Switch {
Layout.fillWidth: true Layout.fillWidth: true
color: "#878B91" color: root.enabled ? root.descriptionTextColor : root.descriptionTextDisabledColor
visible: text !== "" visible: text !== ""
} }

View file

@ -22,22 +22,14 @@ PageType {
property string borderColor: "#2C2D30" property string borderColor: "#2C2D30"
property string currentServerName property string defaultServerName: ServersModel.defaultServerName
property string currentServerHostName property string defaultServerHostName: ServersModel.defaultServerHostName
property string currentContainerName property string defaultContainerName: ContainersModel.defaultContainerName
ConnectButton { ConnectButton {
anchors.centerIn: parent anchors.centerIn: parent
} }
Connections {
target: ContainersModel
function onDefaultContainerChanged() {
root.currentContainerName = ContainersModel.getDefaultContainerName()
}
}
Connections { Connections {
target: PageController target: PageController
@ -79,7 +71,7 @@ PageType {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Header1TextType { Header1TextType {
text: root.currentServerName text: root.defaultServerName
} }
Image { Image {
@ -107,7 +99,7 @@ PageType {
} }
} }
description += root.currentContainerName + " | " + root.currentServerHostName description += root.defaultContainerName + " | " + root.defaultServerHostName
return description return description
} }
} }
@ -139,14 +131,14 @@ PageType {
Layout.topMargin: 24 Layout.topMargin: 24
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
text: root.currentServerName text: root.defaultServerName
} }
LabelTextType { LabelTextType {
Layout.bottomMargin: 24 Layout.bottomMargin: 24
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
text: root.currentServerHostName text: root.defaultServerHostName
} }
RowLayout { RowLayout {
@ -161,7 +153,7 @@ PageType {
rootButtonImageColor: "#0E0E11" rootButtonImageColor: "#0E0E11"
rootButtonBackgroundColor: "#D7D8DB" rootButtonBackgroundColor: "#D7D8DB"
text: root.currentContainerName text: root.defaultContainerName
textColor: "#0E0E11" textColor: "#0E0E11"
headerText: qsTr("Connection protocol") headerText: qsTr("Connection protocol")
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg" headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
@ -299,9 +291,6 @@ PageType {
ServersModel.currentlyProcessedIndex = index ServersModel.currentlyProcessedIndex = index
ServersModel.defaultIndex = index ServersModel.defaultIndex = index
root.currentServerName = name
root.currentServerHostName = hostName
} }
MouseArea { MouseArea {
@ -331,13 +320,6 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
} }
} }
Component.onCompleted: {
if (serversMenuContent.currentIndex === index) {
root.currentServerName = name
root.currentServerHostName = hostName
}
}
} }
} }
} }

View file

@ -425,16 +425,13 @@ PageType {
onClicked: { onClicked: {
questionDrawer.headerText = qsTr("Remove OpenVpn from server?") questionDrawer.headerText = qsTr("Remove OpenVpn from server?")
// questionDrawer.descriptionText = qsTr("")
questionDrawer.yesButtonText = qsTr("Continue") questionDrawer.yesButtonText = qsTr("Continue")
questionDrawer.noButtonText = qsTr("Cancel") questionDrawer.noButtonText = qsTr("Cancel")
questionDrawer.yesButtonFunction = function() { questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false
goToPage(PageEnum.PageDeinstalling) goToPage(PageEnum.PageDeinstalling)
ContainersModel.removeCurrentlyProcessedContainer() InstallController.removeCurrentlyProcessedContainer()
closePage()
closePage() //todo auto close to deinstall page?
} }
questionDrawer.noButtonFunction = function() { questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false

View file

@ -173,8 +173,19 @@ PageType {
textColor: "#EB5757" textColor: "#EB5757"
clickedFunction: function() { clickedFunction: function() {
ContainersModel.removeCurrentlyProcessedContainer() questionDrawer.headerText = qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName() + qsTr(" from server?")
closePage() questionDrawer.yesButtonText = qsTr("Continue")
questionDrawer.noButtonText = qsTr("Cancel")
questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false
goToPage(PageEnum.PageDeinstalling)
InstallController.removeCurrentlyProcessedContainer()
}
questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false
}
questionDrawer.visible = true
} }
MouseArea { MouseArea {
@ -186,5 +197,9 @@ PageType {
DividerType {} DividerType {}
} }
QuestionDrawer {
id: questionDrawer
}
} }
} }

View file

@ -258,9 +258,7 @@ PageType {
questionDrawer.yesButtonFunction = function() { questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false
goToPage(PageEnum.PageDeinstalling) goToPage(PageEnum.PageDeinstalling)
ContainersModel.removeCurrentlyProcessedContainer() InstallController.removeCurrentlyProcessedContainer()
closePage()
closePage() //todo auto close to deinstall page?
} }
questionDrawer.noButtonFunction = function() { questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false

View file

@ -150,9 +150,7 @@ PageType {
questionDrawer.yesButtonFunction = function() { questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false
goToPage(PageEnum.PageDeinstalling) goToPage(PageEnum.PageDeinstalling)
ContainersModel.removeCurrentlyProcessedContainer() InstallController.removeCurrentlyProcessedContainer()
closePage()
closePage() //todo auto close to deinstall page?
} }
questionDrawer.noButtonFunction = function() { questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false

View file

@ -92,6 +92,7 @@ PageType {
questionDrawer.yesButtonFunction = function() { questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false
SettingsController.clearSettings() SettingsController.clearSettings()
PageController.replaceStartPage()
} }
questionDrawer.noButtonFunction = function() { questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false

View file

@ -12,6 +12,20 @@ import "../Controls2/TextTypes"
PageType { PageType {
id: root id: root
Connections {
target: SettingsController
function onChangeSettingsErrorOccurred(errorMessage) {
PageController.showErrorMessage(errorMessage)
}
function onRestoreBackupFinished() {
PageController.showNotificationMessage(qsTr("Settings restored from backup file"))
goToStartPage()
PageController.goToPageHome()
}
}
BackButtonType { BackButtonType {
id: backButton id: backButton
@ -66,7 +80,9 @@ PageType {
text: qsTr("Make a backup") text: qsTr("Make a backup")
onClicked: { onClicked: {
PageController.showBusyIndicator(true)
SettingsController.backupAppConfig() SettingsController.backupAppConfig()
PageController.showBusyIndicator(false)
} }
} }
@ -84,7 +100,9 @@ PageType {
text: qsTr("Restore from backup") text: qsTr("Restore from backup")
onClicked: { onClicked: {
PageController.showBusyIndicator(true)
SettingsController.restoreAppConfig() SettingsController.restoreAppConfig()
PageController.showBusyIndicator(false)
} }
} }
} }

View file

@ -55,6 +55,9 @@ PageType {
headerText: "Primary DNS" headerText: "Primary DNS"
textFieldText: SettingsController.primaryDns textFieldText: SettingsController.primaryDns
textField.validator: RegularExpressionValidator {
regularExpression: InstallController.ipAddressRegExp()
}
} }
TextFieldWithHeaderType { TextFieldWithHeaderType {
@ -64,6 +67,9 @@ PageType {
headerText: "Secondary DNS" headerText: "Secondary DNS"
textFieldText: SettingsController.secondaryDns textFieldText: SettingsController.secondaryDns
textField.validator: RegularExpressionValidator {
regularExpression: InstallController.ipAddressRegExp()
}
} }
BasicButtonType { BasicButtonType {

View file

@ -27,6 +27,32 @@ PageType {
PageController.showErrorMessage(message) PageController.showErrorMessage(message)
} }
function onInstallationErrorOccurred(errorMessage) {
closePage() // close deInstalling page
PageController.showErrorMessage(errorMessage)
}
function onRemoveCurrentlyProcessedServerFinished(finishedMessage) {
if (!ServersModel.getServersCount()) {
PageController.replaceStartPage()
} else {
goToStartPage()
goToPage(PageEnum.PageSettingsServersList)
}
PageController.showNotificationMessage(finishedMessage)
}
function onRemoveAllContainersFinished(finishedMessage) {
closePage() // close deInstalling page
PageController.showNotificationMessage(finishedMessage)
}
function onRemoveCurrentlyProcessedContainerFinished(finishedMessage) {
closePage() // close deInstalling page
closePage() // close page with remove button
PageController.showNotificationMessage(finishedMessage)
}
} }
Connections { Connections {
@ -112,16 +138,12 @@ PageType {
questionDrawer.yesButtonFunction = function() { questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false
PageController.showBusyIndicator(true)
if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected) { if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected) {
ConnectionController.closeConnection() ConnectionController.closeConnection()
} }
ServersModel.removeServer() InstallController.removeCurrentlyProcessedServer()
if (!ServersModel.getServersCount()) { PageController.showBusyIndicator(false)
PageController.replaceStartPage()
} else {
goToStartPage()
goToPage(PageEnum.PageSettingsServersList)
}
} }
questionDrawer.noButtonFunction = function() { questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false
@ -151,8 +173,7 @@ PageType {
if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected) { if (ServersModel.isDefaultServerCurrentlyProcessed && ConnectionController.isConnected) {
ConnectionController.closeVpnConnection() ConnectionController.closeVpnConnection()
} }
ContainersModel.removeAllContainers() InstallController.removeAllContainers()
closePage()
} }
questionDrawer.noButtonFunction = function() { questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false questionDrawer.visible = false

View file

@ -93,6 +93,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
headerText: qsTr("Server name") headerText: qsTr("Server name")
textFieldText: name textFieldText: name
textField.maximumLength: 20
} }
BasicButtonType { BasicButtonType {

View file

@ -81,13 +81,12 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg" rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() { clickedFunction: function() {
var containerIndex = ContainersModel.getCurrentlyProcessedContainerIndex() switch (protocolIndex) {
switch (containerIndex) { case ProtocolEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ContainerEnum.OpenVpn: OpenVpnConfigModel.updateModel(ProtocolsModel.getConfig()); break; case ProtocolEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ContainerEnum.ShadowSocks: ShadowSocksConfigModel.updateModel(ProtocolsModel.getConfig()); break; case ProtocolEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ContainerEnum.Cloak: CloakConfigModel.updateModel(ProtocolsModel.getConfig()); break; case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ContainerEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break; case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
case ContainerEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
} }
goToPage(protocolPage); goToPage(protocolPage);
} }
@ -113,8 +112,19 @@ PageType {
textColor: "#EB5757" textColor: "#EB5757"
clickedFunction: function() { clickedFunction: function() {
ContainersModel.removeCurrentlyProcessedContainer() questionDrawer.headerText = qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName() + qsTr(" from server?")
closePage() questionDrawer.yesButtonText = qsTr("Continue")
questionDrawer.noButtonText = qsTr("Cancel")
questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false
goToPage(PageEnum.PageDeinstalling)
InstallController.removeCurrentlyProcessedContainer()
}
questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false
}
questionDrawer.visible = true
} }
MouseArea { MouseArea {
@ -126,5 +136,9 @@ PageType {
DividerType {} DividerType {}
} }
QuestionDrawer {
id: questionDrawer
}
} }
} }

View file

@ -22,7 +22,7 @@ PageType {
PageController.showErrorMessage(errorMessage) PageController.showErrorMessage(errorMessage)
} }
function onInstallContainerFinished(isInstalledContainerFound) { function onInstallContainerFinished(finishedMessage) {
goToStartPage() goToStartPage()
if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) { if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) {
PageController.restorePageHomeState(true) PageController.restorePageHomeState(true)
@ -33,14 +33,10 @@ PageType {
goToPage(PageEnum.PageHome) goToPage(PageEnum.PageHome)
} }
if (isInstalledContainerFound) { PageController.showNotificationMessage(finishedMessage)
//todo change to info message
PageController.showErrorMessage(qsTr("The container you are trying to install is already installed on the server. " +
"All installed containers have been added to the application"))
}
} }
function onInstallServerFinished(isInstalledContainerFound) { function onInstallServerFinished(finishedMessage) {
goToStartPage() goToStartPage()
if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) { if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) {
PageController.restorePageHomeState() PageController.restorePageHomeState()
@ -50,10 +46,7 @@ PageType {
PageController.replaceStartPage() PageController.replaceStartPage()
} }
if (isInstalledContainerFound) { PageController.showNotificationMessage(finishedMessage)
PageController.showErrorMessage(qsTr("The container you are trying to install is already installed on the server. " +
"All installed containers have been added to the application"))
}
} }
function onServerAlreadyExists(serverIndex) { function onServerAlreadyExists(serverIndex) {

View file

@ -123,15 +123,16 @@ PageType {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
contentHeight: { contentHeight: {
var emptySpaceHeight = parent.height - showDetailsBackButton.implicitHeight - showDetailsBackButton.anchors.topMargin var emptySpaceHeight = parent.height - showDetailsBackButton.implicitHeight - showDetailsBackButton.anchors.topMargin
return (showDetailsDrawerContent.height > emptySpaceHeight) ?
return (showDetailsDrawerContent.implicitHeight > emptySpaceHeight) ? showDetailsDrawerContent.height : emptySpaceHeight
showDetailsDrawerContent.implicitHeight : emptySpaceHeight
} }
ColumnLayout { ColumnLayout {
id: showDetailsDrawerContent id: showDetailsDrawerContent
anchors.fill: parent anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 16 anchors.rightMargin: 16
anchors.leftMargin: 16 anchors.leftMargin: 16

View file

@ -16,11 +16,6 @@ PageType {
Connections { Connections {
target: PageController target: PageController
function onShowErrorMessage(errorMessage) {
popupErrorMessage.popupErrorMessageText = errorMessage
popupErrorMessage.open()
}
function onGoToPageViewConfig() { function onGoToPageViewConfig() {
goToPage(PageEnum.PageSetupWizardViewConfig) goToPage(PageEnum.PageSetupWizardViewConfig)
} }
@ -98,16 +93,4 @@ PageType {
id: connectionTypeSelection id: connectionTypeSelection
} }
} }
Item {
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
implicitHeight: popupErrorMessage.height
PopupType {
id: popupErrorMessage
}
}
} }

View file

@ -58,7 +58,7 @@ PageType {
property string fullConfigServerSelectorText property string fullConfigServerSelectorText
property string connectionServerSelectorText property string connectionServerSelectorText
property bool showContent: false property bool showContent: false
property bool shareButtonEnabled: false property bool shareButtonEnabled: true
property list<QtObject> connectionTypesModel: [ property list<QtObject> connectionTypesModel: [
amneziaConnectionFormat amneziaConnectionFormat
] ]
@ -140,6 +140,7 @@ PageType {
onClicked: { onClicked: {
accessTypeSelector.currentIndex = 1 accessTypeSelector.currentIndex = 1
serverSelector.text = root.fullConfigServerSelectorText serverSelector.text = root.fullConfigServerSelectorText
root.shareButtonEnabled = true
} }
} }
} }

View file

@ -31,11 +31,6 @@ PageType {
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition) tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.PushTransition)
} }
function onShowErrorMessage(errorMessage) {
popupErrorMessage.popupErrorMessageText = errorMessage
popupErrorMessage.open()
}
function onShowBusyIndicator(visible) { function onShowBusyIndicator(visible) {
busyIndicator.visible = visible busyIndicator.visible = visible
tabBarStackView.enabled = !visible tabBarStackView.enabled = !visible
@ -119,14 +114,15 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onDefaultServerIndexChanged() { function onModelReset() {
shareTabButton.visible = ServersModel.isCurrentlyProcessedServerHasWriteAccess() var hasServerWithWriteAccess = ServersModel.hasServerWithWriteAccess()
shareTabButton.width = ServersModel.isCurrentlyProcessedServerHasWriteAccess() ? undefined : 0 shareTabButton.visible = hasServerWithWriteAccess
shareTabButton.width = hasServerWithWriteAccess ? undefined : 0
} }
} }
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess() visible: ServersModel.hasServerWithWriteAccess()
width: ServersModel.isCurrentlyProcessedServerHasWriteAccess() ? undefined : 0 width: ServersModel.hasServerWithWriteAccess() ? undefined : 0
isSelected: tabBar.currentIndex === 1 isSelected: tabBar.currentIndex === 1
image: "qrc:/images/controls/share-2.svg" image: "qrc:/images/controls/share-2.svg"
@ -151,18 +147,6 @@ PageType {
enabled: false enabled: false
} }
Item {
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
implicitHeight: popupErrorMessage.height
PopupType {
id: popupErrorMessage
}
}
BusyIndicatorType { BusyIndicatorType {
id: busyIndicator id: busyIndicator
anchors.centerIn: parent anchors.centerIn: parent

View file

@ -63,5 +63,52 @@ Window {
function onHideMainWindow() { function onHideMainWindow() {
root.hide() root.hide()
} }
function onShowErrorMessage(errorMessage) {
popupErrorMessage.text = errorMessage
popupErrorMessage.open()
}
function onShowNotificationMessage(message) {
popupNotificationMessage.text = message
popupNotificationMessage.closeButtonVisible = false
popupNotificationMessage.open()
popupNotificationTimer.start()
}
}
Item {
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
implicitHeight: popupNotificationMessage.height
PopupType {
id: popupNotificationMessage
}
Timer {
id: popupNotificationTimer
interval: 3000
repeat: false
running: false
onTriggered: {
popupNotificationMessage.close()
}
}
}
Item {
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
implicitHeight: popupErrorMessage.height
PopupType {
id: popupErrorMessage
}
} }
} }