Multiple ui fixes, save file function reimpl

This commit is contained in:
pokamest 2022-02-15 17:08:55 +03:00
parent b63bf2465f
commit c233f767f4
22 changed files with 229 additions and 2601 deletions

View file

@ -136,7 +136,7 @@ Proto ContainerProps::defaultProtocol(DockerContainer c)
} }
} }
bool ContainerProps::isWorkingOnPlatform(DockerContainer c) bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
{ {
#ifdef Q_OS_WINDOWS #ifdef Q_OS_WINDOWS
return true; return true;

View file

@ -54,7 +54,7 @@ public:
// it may be changed fot future containers :) // it may be changed fot future containers :)
Q_INVOKABLE static Proto defaultProtocol(DockerContainer c); Q_INVOKABLE static Proto defaultProtocol(DockerContainer c);
Q_INVOKABLE static bool isWorkingOnPlatform(DockerContainer c); Q_INVOKABLE static bool isSupportedByCurrentPlatform(DockerContainer c);
}; };

View file

@ -97,7 +97,7 @@ constexpr char ckBypassUidKeyPath[] = "/opt/amnezia/cloak/cloak_bypass_uid.key";
constexpr char ckAdminKeyPath[] = "/opt/amnezia/cloak/cloak_admin_uid.key"; constexpr char ckAdminKeyPath[] = "/opt/amnezia/cloak/cloak_admin_uid.key";
constexpr char defaultPort[] = "443"; constexpr char defaultPort[] = "443";
constexpr char defaultRedirSite[] = "tile.openstreetmap.org"; constexpr char defaultRedirSite[] = "tile.openstreetmap.org";
constexpr char defaultCipher[] = "chacha20-ietf-poly1305"; constexpr char defaultCipher[] = "chacha20-poly1305";
} }

File diff suppressed because it is too large Load diff

View file

@ -3,6 +3,7 @@
#include "debug.h" #include "debug.h"
#include "defines.h" #include "defines.h"
#include "ui/qautostart.h" #include "ui/qautostart.h"
#include "ui/uilogic.h"
#include <QDesktopServices> #include <QDesktopServices>
#include <QFileDialog> #include <QFileDialog>
@ -65,22 +66,7 @@ void AppSettingsLogic::onPushButtonOpenLogsClicked()
void AppSettingsLogic::onPushButtonExportLogsClicked() void AppSettingsLogic::onPushButtonExportLogsClicked()
{ {
QString log = Debug::getLogFile(); uiLogic()->saveTextFile(tr("Save log"), "AmneziaVPN.log", ".log", Debug::getLogFile());
QString ext = ".log";
QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save log"),
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*" + ext);
if (fileName.isEmpty()) return;
if (!fileName.endsWith(ext)) fileName.append(ext);
QFile save(fileName);
save.open(QIODevice::WriteOnly);
save.write(log.toUtf8());
save.close();
QFileInfo fi(fileName);
QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
} }
void AppSettingsLogic::onPushButtonClearLogsClicked() void AppSettingsLogic::onPushButtonClearLogsClicked()

View file

@ -206,6 +206,6 @@ void SitesLogic::onPushButtonSitesExportClicked()
for (auto s : sites.keys()) { for (auto s : sites.keys()) {
data += s + "\t" + sites.value(s).toString() + "\n"; data += s + "\t" + sites.value(s).toString() + "\n";
} }
uiLogic()->saveTextFile("Sites", ".txt", data); uiLogic()->saveTextFile("Export Sites", "sites.txt", ".txt", data);
} }

View file

@ -19,6 +19,8 @@ VpnLogic::VpnLogic(UiLogic *logic, QObject *parent):
m_labelSpeedReceivedText{tr("0 Mbps")}, m_labelSpeedReceivedText{tr("0 Mbps")},
m_labelSpeedSentText{tr("0 Mbps")}, m_labelSpeedSentText{tr("0 Mbps")},
m_labelStateText{}, m_labelStateText{},
m_isContainerHaveAuthData{false},
m_isContainerSupportedByCurrentPlatform{false},
m_widgetVpnModeEnabled{false} m_widgetVpnModeEnabled{false}
{ {
connect(uiLogic()->m_vpnConnection, &VpnConnection::bytesChanged, this, &VpnLogic::onBytesChanged); connect(uiLogic()->m_vpnConnection, &VpnConnection::bytesChanged, this, &VpnLogic::onBytesChanged);
@ -49,6 +51,8 @@ void VpnLogic::onUpdatePage()
selectedContainer == DockerContainer::ShadowSocks|| selectedContainer == DockerContainer::ShadowSocks||
selectedContainer == DockerContainer::Cloak); selectedContainer == DockerContainer::Cloak);
set_isContainerHaveAuthData(m_settings.haveAuthData(m_settings.defaultServerIndex()));
set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites || !isCustomRoutesSupported()); set_radioButtonVpnModeAllSitesChecked(mode == Settings::VpnAllSites || !isCustomRoutesSupported());
set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites && isCustomRoutesSupported()); set_radioButtonVpnModeForwardSitesChecked(mode == Settings::VpnOnlyForwardSites && isCustomRoutesSupported());
set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites && isCustomRoutesSupported()); set_radioButtonVpnModeExceptSitesChecked(mode == Settings::VpnAllExceptSites && isCustomRoutesSupported());
@ -72,8 +76,8 @@ void VpnLogic::onUpdatePage()
} }
set_isContainerWorkingOnPlatform(ContainerProps::isWorkingOnPlatform(selectedContainer)); set_isContainerSupportedByCurrentPlatform(ContainerProps::isSupportedByCurrentPlatform(selectedContainer));
if (!isContainerWorkingOnPlatform()) { if (!isContainerSupportedByCurrentPlatform()) {
set_labelErrorText(tr("AmneziaVPN not supporting selected protocol on this device. Select another protocol.")); set_labelErrorText(tr("AmneziaVPN not supporting selected protocol on this device. Select another protocol."));
} }
else { else {

View file

@ -22,7 +22,8 @@ class VpnLogic : public PageLogicBase
AUTO_PROPERTY(bool, pushButtonConnectEnabled) AUTO_PROPERTY(bool, pushButtonConnectEnabled)
AUTO_PROPERTY(bool, pushButtonConnectVisible) AUTO_PROPERTY(bool, pushButtonConnectVisible)
AUTO_PROPERTY(bool, widgetVpnModeEnabled) AUTO_PROPERTY(bool, widgetVpnModeEnabled)
AUTO_PROPERTY(bool, isContainerWorkingOnPlatform) AUTO_PROPERTY(bool, isContainerSupportedByCurrentPlatform)
AUTO_PROPERTY(bool, isContainerHaveAuthData)
AUTO_PROPERTY(QString, labelErrorText) AUTO_PROPERTY(QString, labelErrorText)
AUTO_PROPERTY(QString, labelVersionText) AUTO_PROPERTY(QString, labelVersionText)

View file

@ -5,11 +5,13 @@ BasicButtonType {
id: root id: root
property alias iconMargin: img.anchors.margins property alias iconMargin: img.anchors.margins
property alias img: img property alias img: img
property int imgMargin: 4
property int imgMarginHover: 3
background: Item {} background: Item {}
contentItem: Image { contentItem: Image {
id: img id: img
source: root.icon.source source: root.icon.source
anchors.fill: root anchors.fill: root
anchors.margins: root.containsMouse ? 3 : 4 anchors.margins: root.containsMouse ? imgMarginHover : imgMargin
} }
} }

View file

@ -4,6 +4,7 @@ import QtQuick.Controls 2.12
BasicButtonType { BasicButtonType {
id: root id: root
property alias textItem: textItem property alias textItem: textItem
height: 30
background: Item {} background: Item {}
contentItem: Item { contentItem: Item {

View file

@ -42,6 +42,7 @@ PageBase {
anchors.right: parent.right anchors.right: parent.right
CheckBoxType { CheckBoxType {
visible: !GC.isMobile()
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Auto connect") text: qsTr("Auto connect")
checked: AppSettingsLogic.checkBoxAutoConnectChecked checked: AppSettingsLogic.checkBoxAutoConnectChecked
@ -51,6 +52,7 @@ PageBase {
} }
} }
CheckBoxType { CheckBoxType {
visible: !GC.isMobile()
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Auto start") text: qsTr("Auto start")
checked: AppSettingsLogic.checkBoxAutostartChecked checked: AppSettingsLogic.checkBoxAutostartChecked
@ -60,6 +62,7 @@ PageBase {
} }
} }
CheckBoxType { CheckBoxType {
visible: !GC.isMobile()
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Start minimized") text: qsTr("Start minimized")
checked: AppSettingsLogic.checkBoxStartMinimizedChecked checked: AppSettingsLogic.checkBoxStartMinimizedChecked
@ -74,6 +77,7 @@ PageBase {
text: AppSettingsLogic.labelVersionText text: AppSettingsLogic.labelVersionText
} }
BlueButtonType { BlueButtonType {
visible: !GC.isMobile()
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: 41 Layout.preferredHeight: 41
text: qsTr("Check for updates") text: qsTr("Check for updates")

View file

@ -1,5 +1,6 @@
import QtQuick 2.12 import QtQuick 2.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import QtGraphicalEffects 1.15 import QtGraphicalEffects 1.15
import PageEnum 1.0 import PageEnum 1.0
import "./" import "./"
@ -13,27 +14,44 @@ PageBase {
BackButton { BackButton {
id: back id: back
z: -1
} }
Flickable {
id: fl
width: root.width
anchors.top: back.bottom
anchors.topMargin: 0
anchors.bottom: root.bottom
anchors.bottomMargin: 10
anchors.left: root.left
anchors.leftMargin: 30
anchors.right: root.right
anchors.rightMargin: 30
contentHeight: content.height
clip: true
ColumnLayout {
id: content
enabled: logic.pageEnabled
anchors.top: parent.top
anchors.topMargin: 10
anchors.left: parent.left
anchors.right: parent.right
spacing: 15
// ---------- App settings ------------ // ---------- App settings ------------
Rectangle { Rectangle {
id: l1 Layout.fillWidth: true
visible: !GC.isMobile() Layout.preferredHeight: 1
anchors.top: back.bottom
x: 20
width: parent.width - 40
height: GC.isMobile() ? 0: 1
color: "#DDDDDD" color: "#DDDDDD"
} }
SettingButtonType { SettingButtonType {
id: b1 Layout.fillWidth: true
visible: !GC.isMobile() Layout.preferredHeight: 30
anchors.top: l1.bottom
anchors.topMargin: GC.isMobile() ? 0: 15
x: 30
width: parent.width - 80
height: GC.isMobile() ? 0: 30
icon.source: "qrc:/images/svg/settings_black_24dp.svg" icon.source: "qrc:/images/svg/settings_black_24dp.svg"
text: qsTr("App settings") text: qsTr("App settings")
onClicked: { onClicked: {
@ -43,21 +61,13 @@ PageBase {
// ---------- Network settings ------------ // ---------- Network settings ------------
Rectangle { Rectangle {
id: l2 Layout.fillWidth: true
anchors.top: b1.bottom Layout.preferredHeight: 1
anchors.topMargin: 15
x: 20
width: parent.width - 40
height: 1
color: "#DDDDDD" color: "#DDDDDD"
} }
SettingButtonType { SettingButtonType {
id: b2 Layout.fillWidth: true
x: 30 Layout.preferredHeight: 30
anchors.top: l2.bottom
anchors.topMargin: 15
width: parent.width - 40
height: 30
icon.source: "qrc:/images/svg/settings_suggest_black_24dp.svg" icon.source: "qrc:/images/svg/settings_suggest_black_24dp.svg"
text: qsTr("Network settings") text: qsTr("Network settings")
onClicked: { onClicked: {
@ -67,21 +77,13 @@ PageBase {
// ---------- Server settings ------------ // ---------- Server settings ------------
Rectangle { Rectangle {
id: l3 Layout.fillWidth: true
anchors.top: b2.bottom Layout.preferredHeight: 1
anchors.topMargin: 15
x: 20
width: parent.width - 40
height: 1
color: "#DDDDDD" color: "#DDDDDD"
} }
SettingButtonType { SettingButtonType {
id: b3 Layout.fillWidth: true
x: 30 Layout.preferredHeight: 30
anchors.top: l3.bottom
anchors.topMargin: 15
width: 330
height: 30
icon.source: "qrc:/images/svg/vpn_key_black_24dp.svg" icon.source: "qrc:/images/svg/vpn_key_black_24dp.svg"
text: qsTr("Server Settings") text: qsTr("Server Settings")
onClicked: { onClicked: {
@ -91,21 +93,13 @@ PageBase {
// ---------- Share connection ------------ // ---------- Share connection ------------
Rectangle { Rectangle {
id: l4 Layout.fillWidth: true
anchors.top: b3.bottom Layout.preferredHeight: 1
anchors.topMargin: 15
x: 20
width: parent.width - 40
height: 1
color: "#DDDDDD" color: "#DDDDDD"
} }
SettingButtonType { SettingButtonType {
id: b4 Layout.fillWidth: true
x: 30 Layout.preferredHeight: 30
anchors.top: l4.bottom
anchors.topMargin: 15
width: 330
height: 30
icon.source: "qrc:/images/svg/share_black_24dp.svg" icon.source: "qrc:/images/svg/share_black_24dp.svg"
text: qsTr("Share connection") text: qsTr("Share connection")
enabled: GeneralSettingsLogic.pushButtonGeneralSettingsShareConnectionEnable enabled: GeneralSettingsLogic.pushButtonGeneralSettingsShareConnectionEnable
@ -116,21 +110,13 @@ PageBase {
// ---------- Servers ------------ // ---------- Servers ------------
Rectangle { Rectangle {
id: l5 Layout.fillWidth: true
anchors.top: b4.bottom Layout.preferredHeight: 1
anchors.topMargin: 15
x: 20
width: parent.width - 40
height: 1
color: "#DDDDDD" color: "#DDDDDD"
} }
SettingButtonType { SettingButtonType {
id: b5 Layout.fillWidth: true
x: 30 Layout.preferredHeight: 30
anchors.top: l5.bottom
anchors.topMargin: 15
width: 330
height: 30
icon.source: "qrc:/images/svg/format_list_bulleted_black_24dp.svg" icon.source: "qrc:/images/svg/format_list_bulleted_black_24dp.svg"
text: qsTr("Servers") text: qsTr("Servers")
onClicked: { onClicked: {
@ -140,21 +126,13 @@ PageBase {
// ---------- Add server ------------ // ---------- Add server ------------
Rectangle { Rectangle {
id: l6 Layout.fillWidth: true
anchors.top: b5.bottom Layout.preferredHeight: 1
anchors.topMargin: 15
x: 20
width: parent.width - 40
height: 1
color: "#DDDDDD" color: "#DDDDDD"
} }
SettingButtonType { SettingButtonType {
id: b6 Layout.fillWidth: true
x: 30 Layout.preferredHeight: 30
anchors.top: l6.bottom
anchors.topMargin: 15
width: 330
height: 30
icon.source: "qrc:/images/svg/control_point_black_24dp.svg" icon.source: "qrc:/images/svg/control_point_black_24dp.svg"
text: qsTr("Add server") text: qsTr("Add server")
onClicked: { onClicked: {
@ -163,26 +141,28 @@ PageBase {
} }
Rectangle { Rectangle {
id: l7 Layout.fillWidth: true
anchors.top: b6.bottom Layout.preferredHeight: 1
anchors.topMargin: 15
x: 20
width: parent.width - 40
height: 1
color: "#DDDDDD" color: "#DDDDDD"
} }
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: fl.height > (75+1) * 6 ? fl.height - (75+1) * 6 : 0
}
SettingButtonType { SettingButtonType {
x: 30 Layout.fillWidth: true
anchors.bottom: parent.bottom Layout.preferredHeight: 30
anchors.bottomMargin: 20 Layout.bottomMargin: 20
width: 330
height: 30
icon.source: "qrc:/images/svg/logout_black_24dp.svg" icon.source: "qrc:/images/svg/logout_black_24dp.svg"
text: qsTr("Exit") text: qsTr("Exit")
onClicked: { onClicked: {
Qt.quit() Qt.quit()
} }
} }
}
}
} }

View file

@ -16,16 +16,16 @@ PageBase {
} }
Caption { Caption {
id: caption id: caption
text: qsTr("Servers list") text: qsTr("Servers")
width: undefined width: undefined
} }
SvgButtonType { SvgButtonType {
anchors.bottom: caption.bottom anchors.verticalCenter: caption.verticalCenter
anchors.leftMargin: 10 anchors.leftMargin: 10
anchors.left: caption.right anchors.left: caption.right
width: 24 width: 27
height: 24 height: 27
icon.source: "qrc:/images/svg/control_point_black_24dp.svg" icon.source: "qrc:/images/svg/control_point_black_24dp.svg"
onClicked: { onClicked: {

View file

@ -59,9 +59,11 @@ PageBase {
ImageButtonType { ImageButtonType {
x: parent.width - 40 x: parent.width - 40
y: 10 y: 0
width: 31 width: 41
height: 31 height: 41
imgMarginHover: 8
imgMargin: 9
icon.source: "qrc:/images/settings_grey.png" icon.source: "qrc:/images/settings_grey.png"
onClicked: { onClicked: {
UiLogic.goToPage(PageEnum.GeneralSettings) UiLogic.goToPage(PageEnum.GeneralSettings)
@ -98,7 +100,7 @@ PageBase {
} }
contentItem: Item {} contentItem: Item {}
antialiasing: true antialiasing: true
enabled: VpnLogic.pushButtonConnectEnabled && VpnLogic.isContainerWorkingOnPlatform enabled: VpnLogic.pushButtonConnectEnabled && VpnLogic.isContainerSupportedByCurrentPlatform
opacity: VpnLogic.pushButtonConnectVisible ? 1 : 0 opacity: VpnLogic.pushButtonConnectVisible ? 1 : 0
// transitions: Transition { // transitions: Transition {
@ -128,14 +130,14 @@ PageBase {
LabelType { LabelType {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
height: 21 height: 21
text: qsTr("Server") + ": " text: ( VpnLogic.isContainerHaveAuthData ? qsTr("Server") : qsTr("Profile")) + ": "
} }
BasicButtonType { BasicButtonType {
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
height: 21 height: 21
background: Item {} background: Item {}
text: VpnLogic.labelCurrentServer + " →" text: VpnLogic.labelCurrentServer + (VpnLogic.isContainerHaveAuthData ? " →" : "")
font.family: "Lato" font.family: "Lato"
font.styleName: "normal" font.styleName: "normal"
font.pixelSize: 16 font.pixelSize: 16
@ -163,12 +165,12 @@ PageBase {
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
height: 21 height: 21
background: Item {} background: Item {}
text: VpnLogic.labelCurrentService + " →" text: VpnLogic.labelCurrentService + (VpnLogic.isContainerHaveAuthData ? " →" : "")
font.family: "Lato" font.family: "Lato"
font.styleName: "normal" font.styleName: "normal"
font.pixelSize: 16 font.pixelSize: 16
onClicked: { onClicked: {
UiLogic.onGotoCurrentProtocolsPage() if (VpnLogic.isContainerHaveAuthData) UiLogic.onGotoCurrentProtocolsPage()
} }
} }
} }
@ -192,12 +194,12 @@ PageBase {
height: 21 height: 21
implicitWidth: implicitContentWidth > root.width * 0.6 ? root.width * 0.6 : implicitContentWidth + leftPadding + rightPadding implicitWidth: implicitContentWidth > root.width * 0.6 ? root.width * 0.6 : implicitContentWidth + leftPadding + rightPadding
background: Item {} background: Item {}
text: VpnLogic.labelCurrentDns + " →" text: VpnLogic.labelCurrentDns + (VpnLogic.isContainerHaveAuthData ? " →" : "")
font.family: "Lato" font.family: "Lato"
font.styleName: "normal" font.styleName: "normal"
font.pixelSize: 16 font.pixelSize: 16
onClicked: { onClicked: {
UiLogic.goToPage(PageEnum.NetworkSettings) if (VpnLogic.isContainerHaveAuthData) UiLogic.goToPage(PageEnum.NetworkSettings)
} }
} }

View file

@ -117,7 +117,7 @@ New encryption keys pair will be generated.")
visible: tfShareCode.textArea.length > 0 visible: tfShareCode.textArea.length > 0
onClicked: { onClicked: {
UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "*.vpn", tfShareCode.textArea.text) UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "amnezia_config.vpn", "*.vpn", tfShareCode.textArea.text)
} }
} }

View file

@ -99,7 +99,7 @@ PageShareProtocolBase {
visible: tfShareCode.textArea.length > 0 visible: tfShareCode.textArea.length > 0
onClicked: { onClicked: {
UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "*.json", tfShareCode.textArea.text) UiLogic.saveTextFile(qsTr("Save AmneziaVPN config"), "amnezia_config_cloak.json", "*.json", tfShareCode.textArea.text)
} }
} }

View file

@ -102,7 +102,7 @@ PageShareProtocolBase {
visible: tfCert.textArea.length > 0 visible: tfCert.textArea.length > 0
onClicked: { onClicked: {
UiLogic.saveTextFile(qsTr("Export p12 certificate"), "*.p12", tfCert.textArea.text) UiLogic.saveTextFile(qsTr("Export p12 certificate"), "amnezia_ikev2_cert_for_windows.p12", "*.p12", tfCert.textArea.text)
} }
} }
@ -117,7 +117,7 @@ PageShareProtocolBase {
visible: tfMobileConfig.textArea.length > 0 visible: tfMobileConfig.textArea.length > 0
onClicked: { onClicked: {
UiLogic.saveTextFile(qsTr("Export config for Apple"), "*.plist", tfMobileConfig.textArea.text) UiLogic.saveTextFile(qsTr("Export config for Apple"), "amnezia_for_apple.plist", "*.plist", tfMobileConfig.textArea.text)
} }
} }
@ -132,7 +132,7 @@ PageShareProtocolBase {
visible: tfStrongSwanConfig.textArea.length > 0 visible: tfStrongSwanConfig.textArea.length > 0
onClicked: { onClicked: {
UiLogic.saveTextFile(qsTr("Export config for StrongSwan"), "*.profile", tfStrongSwanConfig.textArea.text) UiLogic.saveTextFile(qsTr("Export config for StrongSwan"), "amnezia_for_StrongSwan.profile", "*.profile", tfStrongSwanConfig.textArea.text)
} }
} }
} }

View file

@ -98,7 +98,7 @@ PageShareProtocolBase {
visible: tfShareCode.textArea.length > 0 visible: tfShareCode.textArea.length > 0
onClicked: { onClicked: {
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "*.ovpn", tfShareCode.textArea.text) UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "amnezia_for_openvpn.ovpn", "*.ovpn", tfShareCode.textArea.text)
} }
} }
} }

View file

@ -96,7 +96,7 @@ PageShareProtocolBase {
visible: tfShareCode.textArea.length > 0 visible: tfShareCode.textArea.length > 0
onClicked: { onClicked: {
UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "*.conf", tfShareCode.textArea.text) UiLogic.saveTextFile(qsTr("Save OpenVPN config"), "amnezia_for_wireguard.conf", "*.conf", tfShareCode.textArea.text)
} }
} }

View file

@ -26,7 +26,6 @@ Window {
height: GC.isDesktop() ? GC.screenHeight + titleBar.height : GC.screenHeight height: GC.isDesktop() ? GC.screenHeight + titleBar.height : GC.screenHeight
minimumWidth: 360 minimumWidth: 360
minimumHeight: GC.isDesktop() ? 640 : 0 minimumHeight: GC.isDesktop() ? 640 : 0
Keys.enabled: true
onClosing: { onClosing: {
console.debug("QML onClosing signal") console.debug("QML onClosing signal")
UiLogic.onCloseWindow() UiLogic.onCloseWindow()

View file

@ -17,6 +17,7 @@
#include <QThread> #include <QThread>
#include <QTimer> #include <QTimer>
#include <QRegularExpression> #include <QRegularExpression>
#include <QQmlFile>
#include "configurators/cloak_configurator.h" #include "configurators/cloak_configurator.h"
#include "configurators/vpn_configurator.h" #include "configurators/vpn_configurator.h"
@ -605,21 +606,52 @@ PageEnumNS::Page UiLogic::currentPage()
return static_cast<PageEnumNS::Page>(currentPageValue()); return static_cast<PageEnumNS::Page>(currentPageValue());
} }
void UiLogic::saveTextFile(const QString& desc, QString ext, const QString& data) void UiLogic::saveTextFile(const QString& desc, const QString& suggestedName, QString ext, const QString& data)
{ {
// ext.replace("*", "");
// QString fileName = QFileDialog::getSaveFileName(nullptr, desc,
// QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*" + ext);
// if (fileName.isEmpty()) return;
// if (!fileName.endsWith(ext)) fileName.append(ext);
// QFile save(fileName);
// save.open(QIODevice::WriteOnly);
// save.write(data.toUtf8());
// save.close();
// QFileInfo fi(fileName);
// QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
ext.replace("*", ""); ext.replace("*", "");
QString fileName = QFileDialog::getSaveFileName(nullptr, desc, QString docDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation), "*" + ext); QUrl fileName;
#ifdef AMNEZIA_DESKTOP
fileName = QFileDialog::getSaveFileUrl(nullptr, desc,
QUrl::fromLocalFile(docDir + "/" + suggestedName), "*" + ext);
if (fileName.isEmpty()) return; if (fileName.isEmpty()) return;
if (!fileName.endsWith(ext)) fileName.append(ext); if (!fileName.toString().endsWith(ext)) fileName = QUrl(fileName.toString() + ext);
#elif defined Q_OS_ANDROID
fileName = QFileDialog::getSaveFileUrl(nullptr, suggestedName,
QUrl::fromLocalFile(docDir), "*" + ext);
#endif
qDebug() << "UiLogic::saveTextFile" << fileName;
if (fileName.isEmpty()) return;
#ifdef AMNEZIA_DESKTOP
QFile save(fileName.toLocalFile());
#else
qDebug() << "UiLogic::saveTextFile" << QQmlFile::urlToLocalFileOrQrc(fileName);
QFile save(QQmlFile::urlToLocalFileOrQrc(fileName));
#endif
QFile save(fileName);
save.open(QIODevice::WriteOnly); save.open(QIODevice::WriteOnly);
save.write(data.toUtf8()); save.write(data.toUtf8());
save.close(); save.close();
QFileInfo fi(fileName); QFileInfo fi(fileName.toLocalFile());
QDesktopServices::openUrl(fi.absoluteDir().absolutePath()); QDesktopServices::openUrl(fi.absoluteDir().absolutePath());
} }

View file

@ -100,7 +100,7 @@ public:
Q_INVOKABLE void keyPressEvent(Qt::Key key); Q_INVOKABLE void keyPressEvent(Qt::Key key);
Q_INVOKABLE void saveTextFile(const QString& desc, QString ext, const QString& data); Q_INVOKABLE void saveTextFile(const QString& desc, const QString &suggestedName, QString ext, const QString& data);
Q_INVOKABLE void saveBinaryFile(const QString& desc, QString ext, const QString& data); Q_INVOKABLE void saveBinaryFile(const QString& desc, QString ext, const QString& data);
Q_INVOKABLE void copyToClipboard(const QString& text); Q_INVOKABLE void copyToClipboard(const QString& text);