added disconnection from vpn when closing application for desktop
- many small ui fixes
This commit is contained in:
parent
14fa0b4fd3
commit
e157160337
24 changed files with 121 additions and 64 deletions
|
@ -57,36 +57,13 @@ AmneziaApplication::AmneziaApplication(int &argc, char *argv[], bool allowSecond
|
|||
|
||||
AmneziaApplication::~AmneziaApplication()
|
||||
{
|
||||
// emit hide();
|
||||
|
||||
// #ifdef AMNEZIA_DESKTOP
|
||||
// if (m_vpnConnection->connectionState() != Vpn::ConnectionState::Disconnected) {
|
||||
// m_vpnConnection->disconnectFromVpn();
|
||||
// for (int i = 0; i < 50; i++) {
|
||||
// qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
// QThread::msleep(100);
|
||||
// if (m_vpnConnection->isDisconnected()) {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// m_vpnConnection->deleteLater();
|
||||
// m_vpnConnectionThread.quit();
|
||||
// m_vpnConnectionThread.wait(3000);
|
||||
|
||||
// qDebug() << "Application closed";
|
||||
m_vpnConnectionThread.quit();
|
||||
m_vpnConnectionThread.wait(3000);
|
||||
|
||||
if (m_engine) {
|
||||
QObject::disconnect(m_engine, 0, 0, 0);
|
||||
delete m_engine;
|
||||
}
|
||||
|
||||
if (m_protocolProps)
|
||||
delete m_protocolProps;
|
||||
if (m_containerProps)
|
||||
delete m_containerProps;
|
||||
}
|
||||
|
||||
void AmneziaApplication::init()
|
||||
|
@ -208,11 +185,11 @@ void AmneziaApplication::registerTypes()
|
|||
|
||||
qmlRegisterType<QRCodeReader>("QRCodeReader", 1, 0, "QRCodeReader");
|
||||
|
||||
m_containerProps = new ContainerProps;
|
||||
qmlRegisterSingletonInstance("ContainerProps", 1, 0, "ContainerProps", m_containerProps);
|
||||
m_containerProps.reset(new ContainerProps());
|
||||
qmlRegisterSingletonInstance("ContainerProps", 1, 0, "ContainerProps", m_containerProps.get());
|
||||
|
||||
m_protocolProps = new ProtocolProps;
|
||||
qmlRegisterSingletonInstance("ProtocolProps", 1, 0, "ProtocolProps", m_protocolProps);
|
||||
m_protocolProps.reset(new ProtocolProps());
|
||||
qmlRegisterSingletonInstance("ProtocolProps", 1, 0, "ProtocolProps", m_protocolProps.get());
|
||||
|
||||
qmlRegisterSingletonType(QUrl("qrc:/ui/qml/Filters/ContainersModelFilters.qml"), "ContainersModelFilters", 1, 0,
|
||||
"ContainersModelFilters");
|
||||
|
@ -232,9 +209,13 @@ void AmneziaApplication::loadFonts()
|
|||
void AmneziaApplication::loadTranslator()
|
||||
{
|
||||
auto locale = m_settings->getAppLanguage();
|
||||
m_translator = new QTranslator;
|
||||
if (m_translator->load(locale, QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/i18n"))) {
|
||||
installTranslator(m_translator);
|
||||
if (locale != QLocale::English) {
|
||||
m_translator.reset(new QTranslator());
|
||||
if (m_translator->load(locale, QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/i18n"))) {
|
||||
if (QCoreApplication::installTranslator(m_translator.get())) {
|
||||
m_settings->setAppLanguage(locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +223,7 @@ void AmneziaApplication::updateTranslator(const QLocale &locale)
|
|||
{
|
||||
QResource::registerResource(":/translations.qrc");
|
||||
if (!m_translator->isEmpty())
|
||||
QCoreApplication::removeTranslator(m_translator);
|
||||
QCoreApplication::removeTranslator(m_translator.get());
|
||||
|
||||
if (locale == QLocale::English) {
|
||||
m_settings->setAppLanguage(locale);
|
||||
|
@ -250,7 +231,7 @@ void AmneziaApplication::updateTranslator(const QLocale &locale)
|
|||
}
|
||||
|
||||
if (m_translator->load(locale, QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/i18n"))) {
|
||||
if (QCoreApplication::installTranslator(m_translator)) {
|
||||
if (QCoreApplication::installTranslator(m_translator.get())) {
|
||||
m_settings->setAppLanguage(locale);
|
||||
}
|
||||
|
||||
|
@ -351,7 +332,7 @@ void AmneziaApplication::initControllers()
|
|||
m_exportController.reset(new ExportController(m_serversModel, m_containersModel, m_settings, m_configurator));
|
||||
m_engine->rootContext()->setContextProperty("ExportController", m_exportController.get());
|
||||
|
||||
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_settings));
|
||||
m_settingsController.reset(new SettingsController(m_serversModel, m_containersModel, m_languageModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("SettingsController", m_settingsController.get());
|
||||
|
||||
m_sitesController.reset(new SitesController(m_settings, m_vpnConnection, m_sitesModel));
|
||||
|
|
|
@ -79,15 +79,15 @@ private:
|
|||
std::shared_ptr<Settings> m_settings;
|
||||
std::shared_ptr<VpnConfigurator> m_configurator;
|
||||
|
||||
ContainerProps *m_containerProps {};
|
||||
ProtocolProps *m_protocolProps {};
|
||||
QSharedPointer<ContainerProps> m_containerProps;
|
||||
QSharedPointer<ProtocolProps> m_protocolProps;
|
||||
|
||||
QTranslator *m_translator;
|
||||
QSharedPointer<QTranslator> m_translator;
|
||||
QCommandLineParser m_parser;
|
||||
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QScopedPointer<LanguageModel> m_languageModel;
|
||||
QSharedPointer<LanguageModel> m_languageModel;
|
||||
QScopedPointer<ProtocolsModel> m_protocolsModel;
|
||||
QSharedPointer<SitesModel> m_sitesModel;
|
||||
|
||||
|
|
|
@ -17,6 +17,23 @@ ConnectionController::ConnectionController(const QSharedPointer<ServersModel> &s
|
|||
Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
ConnectionController::~ConnectionController()
|
||||
{
|
||||
// todo use ConnectionController instead of using m_vpnConnection directly
|
||||
#ifdef AMNEZIA_DESKTOP
|
||||
if (m_vpnConnection->connectionState() != Vpn::ConnectionState::Disconnected) {
|
||||
m_vpnConnection->disconnectFromVpn();
|
||||
for (int i = 0; i < 50; i++) {
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
QThread::msleep(100);
|
||||
if (m_vpnConnection->isDisconnected()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConnectionController::openConnection()
|
||||
{
|
||||
int serverIndex = m_serversModel->getDefaultServerIndex();
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<VpnConnection> &vpnConnection, QObject *parent = nullptr);
|
||||
|
||||
~ConnectionController();
|
||||
|
||||
bool isConnected() const;
|
||||
bool isConnectionInProgress() const;
|
||||
QString connectionStateText() const;
|
||||
|
|
|
@ -173,7 +173,7 @@ void InstallController::installContainer(DockerContainer container, QJsonObject
|
|||
"All installed containers have been added to the application");
|
||||
}
|
||||
|
||||
emit installContainerFinished(finishMessage);
|
||||
emit installContainerFinished(finishMessage, ContainerProps::containerService(container) == ServiceType::Other);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ public slots:
|
|||
void setEncryptedPassphrase(QString passphrase);
|
||||
|
||||
signals:
|
||||
void installContainerFinished(const QString &finishMessage);
|
||||
void installContainerFinished(const QString &finishMessage, bool isServiceInstall);
|
||||
void installServerFinished(const QString &finishMessage);
|
||||
|
||||
void updateContainerFinished();
|
||||
|
|
|
@ -79,6 +79,8 @@ signals:
|
|||
void goToPageHome();
|
||||
void goToPageSettings();
|
||||
void goToPageViewConfig();
|
||||
void goToPageSettingsServerServices();
|
||||
|
||||
void closePage();
|
||||
|
||||
void restorePageHomeState(bool isContainerInstalled = false);
|
||||
|
|
|
@ -8,8 +8,13 @@
|
|||
|
||||
SettingsController::SettingsController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<LanguageModel> &languageModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent)
|
||||
: QObject(parent), m_serversModel(serversModel), m_containersModel(containersModel), m_settings(settings)
|
||||
: QObject(parent),
|
||||
m_serversModel(serversModel),
|
||||
m_containersModel(containersModel),
|
||||
m_languageModel(languageModel),
|
||||
m_settings(settings)
|
||||
{
|
||||
m_appVersion = QString("%1: %2 (%3)").arg(tr("Software version"), QString(APP_MAJOR_VERSION), __DATE__);
|
||||
}
|
||||
|
@ -95,6 +100,8 @@ void SettingsController::restoreAppConfig()
|
|||
bool ok = m_settings->restoreAppConfig(data);
|
||||
if (ok) {
|
||||
m_serversModel->resetModel();
|
||||
m_languageModel->changeLanguage(
|
||||
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||
emit restoreBackupFinished();
|
||||
} else {
|
||||
emit changeSettingsErrorOccurred(tr("Backup file is corrupted"));
|
||||
|
@ -110,6 +117,15 @@ void SettingsController::clearSettings()
|
|||
{
|
||||
m_settings->clearSettings();
|
||||
m_serversModel->resetModel();
|
||||
m_languageModel->changeLanguage(
|
||||
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageModel->getCurrentLanguageIndex()));
|
||||
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
||||
}
|
||||
|
||||
void SettingsController::clearCachedProfiles()
|
||||
{
|
||||
m_containersModel->clearCachedProfiles();
|
||||
emit changeSettingsFinished(tr("Cached profiles cleared"));
|
||||
}
|
||||
|
||||
bool SettingsController::isAutoConnectEnabled()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QObject>
|
||||
|
||||
#include "ui/models/containers_model.h"
|
||||
#include "ui/models/languageModel.h"
|
||||
#include "ui/models/servers_model.h"
|
||||
|
||||
class SettingsController : public QObject
|
||||
|
@ -12,6 +13,7 @@ class SettingsController : public QObject
|
|||
public:
|
||||
explicit SettingsController(const QSharedPointer<ServersModel> &serversModel,
|
||||
const QSharedPointer<ContainersModel> &containersModel,
|
||||
const QSharedPointer<LanguageModel> &languageModel,
|
||||
const std::shared_ptr<Settings> &settings, QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(QString primaryDns READ getPrimaryDns WRITE setPrimaryDns NOTIFY primaryDnsChanged)
|
||||
|
@ -41,6 +43,7 @@ public slots:
|
|||
QString getAppVersion();
|
||||
|
||||
void clearSettings();
|
||||
void clearCachedProfiles();
|
||||
|
||||
bool isAutoConnectEnabled();
|
||||
void toggleAutoConnect(bool enable);
|
||||
|
@ -51,11 +54,13 @@ signals:
|
|||
void loggingStateChanged();
|
||||
|
||||
void restoreBackupFinished();
|
||||
void changeSettingsFinished(const QString &finishedMessage);
|
||||
void changeSettingsErrorOccurred(const QString &errorMessage);
|
||||
|
||||
private:
|
||||
QSharedPointer<ServersModel> m_serversModel;
|
||||
QSharedPointer<ContainersModel> m_containersModel;
|
||||
QSharedPointer<LanguageModel> m_languageModel;
|
||||
std::shared_ptr<Settings> m_settings;
|
||||
|
||||
QString m_appVersion;
|
||||
|
|
|
@ -6,6 +6,8 @@ ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
|
|||
m_servers = m_settings->serversArray();
|
||||
m_defaultServerIndex = m_settings->defaultServerIndex();
|
||||
m_currentlyProcessedServerIndex = m_defaultServerIndex;
|
||||
|
||||
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
|
||||
}
|
||||
|
||||
int ServersModel::rowCount(const QModelIndex &parent) const
|
||||
|
@ -27,6 +29,9 @@ bool ServersModel::setData(const QModelIndex &index, const QVariant &value, int
|
|||
server.insert(config_key::description, value.toString());
|
||||
m_settings->editServer(index.row(), server);
|
||||
m_servers.replace(index.row(), server);
|
||||
if (index.row() == m_defaultServerIndex) {
|
||||
emit defaultServerNameChanged();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
void resetModel();
|
||||
|
||||
Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged)
|
||||
Q_PROPERTY(QString defaultServerHostName READ getDefaultServerHostName NOTIFY defaultServerIndexChanged)
|
||||
Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex
|
||||
NOTIFY currentlyProcessedServerIndexChanged)
|
||||
|
@ -65,6 +65,7 @@ protected:
|
|||
signals:
|
||||
void currentlyProcessedServerIndexChanged(const int index);
|
||||
void defaultServerIndexChanged();
|
||||
void defaultServerNameChanged();
|
||||
|
||||
private:
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
|
|
|
@ -80,6 +80,7 @@ DrawerType {
|
|||
configText.selectAll()
|
||||
configText.copy()
|
||||
configText.select(0, 0)
|
||||
PageController.showNotificationMessage(qsTr("Copied"))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,6 +93,7 @@ DrawerType {
|
|||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||
disabledColor: "#878B91"
|
||||
textColor: "#D7D8DB"
|
||||
borderWidth: 1
|
||||
|
||||
text: qsTr("Show content")
|
||||
|
||||
|
|
|
@ -8,11 +8,17 @@ ListView {
|
|||
id: menuContent
|
||||
|
||||
property var rootWidth
|
||||
|
||||
property var selectedText
|
||||
|
||||
property string imageSource
|
||||
|
||||
property var clickedFunction
|
||||
|
||||
property bool dividerVisible: false
|
||||
|
||||
currentIndex: 0
|
||||
|
||||
width: rootWidth
|
||||
height: menuContent.contentItem.height
|
||||
|
||||
|
|
|
@ -102,6 +102,7 @@ PageType {
|
|||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.maximumLength: 5
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
|
@ -114,7 +115,6 @@ PageType {
|
|||
id: cipherDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
implicitHeight: 74
|
||||
|
||||
descriptionText: qsTr("Cipher")
|
||||
headerText: qsTr("Cipher")
|
||||
|
|
|
@ -133,6 +133,7 @@ PageType {
|
|||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.maximumLength: 5
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
|
@ -161,7 +162,6 @@ PageType {
|
|||
id: hashDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
implicitHeight: 74
|
||||
|
||||
enabled: !autoNegotiateEncryprionSwitcher.checked
|
||||
|
||||
|
@ -208,7 +208,6 @@ PageType {
|
|||
id: cipherDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
implicitHeight: 74
|
||||
|
||||
enabled: !autoNegotiateEncryprionSwitcher.checked
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ PageType {
|
|||
|
||||
headerText: qsTr("Port")
|
||||
textFieldText: port
|
||||
textField.maximumLength: 5
|
||||
|
||||
textField.onEditingFinished: {
|
||||
if (textFieldText !== port) {
|
||||
|
@ -100,7 +101,6 @@ PageType {
|
|||
id: cipherDropDown
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 20
|
||||
implicitHeight: 74
|
||||
|
||||
descriptionText: qsTr("Cipher")
|
||||
headerText: qsTr("Cipher")
|
||||
|
|
|
@ -50,6 +50,13 @@ PageType {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsController
|
||||
function onChangeSettingsFinished(finishedMessage) {
|
||||
PageController.showNotificationMessage(finishedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
|
||||
|
|
|
@ -18,6 +18,14 @@ import "../Components"
|
|||
PageType {
|
||||
id: root
|
||||
|
||||
Connections {
|
||||
target: PageController
|
||||
|
||||
function onGoToPageSettingsServerServices() {
|
||||
tabBar.currentIndex = 1
|
||||
}
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: proxyServersModel
|
||||
sourceModel: ServersModel
|
||||
|
@ -99,13 +107,6 @@ PageType {
|
|||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
|
||||
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("Save")
|
||||
|
||||
onClicked: {
|
||||
|
|
|
@ -107,6 +107,8 @@ PageType {
|
|||
|
||||
width: parent.width
|
||||
|
||||
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
|
||||
|
||||
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
|
||||
textColor: "#EB5757"
|
||||
|
||||
|
|
|
@ -20,13 +20,16 @@ PageType {
|
|||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallContainerFinished(finishedMessage) {
|
||||
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
|
||||
goToStartPage()
|
||||
if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageHome)) {
|
||||
PageController.restorePageHomeState(true)
|
||||
} else if (stackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageSettings)) {
|
||||
goToPage(PageEnum.PageSettingsServersList, false)
|
||||
goToPage(PageEnum.PageSettingsServerInfo, false)
|
||||
if (isServiceInstall) {
|
||||
PageController.goToPageSettingsServerServices()
|
||||
}
|
||||
} else {
|
||||
goToPage(PageEnum.PageHome)
|
||||
}
|
||||
|
|
|
@ -211,6 +211,7 @@ PageType {
|
|||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("Port")
|
||||
textField.maximumLength: 5
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
|
@ -79,6 +79,7 @@ PageType {
|
|||
Layout.fillWidth: true
|
||||
|
||||
text: ImportController.getConfigFileName()
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -161,11 +161,9 @@ PageType {
|
|||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
|
||||
implicitHeight: 74
|
||||
|
||||
drawerHeight: 0.4375
|
||||
|
||||
descriptionText: qsTr("Server and service")
|
||||
descriptionText: accessTypeSelector.currentIndex === 0 ? qsTr("Server and service") : qsTr("Server")
|
||||
headerText: qsTr("Server")
|
||||
|
||||
listView: ListViewType {
|
||||
|
@ -261,7 +259,7 @@ PageType {
|
|||
rootWidth: root.width
|
||||
dividerVisible: true
|
||||
|
||||
imageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
imageSource: "qrc:/images/controls/check.svg"
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
id: proxyContainersModel
|
||||
|
@ -327,13 +325,11 @@ PageType {
|
|||
DropDownType {
|
||||
id: exportTypeSelector
|
||||
|
||||
property int currentIndex
|
||||
property int currentIndex: 0
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
implicitHeight: 74
|
||||
|
||||
drawerHeight: 0.4375
|
||||
|
||||
visible: accessTypeSelector.currentIndex === 0
|
||||
|
@ -343,13 +339,15 @@ PageType {
|
|||
headerText: qsTr("Connection format")
|
||||
|
||||
listView: ListViewType {
|
||||
id: exportTypeListView
|
||||
|
||||
rootWidth: root.width
|
||||
dividerVisible: true
|
||||
|
||||
imageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
model: root.connectionTypesModel
|
||||
currentIndex: 0
|
||||
currentIndex: exportTypeSelector.currentIndex
|
||||
|
||||
clickedFunction: function() {
|
||||
exportTypeSelector.text = selectedText
|
||||
|
@ -375,6 +373,7 @@ PageType {
|
|||
enabled: shareButtonEnabled
|
||||
|
||||
text: qsTr("Share")
|
||||
imageSource: "qrc:/images/controls/share-2.svg"
|
||||
|
||||
onClicked: {
|
||||
if (accessTypeSelector.currentIndex === 0) {
|
||||
|
|
|
@ -81,6 +81,13 @@ Window {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsController
|
||||
function onChangeSettingsFinished(finishedMessage) {
|
||||
PageController.showNotificationMessage(finishedMessage)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue