added pages for sftp and tor website settings
This commit is contained in:
parent
75489c00c2
commit
5d677a9115
22 changed files with 713 additions and 6 deletions
|
@ -129,8 +129,16 @@ file(GLOB_RECURSE PAGE_LOGIC_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/
|
||||||
file(GLOB CONFIGURATORS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.h)
|
file(GLOB CONFIGURATORS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.h)
|
||||||
file(GLOB CONFIGURATORS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.cpp)
|
file(GLOB CONFIGURATORS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/configurators/*.cpp)
|
||||||
|
|
||||||
file(GLOB UI_MODELS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/models/*.h ${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.h)
|
file(GLOB UI_MODELS_H CONFIGURE_DEPENDS
|
||||||
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/models/*.cpp ${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.cpp)
|
${CMAKE_CURRENT_LIST_DIR}/ui/models/*.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.h
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/ui/models/services/*.h
|
||||||
|
)
|
||||||
|
file(GLOB UI_MODELS_CPP CONFIGURE_DEPENDS
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/ui/models/*.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/ui/models/protocols/*.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/ui/models/services/*.cpp
|
||||||
|
)
|
||||||
|
|
||||||
file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.h)
|
file(GLOB UI_CONTROLLERS_H CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.h)
|
||||||
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.cpp)
|
file(GLOB UI_CONTROLLERS_CPP CONFIGURE_DEPENDS ${CMAKE_CURRENT_LIST_DIR}/ui/controllers/*.cpp)
|
||||||
|
|
|
@ -267,6 +267,9 @@ void AmneziaApplication::initModels()
|
||||||
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
m_ikev2ConfigModel.reset(new Ikev2ConfigModel(this));
|
||||||
m_engine->rootContext()->setContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel.get());
|
m_engine->rootContext()->setContextProperty("Ikev2ConfigModel", m_ikev2ConfigModel.get());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
m_sftpConfigModel.reset(new SftpConfigModel(this));
|
||||||
|
m_engine->rootContext()->setContextProperty("SftpConfigModel", m_sftpConfigModel.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmneziaApplication::initControllers()
|
void AmneziaApplication::initControllers()
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "ui/models/protocols/wireguardConfigModel.h"
|
#include "ui/models/protocols/wireguardConfigModel.h"
|
||||||
#include "ui/models/protocols_model.h"
|
#include "ui/models/protocols_model.h"
|
||||||
#include "ui/models/servers_model.h"
|
#include "ui/models/servers_model.h"
|
||||||
|
#include "ui/models/services/sftpConfigModel.h"
|
||||||
|
|
||||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||||
|
|
||||||
|
@ -91,6 +92,8 @@ private:
|
||||||
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
QScopedPointer<Ikev2ConfigModel> m_ikev2ConfigModel;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QScopedPointer<SftpConfigModel> m_sftpConfigModel;
|
||||||
|
|
||||||
QSharedPointer<VpnConnection> m_vpnConnection;
|
QSharedPointer<VpnConnection> m_vpnConnection;
|
||||||
QScopedPointer<NotificationHandler> m_notificationHandler;
|
QScopedPointer<NotificationHandler> m_notificationHandler;
|
||||||
|
|
||||||
|
|
4
client/images/controls/copy.svg
Normal file
4
client/images/controls/copy.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20 9H11C9.89543 9 9 9.89543 9 11V20C9 21.1046 9.89543 22 11 22H20C21.1046 22 22 21.1046 22 20V11C22 9.89543 21.1046 9 20 9Z" stroke="#CBCBCB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M5 15H4C3.46957 15 2.96086 14.7893 2.58579 14.4142C2.21071 14.0391 2 13.5304 2 13V4C2 3.46957 2.21071 2.96086 2.58579 2.58579C2.96086 2.21071 3.46957 2 4 2H13C13.5304 2 14.0391 2.21071 14.4142 2.58579C14.7893 2.96086 15 3.46957 15 4V5" stroke="#CBCBCB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 649 B |
|
@ -65,6 +65,7 @@ namespace amnezia
|
||||||
constexpr char wireguard[] = "wireguard";
|
constexpr char wireguard[] = "wireguard";
|
||||||
constexpr char shadowsocks[] = "shadowsocks";
|
constexpr char shadowsocks[] = "shadowsocks";
|
||||||
constexpr char cloak[] = "cloak";
|
constexpr char cloak[] = "cloak";
|
||||||
|
constexpr char sftp[] = "sftp";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,5 +275,8 @@
|
||||||
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
|
<file>ui/qml/Pages2/PageProtocolCloakSettings.qml</file>
|
||||||
<file>ui/qml/Pages2/PageProtocolRaw.qml</file>
|
<file>ui/qml/Pages2/PageProtocolRaw.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
|
<file>ui/qml/Pages2/PageSettingsLogging.qml</file>
|
||||||
|
<file>ui/qml/Pages2/PageServiceSftpSettings.qml</file>
|
||||||
|
<file>images/controls/copy.svg</file>
|
||||||
|
<file>ui/qml/Pages2/PageServiceTorWebsiteSettings.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#include "installController.h"
|
#include "installController.h"
|
||||||
|
|
||||||
|
#include <QDesktopServices>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "core/errorstrings.h"
|
#include "core/errorstrings.h"
|
||||||
#include "core/servercontroller.h"
|
#include "core/servercontroller.h"
|
||||||
|
@ -214,3 +216,80 @@ void InstallController::setShouldCreateServer(bool shouldCreateServer)
|
||||||
{
|
{
|
||||||
m_shouldCreateServer = shouldCreateServer;
|
m_shouldCreateServer = shouldCreateServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InstallController::mountSftpDrive(const QString &port, const QString &password, const QString &username)
|
||||||
|
{
|
||||||
|
QString mountPath;
|
||||||
|
QString cmd;
|
||||||
|
|
||||||
|
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
|
||||||
|
ServerCredentials serverCredentials =
|
||||||
|
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
|
||||||
|
QString hostname = serverCredentials.hostName;
|
||||||
|
|
||||||
|
#ifdef Q_OS_WINDOWS
|
||||||
|
mountPath = getNextDriverLetter() + ":";
|
||||||
|
// QString cmd = QString("net use \\\\sshfs\\%1@x.x.x.x!%2 /USER:%1 %3")
|
||||||
|
// .arg(labelTftpUserNameText())
|
||||||
|
// .arg(labelTftpPortText())
|
||||||
|
// .arg(labelTftpPasswordText());
|
||||||
|
|
||||||
|
cmd = "C:\\Program Files\\SSHFS-Win\\bin\\sshfs.exe";
|
||||||
|
#elif defined AMNEZIA_DESKTOP
|
||||||
|
mountPath =
|
||||||
|
QString("%1/sftp:%2:%3").arg(QStandardPaths::writableLocation(QStandardPaths::HomeLocation), hostname, port);
|
||||||
|
QDir dir(mountPath);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkpath(mountPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd = "/usr/local/bin/sshfs";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef AMNEZIA_DESKTOP
|
||||||
|
QSharedPointer<QProcess> process;
|
||||||
|
process.reset(new QProcess());
|
||||||
|
m_sftpMountProcesses.append(process);
|
||||||
|
process->setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
|
connect(process.get(), &QProcess::readyRead, this, [this, process, mountPath]() {
|
||||||
|
QString s = process->readAll();
|
||||||
|
if (s.contains("The service sshfs has been started")) {
|
||||||
|
QDesktopServices::openUrl(QUrl("file:///" + mountPath));
|
||||||
|
}
|
||||||
|
qDebug() << s;
|
||||||
|
});
|
||||||
|
|
||||||
|
process->setProgram(cmd);
|
||||||
|
|
||||||
|
QString args = QString("%1@%2:/ %3 "
|
||||||
|
"-o port=%4 "
|
||||||
|
"-f "
|
||||||
|
"-o reconnect "
|
||||||
|
"-o rellinks "
|
||||||
|
"-o fstypename=SSHFS "
|
||||||
|
"-o ssh_command=/usr/bin/ssh.exe "
|
||||||
|
"-o UserKnownHostsFile=/dev/null "
|
||||||
|
"-o StrictHostKeyChecking=no "
|
||||||
|
"-o password_stdin")
|
||||||
|
.arg(username, hostname, mountPath, port);
|
||||||
|
|
||||||
|
// args.replace("\n", " ");
|
||||||
|
// args.replace("\r", " ");
|
||||||
|
// #ifndef Q_OS_WIN
|
||||||
|
// args.replace("reconnect-orellinks", "");
|
||||||
|
// #endif
|
||||||
|
process->setArguments(args.split(" ", Qt::SkipEmptyParts));
|
||||||
|
process->start();
|
||||||
|
process->waitForStarted(50);
|
||||||
|
if (process->state() != QProcess::Running) {
|
||||||
|
qDebug() << "onPushButtonSftpMountDriveClicked process not started";
|
||||||
|
qDebug() << args;
|
||||||
|
} else {
|
||||||
|
process->write((password + "\n").toUtf8());
|
||||||
|
}
|
||||||
|
|
||||||
|
// qDebug().noquote() << "onPushButtonSftpMountDriveClicked" << args;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define INSTALLCONTROLLER_H
|
#define INSTALLCONTROLLER_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#include "containers/containers_defs.h"
|
#include "containers/containers_defs.h"
|
||||||
#include "core/defs.h"
|
#include "core/defs.h"
|
||||||
|
@ -28,6 +29,8 @@ public slots:
|
||||||
|
|
||||||
QRegularExpression ipAddressPortRegExp();
|
QRegularExpression ipAddressPortRegExp();
|
||||||
|
|
||||||
|
void mountSftpDrive(const QString &port, const QString &password, const QString &username);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void installContainerFinished(bool isInstalledContainerFound);
|
void installContainerFinished(bool isInstalledContainerFound);
|
||||||
void installServerFinished(bool isInstalledContainerFound);
|
void installServerFinished(bool isInstalledContainerFound);
|
||||||
|
@ -52,6 +55,8 @@ private:
|
||||||
ServerCredentials m_currentlyInstalledServerCredentials;
|
ServerCredentials m_currentlyInstalledServerCredentials;
|
||||||
|
|
||||||
bool m_shouldCreateServer;
|
bool m_shouldCreateServer;
|
||||||
|
|
||||||
|
QList<QSharedPointer<QProcess>> m_sftpMountProcesses;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // INSTALLCONTROLLER_H
|
#endif // INSTALLCONTROLLER_H
|
||||||
|
|
|
@ -29,6 +29,9 @@ namespace PageLoader
|
||||||
PageSettingsAbout,
|
PageSettingsAbout,
|
||||||
PageSettingsLogging,
|
PageSettingsLogging,
|
||||||
|
|
||||||
|
PageServiceSftpSettings,
|
||||||
|
PageServiceTorWebsiteSettings,
|
||||||
|
|
||||||
PageSetupWizardStart,
|
PageSetupWizardStart,
|
||||||
PageSetupWizardCredentials,
|
PageSetupWizardCredentials,
|
||||||
PageSetupWizardProtocols,
|
PageSetupWizardProtocols,
|
||||||
|
|
|
@ -118,6 +118,11 @@ QString ContainersModel::getCurrentlyProcessedContainerName()
|
||||||
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_currentlyProcessedContainerIndex));
|
return ContainerProps::containerHumanNames().value(static_cast<DockerContainer>(m_currentlyProcessedContainerIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonObject ContainersModel::getCurrentlyProcessedContainerConfig()
|
||||||
|
{
|
||||||
|
return qvariant_cast<QJsonObject>(data(index(m_currentlyProcessedContainerIndex), ConfigRole));
|
||||||
|
}
|
||||||
|
|
||||||
void ContainersModel::removeAllContainers()
|
void ContainersModel::removeAllContainers()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ public slots:
|
||||||
int getCurrentlyProcessedContainerIndex();
|
int getCurrentlyProcessedContainerIndex();
|
||||||
|
|
||||||
QString getCurrentlyProcessedContainerName();
|
QString getCurrentlyProcessedContainerName();
|
||||||
|
QJsonObject getCurrentlyProcessedContainerConfig();
|
||||||
|
|
||||||
void removeAllContainers();
|
void removeAllContainers();
|
||||||
void removeCurrentlyProcessedContainer();
|
void removeCurrentlyProcessedContainer();
|
||||||
|
|
|
@ -106,6 +106,11 @@ int ServersModel::getCurrentlyProcessedServerIndex()
|
||||||
return m_currentlyProcessedServerIndex;
|
return m_currentlyProcessedServerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ServersModel::getCurrentlyProcessedServerHostName()
|
||||||
|
{
|
||||||
|
return qvariant_cast<QString>(data(m_currentlyProcessedServerIndex, HostNameRole));
|
||||||
|
}
|
||||||
|
|
||||||
bool ServersModel::isDefaultServerCurrentlyProcessed()
|
bool ServersModel::isDefaultServerCurrentlyProcessed()
|
||||||
{
|
{
|
||||||
return m_defaultServerIndex == m_currentlyProcessedServerIndex;
|
return m_defaultServerIndex == m_currentlyProcessedServerIndex;
|
||||||
|
|
|
@ -45,6 +45,8 @@ public slots:
|
||||||
void setCurrentlyProcessedServerIndex(const int index);
|
void setCurrentlyProcessedServerIndex(const int index);
|
||||||
int getCurrentlyProcessedServerIndex();
|
int getCurrentlyProcessedServerIndex();
|
||||||
|
|
||||||
|
QString getCurrentlyProcessedServerHostName();
|
||||||
|
|
||||||
void addServer(const QJsonObject &server);
|
void addServer(const QJsonObject &server);
|
||||||
void removeServer();
|
void removeServer();
|
||||||
|
|
||||||
|
|
64
client/ui/models/services/sftpConfigModel.cpp
Normal file
64
client/ui/models/services/sftpConfigModel.cpp
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
#include "sftpConfigModel.h"
|
||||||
|
|
||||||
|
#include "protocols/protocols_defs.h"
|
||||||
|
|
||||||
|
SftpConfigModel::SftpConfigModel(QObject *parent) : QAbstractListModel(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int SftpConfigModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SftpConfigModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid() || index.row() < 0 || index.row() >= rowCount()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
|
||||||
|
case Roles::UserNameRole:
|
||||||
|
return m_protocolConfig.value(config_key::userName).toString(protocols::sftp::defaultUserName);
|
||||||
|
case Roles::PasswordRole: return m_protocolConfig.value(config_key::password).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SftpConfigModel::updateModel(const QJsonObject &config)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
m_container = ContainerProps::containerFromString(config.value(config_key::container).toString());
|
||||||
|
|
||||||
|
m_fullConfig = config;
|
||||||
|
QJsonObject protocolConfig = config.value(config_key::sftp).toObject();
|
||||||
|
|
||||||
|
m_protocolConfig.insert(config_key::userName,
|
||||||
|
protocolConfig.value(config_key::userName).toString(protocols::sftp::defaultUserName));
|
||||||
|
|
||||||
|
m_protocolConfig.insert(config_key::password, protocolConfig.value(config_key::password).toString());
|
||||||
|
|
||||||
|
m_protocolConfig.insert(config_key::port, protocolConfig.value(config_key::port).toString());
|
||||||
|
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject SftpConfigModel::getConfig()
|
||||||
|
{
|
||||||
|
m_fullConfig.insert(config_key::sftp, m_protocolConfig);
|
||||||
|
return m_fullConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHash<int, QByteArray> SftpConfigModel::roleNames() const
|
||||||
|
{
|
||||||
|
QHash<int, QByteArray> roles;
|
||||||
|
|
||||||
|
roles[PortRole] = "port";
|
||||||
|
roles[UserNameRole] = "username";
|
||||||
|
roles[PasswordRole] = "password";
|
||||||
|
|
||||||
|
return roles;
|
||||||
|
}
|
39
client/ui/models/services/sftpConfigModel.h
Normal file
39
client/ui/models/services/sftpConfigModel.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef SFTPCONFIGMODEL_H
|
||||||
|
#define SFTPCONFIGMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractListModel>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
|
#include "containers/containers_defs.h"
|
||||||
|
|
||||||
|
class SftpConfigModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum Roles {
|
||||||
|
PortRole = Qt::UserRole + 1,
|
||||||
|
UserNameRole,
|
||||||
|
PasswordRole
|
||||||
|
};
|
||||||
|
|
||||||
|
explicit SftpConfigModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void updateModel(const QJsonObject &config);
|
||||||
|
QJsonObject getConfig();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
DockerContainer m_container;
|
||||||
|
QJsonObject m_protocolConfig;
|
||||||
|
QJsonObject m_fullConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SFTPCONFIGMODEL_H
|
|
@ -92,6 +92,7 @@ ListView {
|
||||||
if (isInstalled) {
|
if (isInstalled) {
|
||||||
var containerIndex = root.model.mapToSource(index)
|
var containerIndex = root.model.mapToSource(index)
|
||||||
ContainersModel.setCurrentlyProcessedContainerIndex(containerIndex)
|
ContainersModel.setCurrentlyProcessedContainerIndex(containerIndex)
|
||||||
|
|
||||||
if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
|
if (config[ContainerProps.containerTypeToString(containerIndex)]["isThirdPartyConfig"]) {
|
||||||
ProtocolsModel.updateModel(config)
|
ProtocolsModel.updateModel(config)
|
||||||
goToPage(PageEnum.PageProtocolRaw)
|
goToPage(PageEnum.PageProtocolRaw)
|
||||||
|
@ -114,6 +115,16 @@ ListView {
|
||||||
goToPage(PageEnum.PageProtocolIKev2Settings)
|
goToPage(PageEnum.PageProtocolIKev2Settings)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case ContainerEnum.Sftp: {
|
||||||
|
SftpConfigModel.updateModel(config)
|
||||||
|
goToPage(PageEnum.PageServiceSftpSettings)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case ContainerEnum.TorWebSite: {
|
||||||
|
goToPage(PageEnum.PageServiceTorWebsiteSettings)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
if (serviceType !== ProtocolEnum.Other) { //todo disable settings for dns container
|
if (serviceType !== ProtocolEnum.Other) { //todo disable settings for dns container
|
||||||
ProtocolsModel.updateModel(config)
|
ProtocolsModel.updateModel(config)
|
||||||
|
|
|
@ -16,6 +16,10 @@ Item {
|
||||||
property string leftImageSource
|
property string leftImageSource
|
||||||
|
|
||||||
property string textColor: "#d7d8db"
|
property string textColor: "#d7d8db"
|
||||||
|
property string descriptionColor: "#878B91"
|
||||||
|
property string rightImageColor: "#878B91"
|
||||||
|
|
||||||
|
property bool descriptionOnTop: false
|
||||||
|
|
||||||
implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
|
implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
|
||||||
implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
|
implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
|
||||||
|
@ -53,26 +57,41 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
property real textLineHeight: 21.6
|
||||||
|
property real descriptionTextLineHeight: 16
|
||||||
|
|
||||||
|
property int textPixelSize: 18
|
||||||
|
property int descriptionTextSize: 13
|
||||||
|
|
||||||
ListItemTitleType {
|
ListItemTitleType {
|
||||||
text: root.text
|
text: root.text
|
||||||
color: root.textColor
|
color: root.descriptionOnTop ? root.descriptionColor : root.textColor
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
lineHeight: root.descriptionOnTop ? parent.descriptionTextLineHeight : parent.textLineHeight
|
||||||
|
font.pixelSize: root.descriptionOnTop ? parent.descriptionTextSize : parent.textPixelSize
|
||||||
|
font.letterSpacing: root.descriptionOnTop ? 0.02 : 0
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CaptionTextType {
|
CaptionTextType {
|
||||||
id: description
|
id: description
|
||||||
|
|
||||||
color: "#878B91"
|
color: root.descriptionOnTop ? root.textColor : root.descriptionColor
|
||||||
text: root.descriptionText
|
text: root.descriptionText
|
||||||
|
|
||||||
visible: root.descriptionText !== ""
|
visible: root.descriptionText !== ""
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
lineHeight: root.descriptionOnTop ? parent.textLineHeight : parent.descriptionTextLineHeight
|
||||||
|
font.pixelSize: root.descriptionOnTop ? parent.textPixelSize : parent.descriptionTextSize
|
||||||
|
font.letterSpacing: root.descriptionOnTop ? 0 : 0.02
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
}
|
}
|
||||||
|
@ -83,6 +102,7 @@ Item {
|
||||||
|
|
||||||
hoverEnabled: false
|
hoverEnabled: false
|
||||||
image: rightImageSource
|
image: rightImageSource
|
||||||
|
imageColor: rightImageColor
|
||||||
visible: rightImageSource ? true : false
|
visible: rightImageSource ? true : false
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
|
@ -10,5 +10,5 @@ Text {
|
||||||
font.family: "PT Root UI VF"
|
font.family: "PT Root UI VF"
|
||||||
font.letterSpacing: 0.02
|
font.letterSpacing: 0.02
|
||||||
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.Wrap
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,5 @@ Text {
|
||||||
font.weight: 400
|
font.weight: 400
|
||||||
font.family: "PT Root UI VF"
|
font.family: "PT Root UI VF"
|
||||||
|
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.Wrap
|
||||||
}
|
}
|
||||||
|
|
|
@ -413,6 +413,8 @@ PageType {
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
|
Layout.leftMargin: -8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
defaultColor: "transparent"
|
defaultColor: "transparent"
|
||||||
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
|
280
client/ui/qml/Pages2/PageServiceSftpSettings.qml
Normal file
280
client/ui/qml/Pages2/PageServiceSftpSettings.qml
Normal file
|
@ -0,0 +1,280 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
|
||||||
|
import "./"
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Controls2/TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
import "../Components"
|
||||||
|
|
||||||
|
PageType {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
//todo move to main?
|
||||||
|
Connections {
|
||||||
|
target: InstallController
|
||||||
|
|
||||||
|
function onInstallationErrorOccurred(errorMessage) {
|
||||||
|
PageController.showErrorMessage(errorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUpdateContainerFinished() {
|
||||||
|
//todo change to notification
|
||||||
|
PageController.showErrorMessage(qsTr("Settings updated successfully"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlickableType {
|
||||||
|
id: fl
|
||||||
|
anchors.top: backButton.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: listview
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: listview.contentItem.height
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
interactive: false
|
||||||
|
|
||||||
|
model: SftpConfigModel
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
implicitWidth: listview.width
|
||||||
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: col
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
HeaderType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("SFTP settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 32
|
||||||
|
|
||||||
|
text: qsTr("Host")
|
||||||
|
descriptionText: ServersModel.getCurrentlyProcessedServerHostName()
|
||||||
|
|
||||||
|
descriptionOnTop: true
|
||||||
|
|
||||||
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
col.copyToClipBoard(descriptionText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: qsTr("Port")
|
||||||
|
descriptionText: port
|
||||||
|
|
||||||
|
descriptionOnTop: true
|
||||||
|
|
||||||
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
col.copyToClipBoard(descriptionText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: qsTr("Login")
|
||||||
|
descriptionText: username
|
||||||
|
|
||||||
|
descriptionOnTop: true
|
||||||
|
|
||||||
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
col.copyToClipBoard(descriptionText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: qsTr("Password")
|
||||||
|
descriptionText: password
|
||||||
|
|
||||||
|
descriptionOnTop: true
|
||||||
|
|
||||||
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
col.copyToClipBoard(descriptionText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEdit{
|
||||||
|
id: clipboard
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToClipBoard(text) {
|
||||||
|
clipboard.text = text
|
||||||
|
clipboard.selectAll()
|
||||||
|
clipboard.copy()
|
||||||
|
clipboard.select(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.bottomMargin: 24
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
disabledColor: "#878B91"
|
||||||
|
textColor: "#D7D8DB"
|
||||||
|
borderWidth: 1
|
||||||
|
|
||||||
|
text: qsTr("Mount folder on device")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
PageController.showBusyIndicator(true)
|
||||||
|
InstallController.mountSftpDrive(port, password, username)
|
||||||
|
PageController.showBusyIndicator(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
readonly property string windowsFirstLink: "<a href=\"https://github.com/billziss-gh/winfsp/releases/latest\" style=\"color: #FBB26A;\">WinFsp</a>"
|
||||||
|
readonly property string windowsSecondLink: "<a href=\"https://github.com/billziss-gh/sshfs-win/releases\" style=\"color: #FBB26A;\">SSHFS-Win</a>"
|
||||||
|
|
||||||
|
readonly property string macosFirstLink: "<a href=\"https://osxfuse.github.io/\" style=\"color: #FBB26A;\">macFUSE</a>"
|
||||||
|
readonly property string macosSecondLink: "<a href=\"https://osxfuse.github.io/\" style=\"color: #FBB26A;\">SSHFS</a>"
|
||||||
|
|
||||||
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
textFormat: Text.RichText
|
||||||
|
text: {
|
||||||
|
var str = qsTr("In order to mount remote SFTP folder as local drive, perform following steps: <br>")
|
||||||
|
if (Qt.platform.os === "windows") {
|
||||||
|
str += qsTr("<br>1. Install the latest version of ") + windowsFirstLink + "\n"
|
||||||
|
str += qsTr("<br>2. Install the latest version of ") + windowsSecondLink + "\n"
|
||||||
|
} else if (Qt.platform.os === "osx") {
|
||||||
|
str += qsTr("<br>1. Install the latest version of ") + macosFirstLink + "\n"
|
||||||
|
str += qsTr("<br>2. Install the latest version of ") + macosSecondLink + "\n"
|
||||||
|
} else if (Qt.platform.os === "linux") {
|
||||||
|
return ""
|
||||||
|
} else return ""
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.topMargin: 16
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
disabledColor: "#878B91"
|
||||||
|
textColor: "#FBB26A"
|
||||||
|
|
||||||
|
text: qsTr("Detailed instructions")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
text: qsTr("Remove SFTP and all data stored there")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
questionDrawer.headerText = qsTr("Some description")
|
||||||
|
questionDrawer.yesButtonText = qsTr("Continue")
|
||||||
|
questionDrawer.noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
|
questionDrawer.yesButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
goToPage(PageEnum.PageDeinstalling)
|
||||||
|
ContainersModel.removeCurrentlyProcessedContainer()
|
||||||
|
closePage()
|
||||||
|
closePage() //todo auto close to deinstall page?
|
||||||
|
}
|
||||||
|
questionDrawer.noButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
}
|
||||||
|
questionDrawer.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionDrawer {
|
||||||
|
id: questionDrawer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
169
client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml
Normal file
169
client/ui/qml/Pages2/PageServiceTorWebsiteSettings.qml
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
import ContainerProps 1.0
|
||||||
|
|
||||||
|
import "./"
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Controls2/TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
import "../Components"
|
||||||
|
|
||||||
|
PageType {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
//todo move to main?
|
||||||
|
Connections {
|
||||||
|
target: InstallController
|
||||||
|
|
||||||
|
function onInstallationErrorOccurred(errorMessage) {
|
||||||
|
PageController.showErrorMessage(errorMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onUpdateContainerFinished() {
|
||||||
|
//todo change to notification
|
||||||
|
PageController.showErrorMessage(qsTr("Settings updated successfully"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlickableType {
|
||||||
|
id: fl
|
||||||
|
anchors.top: backButton.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
HeaderType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Tor website settings")
|
||||||
|
}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 32
|
||||||
|
|
||||||
|
text: qsTr("Website address")
|
||||||
|
descriptionText: {
|
||||||
|
var config = ContainersModel.getCurrentlyProcessedContainerConfig()
|
||||||
|
var containerIndex = ContainersModel.getCurrentlyProcessedContainerIndex()
|
||||||
|
return config[ContainerProps.containerTypeToString(containerIndex)]["site"]
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptionOnTop: true
|
||||||
|
textColor: "#FBB26A"
|
||||||
|
|
||||||
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
content.copyToClipBoard(descriptionText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextEdit{
|
||||||
|
id: clipboard
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToClipBoard(text) {
|
||||||
|
clipboard.text = text
|
||||||
|
clipboard.selectAll()
|
||||||
|
clipboard.copy()
|
||||||
|
clipboard.select(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 40
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
|
textFormat: Text.RichText
|
||||||
|
text: qsTr("Use <a href=\"https://www.torproject.org/download/\" style=\"color: #FBB26A;\">Tor Browser</a> to open this url.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
text: qsTr("After installation it takes several minutes while your onion site will become available in the Tor Network.")
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
text: qsTr("When configuring WordPress set the domain as this onion address.")
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicButtonType {
|
||||||
|
Layout.topMargin: 24
|
||||||
|
Layout.bottomMargin: 16
|
||||||
|
Layout.leftMargin: 8
|
||||||
|
implicitHeight: 32
|
||||||
|
|
||||||
|
defaultColor: "transparent"
|
||||||
|
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
|
||||||
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
text: qsTr("Remove website")
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
questionDrawer.headerText = qsTr("Some description")
|
||||||
|
questionDrawer.yesButtonText = qsTr("Continue")
|
||||||
|
questionDrawer.noButtonText = qsTr("Cancel")
|
||||||
|
|
||||||
|
questionDrawer.yesButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
goToPage(PageEnum.PageDeinstalling)
|
||||||
|
ContainersModel.removeCurrentlyProcessedContainer()
|
||||||
|
closePage()
|
||||||
|
closePage() //todo auto close to deinstall page?
|
||||||
|
}
|
||||||
|
questionDrawer.noButtonFunction = function() {
|
||||||
|
questionDrawer.visible = false
|
||||||
|
}
|
||||||
|
questionDrawer.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionDrawer {
|
||||||
|
id: questionDrawer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue