Share page reimpl

This commit is contained in:
pokamest 2021-11-08 15:18:52 +03:00
parent a89104127a
commit 396af917b5
12 changed files with 298 additions and 286 deletions

View file

@ -134,5 +134,6 @@
<file>ui/qml/Pages/Share/PageShareProtoTorWebSite.qml</file>
<file>ui/qml/Controls/TextAreaType.qml</file>
<file>ui/qml/Controls/ContextMenu.qml</file>
<file>ui/qml/Pages/Share/PageShareProtoAmnezia.qml</file>
</qresource>
</RCC>

View file

@ -12,22 +12,28 @@ GeneralSettingsLogic::GeneralSettingsLogic(UiLogic *logic, QObject *parent):
void GeneralSettingsLogic::onUpdatePage()
{
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(m_settings.defaultServerIndex());
set_pushButtonGeneralSettingsShareConnectionEnable(m_settings.haveAuthData(m_settings.defaultServerIndex()));
}
void GeneralSettingsLogic::onPushButtonGeneralSettingsServerSettingsClicked()
{
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex();
uiLogic()->goToPage(Page::ServerSettings);
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(m_settings.defaultServerIndex());
emit uiLogic()->goToPage(Page::ServerSettings);
}
void GeneralSettingsLogic::onPushButtonGeneralSettingsShareConnectionClicked()
{
uiLogic()->selectedServerIndex = m_settings.defaultServerIndex();
uiLogic()->selectedDockerContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex);
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedServerIndex(uiLogic()->selectedServerIndex);
qobject_cast<ProtocolsModel *>(uiLogic()->protocolsModel())->setSelectedDockerContainer(uiLogic()->selectedDockerContainer);
//uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer);
uiLogic()->goToPage(Page::ShareConnection);
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer);
emit uiLogic()->goToPage(Page::ShareConnection);
}

View file

@ -127,5 +127,5 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
void ServerSettingsLogic::onPushButtonShareFullClicked()
{
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), DockerContainer::None);
uiLogic()->goToPage(Page::ShareConnection);
emit uiLogic()->goToPage(Page::ShareConnection);
}

View file

@ -5,6 +5,7 @@
#include <QTimer>
#include <QSaveFile>
#include <QStandardPaths>
#include <QImage>
#include "ShareConnectionLogic.h"
@ -24,8 +25,6 @@ ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent):
m_textEditShareOpenVpnCodeText{},
m_pushButtonShareOpenVpnCopyEnabled{false},
m_pushButtonShareOpenVpnSaveEnabled{false},
m_toolBoxShareConnectionCurrentIndex{-1},
m_pushButtonShareShadowSocksCopyEnabled{false},
m_lineEditShareShadowSocksStringText{},
m_labelShareShadowSocksQrCodeText{},
m_labelShareShadowSocksServerText{},
@ -33,7 +32,6 @@ ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent):
m_labelShareShadowSocksMethodText{},
m_labelShareShadowSocksPasswordText{},
m_plainTextEditShareCloakText{},
m_pushButtonShareCloakCopyEnabled{false},
m_textEditShareFullCodeText{},
m_textEditShareAmneziaCodeText{},
m_pushButtonShareFullCopyText{tr("Copy")},
@ -48,7 +46,7 @@ ShareConnectionLogic::ShareConnectionLogic(UiLogic *logic, QObject *parent):
m_pushButtonShareOpenVpnGenerateText{tr("Generate config")}
{
// TODO consider move to Component.onCompleted
updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer);
//updateSharingPage(uiLogic()->selectedServerIndex, m_settings.serverCredentials(uiLogic()->selectedServerIndex), uiLogic()->selectedDockerContainer);
}
@ -215,85 +213,6 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCreden
uiLogic()->selectedDockerContainer = container;
uiLogic()->selectedServerIndex = serverIndex;
//const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
enum currentWidget {
full_access = 0,
share_amezia,
share_openvpn,
share_shadowshock,
share_cloak
};
if (container == DockerContainer::OpenVpn) {
QString cfg = tr("Press Generate config");
set_textEditShareOpenVpnCodeText(cfg);
set_pushButtonShareOpenVpnCopyEnabled(false);
set_pushButtonShareOpenVpnSaveEnabled(false);
set_toolBoxShareConnectionCurrentIndex(share_openvpn);
}
if (container == DockerContainer::ShadowSocks ||
container == DockerContainer::Cloak) {
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, &e);
set_pushButtonShareShadowSocksCopyEnabled(true);
}
QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
QString ssString = QString("%1:%2@%3:%4")
.arg(ssConfig.value("method").toString())
.arg(ssConfig.value("password").toString())
.arg(ssConfig.value("server").toString())
.arg(ssConfig.value("server_port").toString());
ssString = "ss://" + ssString.toUtf8().toBase64();
set_lineEditShareShadowSocksStringText(ssString);
updateQRCodeImage(ssString, [this](const QString& labelText) ->void {
set_labelShareShadowSocksQrCodeText(labelText);
});
set_labelShareShadowSocksServerText(ssConfig.value("server").toString());
set_labelShareShadowSocksPortText(ssConfig.value("server_port").toString());
set_labelShareShadowSocksMethodText(ssConfig.value("method").toString());
set_labelShareShadowSocksPasswordText(ssConfig.value("password").toString());
set_toolBoxShareConnectionCurrentIndex(share_shadowshock);
}
if (container == DockerContainer::Cloak) {
//ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
set_plainTextEditShareCloakText(QString(""));
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::Cloak);
QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = CloakConfigurator::genCloakConfig(credentials, container, containerConfig, &e);
set_pushButtonShareCloakCopyEnabled(true);
}
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
cloakConfig.remove(config_key::transport_proto);
cloakConfig.insert("ProxyMethod", "shadowsocks");
set_plainTextEditShareCloakText(QJsonDocument(cloakConfig).toJson());
}
// Full access
if (container == DockerContainer::None) {
@ -303,7 +222,69 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCreden
QByteArray ba = QJsonDocument(server).toJson().toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
set_textEditShareFullCodeText(QString("vpn://%1").arg(QString(ba)));
set_toolBoxShareConnectionCurrentIndex(full_access);
}
else {
for (Protocol p : ContainerProps::protocolsForContainer(container)) {
if (p == Protocol::OpenVpn) {
QString cfg = tr("Press Generate config");
set_textEditShareOpenVpnCodeText(cfg);
set_pushButtonShareOpenVpnCopyEnabled(false);
set_pushButtonShareOpenVpnSaveEnabled(false);
}
else if (p == Protocol::ShadowSocks) {
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, &e);
}
QJsonObject ssConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
QString ssString = QString("%1:%2@%3:%4")
.arg(ssConfig.value("method").toString())
.arg(ssConfig.value("password").toString())
.arg(ssConfig.value("server").toString())
.arg(ssConfig.value("server_port").toString());
ssString = "ss://" + ssString.toUtf8().toBase64();
set_lineEditShareShadowSocksStringText(ssString);
QImage qr = updateQRCodeImage(ssString);
set_labelShareShadowSocksQrCodeText(imageToBase64(qr));
set_labelShareShadowSocksServerText(ssConfig.value("server").toString());
set_labelShareShadowSocksPortText(ssConfig.value("server_port").toString());
set_labelShareShadowSocksMethodText(ssConfig.value("method").toString());
set_labelShareShadowSocksPasswordText(ssConfig.value("password").toString());
}
else if (p == Protocol::Cloak) {
set_plainTextEditShareCloakText(QString(""));
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::Cloak);
QString cfg = protoConfig.value(config_key::last_config).toString();
if (cfg.isEmpty()) {
const QJsonObject &containerConfig = m_settings.containerConfig(serverIndex, container);
ErrorCode e = ErrorCode::NoError;
cfg = CloakConfigurator::genCloakConfig(credentials, container, containerConfig, &e);
//set_pushButtonShareCloakCopyEnabled(true);
}
QJsonObject cloakConfig = QJsonDocument::fromJson(cfg.toUtf8()).object();
cloakConfig.remove(config_key::transport_proto);
cloakConfig.insert("ProxyMethod", "shadowsocks");
set_plainTextEditShareCloakText(QJsonDocument(cloakConfig).toJson());
}
}
}
//ui->toolBox_share_connection->addItem(ui->page_share_amnezia, tr(" Share for Amnezia client"));
@ -323,7 +304,7 @@ void ShareConnectionLogic::updateSharingPage(int serverIndex, const ServerCreden
}
void ShareConnectionLogic::updateQRCodeImage(const QString &text, const std::function<void(const QString&)>& set_labelFunc)
QImage ShareConnectionLogic::updateQRCodeImage(const QString &text)
{
int levelIndex = 1;
int versionIndex = 0;
@ -344,10 +325,14 @@ void ShareConnectionLogic::updateQRCodeImage(const QString &text, const std::fun
if ( m_qrEncode.m_byModuleData[i][j] )
encodeImage.setPixel( i + QR_MARGIN, j + QR_MARGIN, 0 );
QByteArray byteArray;
QBuffer buffer(&byteArray);
encodeImage.save(&buffer, "PNG"); // writes the image in PNG format inside the buffer
QString iconBase64 = QString::fromLatin1(byteArray.toBase64().data());
set_labelFunc(iconBase64);
return encodeImage;
}
QString ShareConnectionLogic::imageToBase64(const QImage &image)
{
QByteArray ba;
QBuffer bu(&ba);
bu.open(QIODevice::WriteOnly);
image.save(&bu, "PNG");
return "data:image/png;base64," + QString::fromLatin1(ba.toBase64().data());
}

View file

@ -14,8 +14,6 @@ public:
AUTO_PROPERTY(QString, textEditShareOpenVpnCodeText)
AUTO_PROPERTY(bool, pushButtonShareOpenVpnCopyEnabled)
AUTO_PROPERTY(bool, pushButtonShareOpenVpnSaveEnabled)
AUTO_PROPERTY(int, toolBoxShareConnectionCurrentIndex)
AUTO_PROPERTY(bool, pushButtonShareShadowSocksCopyEnabled)
AUTO_PROPERTY(QString, lineEditShareShadowSocksStringText)
AUTO_PROPERTY(QString, labelShareShadowSocksQrCodeText)
AUTO_PROPERTY(QString, labelShareShadowSocksServerText)
@ -23,7 +21,6 @@ public:
AUTO_PROPERTY(QString, labelShareShadowSocksMethodText)
AUTO_PROPERTY(QString, labelShareShadowSocksPasswordText)
AUTO_PROPERTY(QString, plainTextEditShareCloakText)
AUTO_PROPERTY(bool, pushButtonShareCloakCopyEnabled)
AUTO_PROPERTY(QString, textEditShareFullCodeText)
AUTO_PROPERTY(QString, textEditShareAmneziaCodeText)
AUTO_PROPERTY(QString, pushButtonShareFullCopyText)
@ -55,7 +52,8 @@ public:
void updateSharingPage(int serverIndex, const ServerCredentials &credentials,
DockerContainer container);
void updateQRCodeImage(const QString &text, const std::function<void(const QString&)>& setLabelFunc);
QImage updateQRCodeImage(const QString &text);
QString imageToBase64(const QImage &image);
private:
CQR_Encode m_qrEncode;

View file

@ -10,42 +10,42 @@ Flickable
clip: true
TextArea.flickable:
TextArea {
id: root
property bool error: false
TextArea {
id: root
property bool error: false
width: parent.width - 80
height: 40
anchors.topMargin: 5
selectByMouse: false
width: parent.width - 80
height: 40
anchors.topMargin: 5
selectByMouse: false
selectionColor: "darkgray"
font.pixelSize: 16
color: "#333333"
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
border.width: 1
color: {
if (root.error) {
return Qt.rgba(213, 40, 60, 255)
selectionColor: "darkgray"
font.pixelSize: 16
color: "#333333"
background: Rectangle {
implicitWidth: 200
implicitHeight: 40
border.width: 1
color: {
if (root.error) {
return Qt.rgba(213, 40, 60, 255)
}
return root.enabled ? "#F4F4F4" : Qt.rgba(127, 127, 127, 255)
}
return root.enabled ? "#F4F4F4" : Qt.rgba(127, 127, 127, 255)
}
border.color: {
if (!root.enabled) {
return Qt.rgba(127, 127, 127, 255)
}
if (root.error) {
return Qt.rgba(213, 40, 60, 255)
}
if (root.focus) {
border.color: {
if (!root.enabled) {
return Qt.rgba(127, 127, 127, 255)
}
if (root.error) {
return Qt.rgba(213, 40, 60, 255)
}
if (root.focus) {
return "#A7A7A7"
}
return "#A7A7A7"
}
return "#A7A7A7"
}
}
}
}

View file

@ -66,6 +66,7 @@ PageBase {
text: qsTr("Share for Amnezia")
height: 40
width: tb_c.width - 10
onClicked: UiLogic.onGotoShareProtocolPage(ProtocolEnum.Any)
}
ListView {
@ -350,63 +351,6 @@ PageBase {
// Item {
// width: 360
// height: 380
// Text {
// x: 10
// y: 280
// width: 341
// height: 111
// font.family: "Lato"
// font.styleName: "normal"
// font.pixelSize: 16
// color: "#181922"
// horizontalAlignment: Text.AlignLeft
// verticalAlignment: Text.AlignVCenter
// wrapMode: Text.Wrap
// text: qsTr("Anyone who logs in with this code will be able to connect to this VPN server. \nThis code does not include server credentials.")
// }
// ShareConnectionButtonType {
// x: 10
// y: 180
// width: 341
// height: 40
// text: ShareConnectionLogic.pushButtonShareAmneziaCopyText
// onClicked: {
// ShareConnectionLogic.onPushButtonShareAmneziaCopyClicked()
// }
// enabled: ShareConnectionLogic.pushButtonShareAmneziaCopyEnabled
// }
// ShareConnectionButtonType {
// x: 10
// y: 130
// width: 341
// height: 40
// text: ShareConnectionLogic.pushButtonShareAmneziaGenerateText
// enabled: ShareConnectionLogic.pushButtonShareAmneziaGenerateEnabled
// onClicked: {
// ShareConnectionLogic.onPushButtonShareAmneziaGenerateClicked()
// }
// }
// ShareConnectionButtonType {
// x: 10
// y: 230
// width: 341
// height: 40
// text: qsTr("Save file")
// onClicked: {
// ShareConnectionLogic.onPushButtonShareAmneziaSaveClicked()
// }
// }
// TextFieldType {
// x: 10
// y: 10
// width: 341
// height: 100
// verticalAlignment: Text.AlignTop
// text: ShareConnectionLogic.textEditShareAmneziaCodeText
// onEditingFinished: {
// ShareConnectionLogic.textEditShareAmneziaCodeText = text
// }
// }
// }
// }
// onClicked: {
@ -428,99 +372,7 @@ PageBase {
// Item {
// width: 360
// height: 380
// LabelType {
// x: 10
// y: 70
// width: 100
// height: 20
// text: qsTr("Password")
// }
// LabelType {
// x: 10
// y: 10
// width: 100
// height: 20
// text: qsTr("Server:")
// }
// LabelType {
// x: 10
// y: 50
// width: 100
// height: 20
// text: qsTr("Encryption:")
// }
// LabelType {
// x: 10
// y: 30
// width: 100
// height: 20
// text: qsTr("Port:")
// }
// LabelType {
// x: 10
// y: 100
// width: 191
// height: 20
// text: qsTr("Connection string")
// }
// LabelType {
// x: 130
// y: 70
// width: 100
// height: 20
// text: ShareConnectionLogic.labelShareShadowSocksPasswordText
// }
// LabelType {
// x: 130
// y: 10
// width: 100
// height: 20
// text: ShareConnectionLogic.labelShareShadowSocksServerText
// }
// LabelType {
// x: 130
// y: 50
// width: 100
// height: 20
// text: ShareConnectionLogic.labelShareShadowSocksMethodText
// }
// LabelType {
// x: 130
// y: 30
// width: 100
// height: 20
// text: ShareConnectionLogic.labelShareShadowSocksPortText
// }
// Image {
// id: label_share_ss_qr_code
// x: 85
// y: 235
// width: 200
// height: 200
// source: ShareConnectionLogic.labelShareShadowSocksQrCodeText === "" ? "" : "data:image/png;base64," + UiLogic.labelShareShadowSocksQrCodeText
// }
// ShareConnectionButtonType {
// x: 10
// y: 180
// width: 331
// height: 40
// text: ShareConnectionLogic.pushButtonShareShadowSocksCopyText
// enabled: ShareConnectionLogic.pushButtonShareShadowSocksCopyEnabled
// onClicked: {
// ShareConnectionLogic.onPushButtonShareShadowSocksCopyClicked()
// }
// }
// TextFieldType {
// x: 10
// y: 130
// width: 331
// height: 100
// horizontalAlignment: Text.AlignHCenter
// text: ShareConnectionLogic.lineEditShareShadowSocksStringText
// onEditingFinished: {
// ShareConnectionLogic.lineEditShareShadowSocksStringText = text
// }
// }
// }
// }
// onClicked: {

View file

@ -0,0 +1,90 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import ProtocolEnum 1.0
import "../"
import "../../Controls"
import "../../Config"
PageShareProtocolBase {
id: root
protocol: ProtocolEnum.Any
logic: ShareConnectionLogic
BackButton {
id: back
}
Caption {
id: caption
text: qsTr("Share for Amnezia")
}
Text {
id: lb_desc
anchors.top: caption.bottom
anchors.topMargin: 20
width: parent.width - 60
anchors.horizontalCenter: root.horizontalCenter
font.family: "Lato"
font.styleName: "normal"
font.pixelSize: 16
color: "#181922"
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
text: qsTr("Anyone who logs in with this code will be able to connect to this VPN server. \nThis code does not include server credentials.")
}
TextAreaType {
anchors.top: lb_desc.bottom
anchors.topMargin: 20
anchors.bottom: pb_gen.top
anchors.bottomMargin: 20
anchors.horizontalCenter: root.horizontalCenter
width: parent.width - 60
textArea.readOnly: true
textArea.wrapMode: TextEdit.WrapAnywhere
textArea.verticalAlignment: Text.AlignTop
textArea.text: ShareConnectionLogic.textEditShareAmneziaCodeText
}
ShareConnectionButtonType {
id: pb_gen
anchors.bottom: pb_copy.top
anchors.bottomMargin: 10
anchors.horizontalCenter: root.horizontalCenter
width: parent.width - 60
text: ShareConnectionLogic.pushButtonShareAmneziaGenerateText
enabled: ShareConnectionLogic.pushButtonShareAmneziaGenerateEnabled
onClicked: {
ShareConnectionLogic.onPushButtonShareAmneziaGenerateClicked()
}
}
ShareConnectionButtonType {
id: pb_copy
anchors.bottom: pb_save.top
anchors.bottomMargin: 10
anchors.horizontalCenter: root.horizontalCenter
width: parent.width - 60
text: ShareConnectionLogic.pushButtonShareAmneziaCopyText
onClicked: {
ShareConnectionLogic.onPushButtonShareAmneziaCopyClicked()
}
enabled: ShareConnectionLogic.pushButtonShareAmneziaCopyEnabled
}
ShareConnectionButtonType {
id: pb_save
anchors.bottom: root.bottom
anchors.bottomMargin: 10
anchors.horizontalCenter: root.horizontalCenter
width: parent.width - 60
text: qsTr("Save file")
onClicked: {
ShareConnectionLogic.onPushButtonShareAmneziaSaveClicked()
}
}
}

View file

@ -40,7 +40,7 @@ PageShareProtocolBase {
anchors.horizontalCenter: root.horizontalCenter
width: parent.width - 60
text: ShareConnectionLogic.pushButtonShareCloakCopyText
enabled: ShareConnectionLogic.pushButtonShareCloakCopyEnabled
//enabled: ShareConnectionLogic.pushButtonShareCloakCopyEnabled
onClicked: {
ShareConnectionLogic.onPushButtonShareCloakCopyClicked()
}

View file

@ -74,7 +74,4 @@ PageShareProtocolBase {
ShareConnectionLogic.onPushButtonShareOpenVpnSaveClicked()
}
}
}

View file

@ -31,18 +31,101 @@ PageShareProtocolBase {
anchors.right: root.right
anchors.rightMargin: 30
contentHeight: content.height
contentHeight: content.height + content2.height + 40
clip: true
ColumnLayout {
GridLayout {
id: content
enabled: logic.pageEnabled
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
columns: 2
//
LabelType {
height: 20
text: qsTr("Server:")
}
TextFieldType {
height: 20
text: ShareConnectionLogic.labelShareShadowSocksServerText
readOnly: true
}
//
LabelType {
height: 20
text: qsTr("Port:")
}
TextFieldType {
height: 20
text: ShareConnectionLogic.labelShareShadowSocksPortText
readOnly: true
}
//
LabelType {
height: 20
text: qsTr("Password")
}
TextFieldType {
height: 20
text: ShareConnectionLogic.labelShareShadowSocksPasswordText
readOnly: true
}
//
LabelType {
height: 20
text: qsTr("Encryption:")
}
TextFieldType {
height: 20
text: ShareConnectionLogic.labelShareShadowSocksMethodText
readOnly: true
}
}
}
ColumnLayout {
id: content2
enabled: logic.pageEnabled
anchors.top: content.bottom
anchors.topMargin: 20
anchors.left: parent.left
anchors.right: parent.right
LabelType {
height: 20
text: qsTr("Connection string")
}
TextFieldType {
id: tfConnString
height: 100
horizontalAlignment: Text.AlignHCenter
Layout.fillWidth: true
text: ShareConnectionLogic.lineEditShareShadowSocksStringText
readOnly: true
}
ShareConnectionButtonType {
height: 40
Layout.fillWidth: true
text: ShareConnectionLogic.pushButtonShareShadowSocksCopyText
enabled: tfConnString.length > 0
onClicked: {
ShareConnectionLogic.onPushButtonShareShadowSocksCopyClicked()
}
}
Image {
id: label_share_ss_qr_code
Layout.topMargin: 20
Layout.fillWidth: true
Layout.preferredHeight: width
smooth: false
source: ShareConnectionLogic.labelShareShadowSocksQrCodeText
}
}
}
}

View file

@ -104,7 +104,7 @@ Window {
color: "white"
}
//PageShareProtoCloak {}
//PageShareProtoAmnezia {}
StackView {
id: pageLoader