diff --git a/client/client.pro b/client/client.pro index c1366731e..226cf2227 100644 --- a/client/client.pro +++ b/client/client.pro @@ -34,7 +34,8 @@ HEADERS += \ protocols/shadowsocksvpnprotocol.h \ protocols/wireguardprotocol.h \ settings.h \ - ui/models/all_containers_model.h \ + ui/models/containers_model.h \ + ui/models/protocols_model.h \ ui/pages.h \ ui/pages_logic/AppSettingsLogic.h \ ui/pages_logic/GeneralSettingsLogic.h \ @@ -84,7 +85,8 @@ SOURCES += \ protocols/shadowsocksvpnprotocol.cpp \ protocols/wireguardprotocol.cpp \ settings.cpp \ - ui/models/all_containers_model.cpp \ + ui/models/containers_model.cpp \ + ui/models/protocols_model.cpp \ ui/pages_logic/AppSettingsLogic.cpp \ ui/pages_logic/GeneralSettingsLogic.cpp \ ui/pages_logic/NetworkSettingsLogic.cpp \ diff --git a/client/containers/containers_defs.cpp b/client/containers/containers_defs.cpp index c589d5248..6ecaee79c 100644 --- a/client/containers/containers_defs.cpp +++ b/client/containers/containers_defs.cpp @@ -46,6 +46,7 @@ QVector amnezia::protocolsForContainer(amnezia::DockerContain QVector amnezia::allContainers() { return QVector { + DockerContainer::None, DockerContainer::OpenVpn, DockerContainer::OpenVpnOverShadowSocks, DockerContainer::OpenVpnOverCloak, diff --git a/client/protocols/protocols_defs.cpp b/client/protocols/protocols_defs.cpp index 1f2b75420..9cc8e0a19 100644 --- a/client/protocols/protocols_defs.cpp +++ b/client/protocols/protocols_defs.cpp @@ -36,3 +36,30 @@ QVector amnezia::allProtocols() }; } + +QMap amnezia::protocolHumanNames() +{ + return { + {Protocol::OpenVpn, "OpenVPN"}, + {Protocol::ShadowSocks, "ShadowSocks"}, + {Protocol::Cloak, "Cloak"}, + {Protocol::WireGuard, "WireGuard"} + }; +} + +QMap amnezia::protocolDescriptions() +{ + return {}; +} + +bool amnezia::isProtocolVpnType(Protocol p) +{ + switch (p) { + case Protocol::Any : return false; + case Protocol::OpenVpn : return true; + case Protocol::Cloak : return true; + case Protocol::ShadowSocks : return true; + case Protocol::WireGuard : return true; + default: return false; + } +} diff --git a/client/protocols/protocols_defs.h b/client/protocols/protocols_defs.h index 9a87992f7..99c2b0962 100644 --- a/client/protocols/protocols_defs.h +++ b/client/protocols/protocols_defs.h @@ -125,6 +125,9 @@ QVector allProtocols(); Protocol protoFromString(QString proto); QString protoToString(Protocol proto); +QMap protocolHumanNames(); +QMap protocolDescriptions(); +bool isProtocolVpnType(Protocol p); } // namespace amnezia diff --git a/client/ui/models/all_containers_model.cpp b/client/ui/models/all_containers_model.cpp deleted file mode 100644 index 4d56136c7..000000000 --- a/client/ui/models/all_containers_model.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "all_containers_model.h" - -AllContainersModel::AllContainersModel(QObject *parent) : - QAbstractListModel(parent) -{ - -} - -int AllContainersModel::rowCount(const QModelIndex &parent) const -{ - Q_UNUSED(parent); - return amnezia::allContainers().size(); -} - -QHash AllContainersModel::roleNames() const { - QHash roles; - roles[NameRole] = "name"; - roles[DescRole] = "desc"; - roles[TypeRole] = "is_vpn"; - roles[InstalledRole] = "installed"; - return roles; -} - -QVariant AllContainersModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.row() < 0 - || index.row() >= amnezia::allContainers().size()) { - return QVariant(); - } - - DockerContainer c = amnezia::allContainers().at(index.row()); - if (role == NameRole) { - return containerHumanNames().value(c); - } - if (role == DescRole) { - return containerDescriptions().value(c); - } - if (role == TypeRole) { - return isContainerVpnType(c); - } - return QVariant(); -} - -void AllContainersModel::setServerData(const QJsonObject &server) -{ - beginResetModel(); - m_serverData = server; - endResetModel(); -} - - diff --git a/client/ui/models/containers_model.cpp b/client/ui/models/containers_model.cpp new file mode 100644 index 000000000..fe3d6c69d --- /dev/null +++ b/client/ui/models/containers_model.cpp @@ -0,0 +1,58 @@ +#include "containers_model.h" + +ContainersModel::ContainersModel(QObject *parent) : + QAbstractListModel(parent) +{ + +} + +int ContainersModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return amnezia::allContainers().size(); +} + +QHash ContainersModel::roleNames() const { + QHash roles; + roles[NameRole] = "name_role"; + roles[DescRole] = "desc_role"; + roles[isVpnTypeRole] = "is_vpn_role"; + roles[isOtherTypeRole] = "is_other_role"; + roles[isInstalledRole] = "is_installed_role"; + return roles; +} + +QVariant ContainersModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() < 0 + || index.row() >= amnezia::allContainers().size()) { + return QVariant(); + } + + DockerContainer c = amnezia::allContainers().at(index.row()); + if (role == NameRole) { + return containerHumanNames().value(c); + } + if (role == DescRole) { + return containerDescriptions().value(c); + } + if (role == isVpnTypeRole) { + return isContainerVpnType(c); + } +// if (role == isOtherTypeRole) { +// return isContainerVpnType(c) +// } + if (role == isInstalledRole) { + return m_settings.containers(m_selectedServerIndex).contains(c); + } + return QVariant(); +} + +void ContainersModel::setSelectedServerIndex(int index) +{ + beginResetModel(); + m_selectedServerIndex = index; + endResetModel(); +} + + diff --git a/client/ui/models/all_containers_model.h b/client/ui/models/containers_model.h similarity index 56% rename from client/ui/models/all_containers_model.h rename to client/ui/models/containers_model.h index c9fa2bf93..03a23d416 100644 --- a/client/ui/models/all_containers_model.h +++ b/client/ui/models/containers_model.h @@ -1,36 +1,39 @@ -#ifndef ALL_CONTAINERS_MODEL_H -#define ALL_CONTAINERS_MODEL_H +#ifndef CONTAINERS_MODEL_H +#define CONTAINERS_MODEL_H #include #include #include #include +#include "settings.h" #include "containers/containers_defs.h" -class AllContainersModel : public QAbstractListModel +class ContainersModel : public QAbstractListModel { Q_OBJECT public: - AllContainersModel(QObject *parent = nullptr); + ContainersModel(QObject *parent = nullptr); public: enum SiteRoles { NameRole = Qt::UserRole + 1, DescRole, - TypeRole, - InstalledRole + isVpnTypeRole, + isOtherTypeRole, + isInstalledRole }; int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - void setServerData(const QJsonObject &server); + void setSelectedServerIndex(int index); protected: QHash roleNames() const override; private: - QJsonObject m_serverData; + int m_selectedServerIndex; + Settings m_settings; }; -#endif // ALL_CONTAINERS_MODEL_H +#endif // CONTAINERS_MODEL_H diff --git a/client/ui/models/protocols_model.cpp b/client/ui/models/protocols_model.cpp new file mode 100644 index 000000000..32b941cd4 --- /dev/null +++ b/client/ui/models/protocols_model.cpp @@ -0,0 +1,65 @@ +#include "protocols_model.h" + +ProtocolsModel::ProtocolsModel(QObject *parent) : + QAbstractListModel(parent) +{ + +} + +int ProtocolsModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return amnezia::allContainers().size(); +} + +QHash ProtocolsModel::roleNames() const { + QHash roles; + roles[NameRole] = "name_role"; + roles[DescRole] = "desc_role"; + roles[isVpnTypeRole] = "is_vpn_role"; + roles[isOtherTypeRole] = "is_other_role"; + roles[isInstalledRole] = "is_installed_role"; + return roles; +} + +QVariant ProtocolsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() < 0 + || index.row() >= amnezia::allContainers().size()) { + return QVariant(); + } + + Protocol p = amnezia::allProtocols().at(index.row()); + if (role == NameRole) { + return protocolHumanNames().value(p); + } + if (role == DescRole) { + return protocolDescriptions().value(p); + } + if (role == isVpnTypeRole) { + return isProtocolVpnType(p); + } +// if (role == isOtherTypeRole) { +// return isContainerVpnType(c) +// } + if (role == isInstalledRole) { + return protocolsForContainer(m_selectedDockerContainer).contains(p); + } + return QVariant(); +} + +void ProtocolsModel::setSelectedServerIndex(int index) +{ + beginResetModel(); + m_selectedServerIndex = index; + endResetModel(); +} + +void ProtocolsModel::setSelectedDockerContainer(DockerContainer c) +{ + beginResetModel(); + m_selectedDockerContainer = c; + endResetModel(); +} + + diff --git a/client/ui/models/protocols_model.h b/client/ui/models/protocols_model.h new file mode 100644 index 000000000..64aa42a85 --- /dev/null +++ b/client/ui/models/protocols_model.h @@ -0,0 +1,41 @@ +#ifndef PROTOCOLS_MODEL_H +#define PROTOCOLS_MODEL_H + +#include +#include +#include +#include + +#include "settings.h" +#include "containers/containers_defs.h" + +class ProtocolsModel : public QAbstractListModel +{ + Q_OBJECT +public: + ProtocolsModel(QObject *parent = nullptr); +public: + enum SiteRoles { + NameRole = Qt::UserRole + 1, + DescRole, + isVpnTypeRole, + isOtherTypeRole, + isInstalledRole + }; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + void setSelectedServerIndex(int index); + void setSelectedDockerContainer(DockerContainer c); + +protected: + QHash roleNames() const override; + +private: + int m_selectedServerIndex; + DockerContainer m_selectedDockerContainer; + Settings m_settings; +}; + +#endif // PROTOCOLS_MODEL_H diff --git a/client/ui/pages_logic/ServerContainersLogic.cpp b/client/ui/pages_logic/ServerContainersLogic.cpp index 2751cb67a..c52b889a7 100644 --- a/client/ui/pages_logic/ServerContainersLogic.cpp +++ b/client/ui/pages_logic/ServerContainersLogic.cpp @@ -50,6 +50,9 @@ void ServerContainersLogic::updateServerContainersPage() { set_progressBarProtocolsContainerReinstallVisible(false); + ContainersModel *model = qobject_cast(uiLogic()->containersModel()); + model->setSelectedServerIndex(uiLogic()->selectedServerIndex); + auto containers = m_settings.containers(uiLogic()->selectedServerIndex); DockerContainer defaultContainer = m_settings.defaultContainer(uiLogic()->selectedServerIndex); bool haveAuthData = m_settings.haveAuthData(uiLogic()->selectedServerIndex); diff --git a/client/ui/qml/Controls/BlueButtonType.qml b/client/ui/qml/Controls/BlueButtonType.qml index d8b67283b..147a6d8be 100644 --- a/client/ui/qml/Controls/BlueButtonType.qml +++ b/client/ui/qml/Controls/BlueButtonType.qml @@ -12,7 +12,7 @@ BasicButtonType { background: Rectangle { anchors.fill: parent radius: 4 - color: root.containsMouse ? "#211966" : "#100A44" + color: root.enabled ? (root.containsMouse ? "#211966" : "#100A44") : "#888888" } font.pixelSize: 16 contentItem: Text { diff --git a/client/ui/qml/Controls/ComboBoxType.qml b/client/ui/qml/Controls/ComboBoxType.qml index 8243146a6..cdfdaf3ec 100644 --- a/client/ui/qml/Controls/ComboBoxType.qml +++ b/client/ui/qml/Controls/ComboBoxType.qml @@ -5,5 +5,7 @@ ComboBox { id: root font.family: "Lato" font.styleName: "normal" - font.pixelSize: 13 + font.pixelSize: 16 + + popup.font.pixelSize: 16 } diff --git a/client/ui/qml/Pages/InstallSettings/SelectContainer.qml b/client/ui/qml/Pages/InstallSettings/SelectContainer.qml index 2e434d4ac..5b766daac 100644 --- a/client/ui/qml/Pages/InstallSettings/SelectContainer.qml +++ b/client/ui/qml/Pages/InstallSettings/SelectContainer.qml @@ -8,6 +8,7 @@ Drawer { id: root signal containerSelected(int id) property alias selectedIndex: tb.currentIndex + property var filter: function (item){ return item.is_vpn_role } z: -3 @@ -20,10 +21,6 @@ Drawer { modal: true interactive: true - onClosed: { - tb.currentIndex = -1 - } - Flickable { clip: true anchors.fill: parent @@ -54,9 +51,18 @@ Drawer { spacing: 1 clip: true interactive: false - model: UiLogic.allContainersModel + model: UiLogic.containersModel delegate: Item { + required property int index + + required property string name_role + required property string desc_role + required property bool is_vpn_role + required property bool is_other_role + required property bool is_installed_role + + visible: filter(this) implicitWidth: 170 * 2 implicitHeight: 30 Item { @@ -79,8 +85,8 @@ Drawer { } Text { id: text_name - text: name - font.pointSize: 12 + text: name_role + font.pixelSize: 16 anchors.fill: parent leftPadding: 10 verticalAlignment: Text.AlignVCenter @@ -116,7 +122,7 @@ Drawer { // clip: true // interactive: false // property int currentRow: -1 -// model: UiLogic.allContainersModel +// model: UiLogic.containersModel // delegate: Item { // implicitWidth: 170 * 2 @@ -142,7 +148,7 @@ Drawer { // Text { // id: text_name_other // text: name -// font.pointSize: 12 +// font.pixelSize: 16 // anchors.fill: parent // leftPadding: 10 // verticalAlignment: Text.AlignVCenter diff --git a/client/ui/qml/Pages/PageNewServerProtocols.qml b/client/ui/qml/Pages/PageNewServerProtocols.qml index 63aa6abcc..cf06c74bc 100644 --- a/client/ui/qml/Pages/PageNewServerProtocols.qml +++ b/client/ui/qml/Pages/PageNewServerProtocols.qml @@ -1,5 +1,6 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.3 import "./" import "../Controls" import "../Config" @@ -17,6 +18,7 @@ Item { BlueButtonType { id: pushButtonConfigure + enabled: container_selector.selectedIndex > 0 anchors.horizontalCenter: parent.horizontalCenter y: parent.height - 60 width: parent.width - 40 @@ -27,7 +29,7 @@ Item { } } - RoundButton { + BlueButtonType { id: pb_add_container anchors.horizontalCenter: parent.horizontalCenter anchors.top: caption.bottom @@ -35,31 +37,63 @@ Item { width: parent.width - 40 height: 40 - text: qsTr("Add protocol") - font.pointSize: 12 - onClicked: drawer_menu.visible ? drawer_menu.close() : drawer_menu.open() + text: qsTr("Select protocol container") + font.pixelSize: 16 + onClicked: container_selector.visible ? container_selector.close() : container_selector.open() } SelectContainer { - id: drawer_menu + id: container_selector + //filter: function (){ return is_vpn_role } } + Column { + id: c1 + visible: container_selector.selectedIndex > 0 + width: parent.width + anchors.top: pb_add_container.bottom + anchors.topMargin: 10 + + Caption { + font.pixelSize: 22 + text: UiLogic.containerName(container_selector.selectedIndex) + } + + Text { + width: parent.width + anchors.topMargin: 10 + padding: 10 + + font.family: "Lato" + font.styleName: "normal" + font.pixelSize: 16 + color: "#181922" + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + wrapMode: Text.Wrap + + text: UiLogic.containerDesc(container_selector.selectedIndex) + } + } + + + Rectangle { id: frame_settings + visible: container_selector.selectedIndex > 0 width: parent.width - anchors.top: pb_add_container.bottom - anchors.bottom: parent.bottom + anchors.top: c1.bottom anchors.topMargin: 10 border.width: 1 border.color: "lightgray" anchors.bottomMargin: 5 anchors.horizontalCenter: parent.horizontalCenter - visible: false radius: 2 Grid { - id: container + id: grid + visible: container_selector.selectedIndex > 0 anchors.fill: parent columns: 2 horizontalItemAlignment: Grid.AlignHCenter @@ -71,12 +105,10 @@ Item { LabelType { width: 130 - height: (parent.height - parent.spacing - parent.topPadding * 2) / 2 text: qsTr("Port (TCP/UDP)") } TextFieldType { width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 - height: (parent.height - parent.spacing - parent.topPadding * 2) / 2 text: NewServerProtocolsLogic.lineEditOpenvpnPortText onEditingFinished: { NewServerProtocolsLogic.lineEditOpenvpnPortText = text @@ -84,12 +116,10 @@ Item { } LabelType { width: 130 - height: (parent.height - parent.spacing - parent.topPadding * 2) / 2 text: qsTr("Protocol") } ComboBoxType { width: parent.width - 130 - parent.spacing - parent.leftPadding * 2 - height: (parent.height - parent.spacing - parent.topPadding * 2) / 2 model: [ qsTr("udp"), qsTr("tcp"), diff --git a/client/ui/qml/Pages/PageServerContainers.qml b/client/ui/qml/Pages/PageServerContainers.qml index 3efc920cc..fb7fd50c5 100644 --- a/client/ui/qml/Pages/PageServerContainers.qml +++ b/client/ui/qml/Pages/PageServerContainers.qml @@ -3,6 +3,7 @@ import QtQuick.Controls 2.12 import "./" import "../Controls" import "../Config" +import "InstallSettings" Item { id: root @@ -11,446 +12,565 @@ Item { id: back } Caption { + id: caption text: qsTr("Protocols") } - ProgressBar { - id: progress_bar + BlueButtonType { + id: pb_add_container anchors.horizontalCenter: parent.horizontalCenter - y: 570 - width: 301 + anchors.top: caption.bottom + anchors.topMargin: 10 + + width: parent.width - 40 height: 40 - from: 0 - to: ServerContainersLogic.progressBarProtocolsContainerReinstallMaximium - value: ServerContainersLogic.progressBarProtocolsContainerReinstallValue - visible: ServerContainersLogic.progressBarProtocolsContainerReinstallVisible - background: Rectangle { - implicitWidth: parent.width - implicitHeight: parent.height - color: "#100A44" - radius: 4 - } + text: qsTr("Add protocols container") + font.pixelSize: 16 + onClicked: container_selector.visible ? container_selector.close() : container_selector.open() - contentItem: Item { - implicitWidth: parent.width - implicitHeight: parent.height - Rectangle { - width: progress_bar.visualPosition * parent.width - height: parent.height - radius: 4 - color: Qt.rgba(255, 255, 255, 0.15); - } - } - - LabelType { - anchors.fill: parent - text: qsTr("Configuring...") - horizontalAlignment: Text.AlignHCenter - font.family: "Lato" - font.styleName: "normal" - font.pixelSize: 16 - color: "#D4D4D4" - } } - ScrollView { - x: 0 - y: 70 - width: 380 - height: 471 + SelectContainer { + id: container_selector + filter: function (item){ return ! item.is_installed_role && (item.is_vpn_role || item.is_other_role)} + } + + Flickable { clip: true + width: parent.width + anchors.top: pb_add_container.bottom + anchors.bottom: parent.bottom + contentHeight: col.height + Column { - spacing: 5 - Rectangle { - id: frame_openvpn_ss_cloak - x: 9 - height: 135 - width: 363 - border.width: 1 - border.color: "lightgray" - radius: 2 - visible: ServerContainersLogic.frameOpenvpnSsCloakSettingsVisible - Item { - x: 5 - y: 5 - width: parent.width - 10 - height: parent.height - 10 - LabelType { - anchors.left: parent.left - width: 239 - height: 24 - text: qsTr("Cloak container") - leftPadding: 5 - } - ImageButtonType { - anchors.right: sr1.left - anchors.rightMargin: 5 - checkable: true - icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" - width: 24 - height: 24 - checked: ServerContainersLogic.pushButtonCloakOpenVpnContDefaultChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonCloakOpenVpnContDefaultChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoCloakOpenVpnContDefaultClicked(checked) - } - - visible: ServerContainersLogic.pushButtonCloakOpenVpnContDefaultVisible - } - - ImageButtonType { - id: sr1 - anchors.right: cn1.left - anchors.rightMargin: 5 - icon.source: "qrc:/images/share.png" - width: 24 - height: 24 - visible: ServerContainersLogic.pushButtonCloakOpenVpnContShareVisible - onClicked: { - ServerContainersLogic.onPushButtonProtoCloakOpenVpnContShareClicked(false) - } - } - ImageButtonType { - id: cn1 - anchors.right: parent.right - checkable: true - icon.source: checked ? "qrc:/images/connect_button_connected.png" - : "qrc:/images/connect_button_disconnected.png" - width: 36 - height: 24 - checked: ServerContainersLogic.pushButtonCloakOpenVpnContInstallChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonCloakOpenVpnContInstallChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoCloakOpenVpnContInstallClicked(checked) - } - enabled: ServerContainersLogic.pushButtonCloakOpenVpnContInstallEnabled - } - } - Rectangle { - x: 10 - y: 42 - height: 83 - width: 343 - border.width: 1 - border.color: "lightgray" - radius: 2 - SettingButtonType { - x: 10 - y: 10 - width: 323 - height: 24 - text: qsTr("OpenVPN settings") - icon.source: "qrc:/images/settings.png" - onClicked: { - ServerContainersLogic.onPushButtonProtoCloakOpenVpnContOpenvpnConfigClicked() - } - } - SettingButtonType { - x: 10 - y: 33 - width: 323 - height: 24 - text: qsTr("ShadowSocks settings") - icon.source: "qrc:/images/settings.png" - onClicked: { - ServerContainersLogic.onPushButtonProtoCloakOpenVpnContSsConfigClicked() - } - } - SettingButtonType { - x: 10 - y: 56 - width: 323 - height: 24 - text: qsTr("Cloak settings") - icon.source: "qrc:/images/settings.png" - onClicked: { - ServerContainersLogic.onPushButtonProtoCloakOpenVpnContCloakConfigClicked() - } - } - } + id: col + anchors { + left: parent.left; + right: parent.right; } - Rectangle { - id: frame_openvpn_ss - x: 9 - height: 105 - width: 363 - border.width: 1 - border.color: "lightgray" - radius: 2 - visible: ServerContainersLogic.frameOpenvpnSsSettingsVisible - Item { - x: 5 - y: 5 - width: parent.width - 10 - height: parent.height - 10 - LabelType { - anchors.left: parent.left - width: 239 - height: 24 - text: qsTr("ShadowSocks container") - leftPadding: 5 - } - ImageButtonType { - anchors.right: sr2.left - anchors.rightMargin: 5 - checkable: true - icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" - width: 24 - height: 24 - checked: ServerContainersLogic.pushButtonSsOpenVpnContDefaultChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonSsOpenVpnContDefaultChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoSsOpenVpnContDefaultClicked(checked) - } + topPadding: 20 + spacing: 10 - visible: ServerContainersLogic.pushButtonSsOpenVpnContDefaultVisible - } + Caption { + id: cap1 + text: qsTr("Installed VPN containers") + font.pixelSize: 20 - ImageButtonType { - id: sr2 - anchors.right: cn2.left - anchors.rightMargin: 5 - icon.source: "qrc:/images/share.png" - width: 24 - height: 24 - visible: ServerContainersLogic.pushButtonSsOpenVpnContShareVisible - onClicked: { - ServerContainersLogic.onPushButtonProtoSsOpenVpnContShareClicked(false) - } - } - ImageButtonType { - id: cn2 - anchors.right: parent.right - checkable: true - icon.source: checked ? "qrc:/images/connect_button_connected.png" - : "qrc:/images/connect_button_disconnected.png" - width: 36 - height: 24 - checked: ServerContainersLogic.pushButtonSsOpenVpnContInstallChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonSsOpenVpnContInstallChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoSsOpenVpnContInstallClicked(checked) - } - enabled: ServerContainersLogic.pushButtonSsOpenVpnContInstallEnabled - } - } - Rectangle { - x: 10 - y: 42 - height: 53 - width: 343 - border.width: 1 - border.color: "lightgray" - radius: 2 - SettingButtonType { - x: 10 - y: 5 - width: 323 - height: 24 - text: qsTr("OpenVPN settings") - icon.source: "qrc:/images/settings.png" - onClicked: { - ServerContainersLogic.onPushButtonProtoSsOpenVpnContOpenvpnConfigClicked() - } - } - SettingButtonType { - x: 10 - y: 27 - width: 323 - height: 24 - text: qsTr("ShadowSocks settings") - icon.source: "qrc:/images/settings.png" - onClicked: { - ServerContainersLogic.onPushButtonProtoSsOpenVpnContSsConfigClicked() - } - } - } } - Rectangle { - id: frame_openvpn - x: 9 - height: 100 - width: 363 - border.width: 1 - border.color: "lightgray" - radius: 2 - visible: ServerContainersLogic.frameOpenvpnSettingsVisible - Item { - x: 5 - y: 5 - width: parent.width - 10 - height: parent.height - 10 - LabelType { + + ListView { + id: tb + x: 10 + width: parent.width - 40 + height: contentItem.height + + spacing: 1 + clip: true + interactive: false + model: UiLogic.containersModel + + delegate: Item { + required property int index + + required property string name_role + required property string desc_role + required property bool is_vpn_role + required property bool is_other_role + required property bool is_installed_role + + visible: true + implicitWidth: 170 * 2 + implicitHeight: 30 + Item { + width: parent.width + height: 30 anchors.left: parent.left - width: 239 - height: 24 - text: qsTr("OpenVPN container") - leftPadding: 5 - } - ImageButtonType { - anchors.right: sr3.left - anchors.rightMargin: 5 - checkable: true - icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" - width: 24 - height: 24 - checked: ServerContainersLogic.pushButtonOpenVpnContDefaultChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonOpenVpnContDefaultChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoOpenVpnContDefaultClicked(checked) + id: c1 + Rectangle { + anchors.top: parent.top + width: parent.width + height: 1 + color: "lightgray" + visible: index !== tb.currentIndex } + Rectangle { + anchors.fill: parent + color: "#63B4FB" + visible: index === tb.currentIndex - visible: ServerContainersLogic.pushButtonOpenVpnContDefaultVisible + } + Text { + id: text_name + text: name_role + font.pixelSize: 16 + anchors.fill: parent + leftPadding: 10 + verticalAlignment: Text.AlignVCenter + wrapMode: Text.WordWrap + } } - ImageButtonType { - id: sr3 - anchors.right: cn3.left - anchors.rightMargin: 5 - icon.source: "qrc:/images/share.png" - width: 24 - height: 24 - visible: ServerContainersLogic.pushButtonOpenVpnContShareVisible + MouseArea { + anchors.fill: parent onClicked: { - ServerContainersLogic.onPushButtonProtoOpenVpnContShareClicked(false) + tb.currentIndex = index + containerSelected(index) + root.close() } } - ImageButtonType { - id: cn3 - anchors.right: parent.right - checkable: true - icon.source: checked ? "qrc:/images/connect_button_connected.png" - : "qrc:/images/connect_button_disconnected.png" - width: 36 - height: 24 - checked: ServerContainersLogic.pushButtonOpenVpnContInstallChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonOpenVpnContInstallChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoOpenVpnContInstallClicked(checked) - } - enabled: ServerContainersLogic.pushButtonOpenVpnContInstallEnabled - } - } - Rectangle { - x: 10 - y: 42 - height: 44 - width: 343 - border.width: 1 - border.color: "lightgray" - radius: 2 - SettingButtonType { - x: 10 - y: 10 - width: 323 - height: 24 - text: qsTr("OpenVPN settings") - icon.source: "qrc:/images/settings.png" - onClicked: { - ServerContainersLogic.onPushButtonProtoOpenVpnContOpenvpnConfigClicked() - } - } - } - } - Rectangle { - id: frame_wireguard - x: 9 - height: 100 - width: 363 - border.width: 1 - border.color: "lightgray" - radius: 2 - visible: ServerContainersLogic.frameWireguardVisible - Item { - x: 5 - y: 5 - width: parent.width - 10 - height: parent.height - 10 - LabelType { - anchors.left: parent.left - width: 239 - height: 24 - text: qsTr("WireGuard container") - leftPadding: 5 - } - ImageButtonType { - anchors.right: sr4.left - anchors.rightMargin: 5 - checkable: true - icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" - width: 24 - height: 24 - checked: ServerContainersLogic.pushButtonWireguardContDefaultChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonWireguardContDefaultChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoWireguardContDefaultClicked(checked) - } - - visible: ServerContainersLogic.pushButtonWireguardContDefaultVisible - } - - ImageButtonType { - id: sr4 - anchors.right: cn4.left - anchors.rightMargin: 5 - icon.source: "qrc:/images/share.png" - width: 24 - height: 24 - visible: ServerContainersLogic.pushButtonWireguardContShareVisible - onClicked: { - ServerContainersLogic.onPushButtonProtoWireguardContShareClicked(false) - } - } - ImageButtonType { - id: cn4 - anchors.right: parent.right - checkable: true - icon.source: checked ? "qrc:/images/connect_button_connected.png" - : "qrc:/images/connect_button_disconnected.png" - width: 36 - height: 24 - checked: ServerContainersLogic.pushButtonWireguardContInstallChecked - onCheckedChanged: { - ServerContainersLogic.pushButtonWireguardContInstallChecked = checked - } - onClicked: { - ServerContainersLogic.onPushButtonProtoWireguardContInstallClicked(checked) - } - enabled: ServerContainersLogic.pushButtonWireguardContInstallEnabled - } - } - Rectangle { - id: frame_wireguard_settings - visible: ServerContainersLogic.frameWireguardSettingsVisible - x: 10 - y: 42 - height: 44 - width: 343 - border.width: 1 - border.color: "lightgray" - radius: 2 - SettingButtonType { - x: 10 - y: 10 - width: 323 - height: 24 - text: qsTr("WireGuard settings") - icon.source: "qrc:/images/settings.png" - } } } } + + } + + + + + + + + + + + +// ProgressBar { +// id: progress_bar +// anchors.horizontalCenter: parent.horizontalCenter +// y: 570 +// width: 301 +// height: 40 +// from: 0 +// to: ServerContainersLogic.progressBarProtocolsContainerReinstallMaximium +// value: ServerContainersLogic.progressBarProtocolsContainerReinstallValue +// visible: ServerContainersLogic.progressBarProtocolsContainerReinstallVisible +// background: Rectangle { +// implicitWidth: parent.width +// implicitHeight: parent.height +// color: "#100A44" +// radius: 4 +// } + +// contentItem: Item { +// implicitWidth: parent.width +// implicitHeight: parent.height +// Rectangle { +// width: progress_bar.visualPosition * parent.width +// height: parent.height +// radius: 4 +// color: Qt.rgba(255, 255, 255, 0.15); +// } +// } + +// LabelType { +// anchors.fill: parent +// text: qsTr("Configuring...") +// horizontalAlignment: Text.AlignHCenter +// font.family: "Lato" +// font.styleName: "normal" +// font.pixelSize: 16 +// color: "#D4D4D4" +// } +// } +// ScrollView { +// x: 0 +// y: 190 +// width: 380 +// height: 471 +// clip: true +// Column { +// spacing: 5 +// Rectangle { +// id: frame_openvpn_ss_cloak +// x: 9 +// height: 135 +// width: 363 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// visible: ServerContainersLogic.frameOpenvpnSsCloakSettingsVisible +// Item { +// x: 5 +// y: 5 +// width: parent.width - 10 +// height: parent.height - 10 +// LabelType { +// anchors.left: parent.left +// width: 239 +// height: 24 +// text: qsTr("Cloak container") +// leftPadding: 5 +// } +// ImageButtonType { +// anchors.right: sr1.left +// anchors.rightMargin: 5 +// checkable: true +// icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" +// width: 24 +// height: 24 +// checked: ServerContainersLogic.pushButtonCloakOpenVpnContDefaultChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonCloakOpenVpnContDefaultChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoCloakOpenVpnContDefaultClicked(checked) +// } + +// visible: ServerContainersLogic.pushButtonCloakOpenVpnContDefaultVisible +// } + +// ImageButtonType { +// id: sr1 +// anchors.right: cn1.left +// anchors.rightMargin: 5 +// icon.source: "qrc:/images/share.png" +// width: 24 +// height: 24 +// visible: ServerContainersLogic.pushButtonCloakOpenVpnContShareVisible +// onClicked: { +// ServerContainersLogic.onPushButtonProtoCloakOpenVpnContShareClicked(false) +// } +// } +// ImageButtonType { +// id: cn1 +// anchors.right: parent.right +// checkable: true +// icon.source: checked ? "qrc:/images/connect_button_connected.png" +// : "qrc:/images/connect_button_disconnected.png" +// width: 36 +// height: 24 +// checked: ServerContainersLogic.pushButtonCloakOpenVpnContInstallChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonCloakOpenVpnContInstallChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoCloakOpenVpnContInstallClicked(checked) +// } +// enabled: ServerContainersLogic.pushButtonCloakOpenVpnContInstallEnabled +// } +// } +// Rectangle { +// x: 10 +// y: 42 +// height: 83 +// width: 343 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// SettingButtonType { +// x: 10 +// y: 10 +// width: 323 +// height: 24 +// text: qsTr("OpenVPN settings") +// icon.source: "qrc:/images/settings.png" +// onClicked: { +// ServerContainersLogic.onPushButtonProtoCloakOpenVpnContOpenvpnConfigClicked() +// } +// } +// SettingButtonType { +// x: 10 +// y: 33 +// width: 323 +// height: 24 +// text: qsTr("ShadowSocks settings") +// icon.source: "qrc:/images/settings.png" +// onClicked: { +// ServerContainersLogic.onPushButtonProtoCloakOpenVpnContSsConfigClicked() +// } +// } +// SettingButtonType { +// x: 10 +// y: 56 +// width: 323 +// height: 24 +// text: qsTr("Cloak settings") +// icon.source: "qrc:/images/settings.png" +// onClicked: { +// ServerContainersLogic.onPushButtonProtoCloakOpenVpnContCloakConfigClicked() +// } +// } +// } +// } +// Rectangle { +// id: frame_openvpn_ss +// x: 9 +// height: 105 +// width: 363 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// visible: ServerContainersLogic.frameOpenvpnSsSettingsVisible +// Item { +// x: 5 +// y: 5 +// width: parent.width - 10 +// height: parent.height - 10 +// LabelType { +// anchors.left: parent.left +// width: 239 +// height: 24 +// text: qsTr("ShadowSocks container") +// leftPadding: 5 +// } +// ImageButtonType { +// anchors.right: sr2.left +// anchors.rightMargin: 5 +// checkable: true +// icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" +// width: 24 +// height: 24 +// checked: ServerContainersLogic.pushButtonSsOpenVpnContDefaultChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonSsOpenVpnContDefaultChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoSsOpenVpnContDefaultClicked(checked) +// } + +// visible: ServerContainersLogic.pushButtonSsOpenVpnContDefaultVisible +// } + +// ImageButtonType { +// id: sr2 +// anchors.right: cn2.left +// anchors.rightMargin: 5 +// icon.source: "qrc:/images/share.png" +// width: 24 +// height: 24 +// visible: ServerContainersLogic.pushButtonSsOpenVpnContShareVisible +// onClicked: { +// ServerContainersLogic.onPushButtonProtoSsOpenVpnContShareClicked(false) +// } +// } +// ImageButtonType { +// id: cn2 +// anchors.right: parent.right +// checkable: true +// icon.source: checked ? "qrc:/images/connect_button_connected.png" +// : "qrc:/images/connect_button_disconnected.png" +// width: 36 +// height: 24 +// checked: ServerContainersLogic.pushButtonSsOpenVpnContInstallChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonSsOpenVpnContInstallChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoSsOpenVpnContInstallClicked(checked) +// } +// enabled: ServerContainersLogic.pushButtonSsOpenVpnContInstallEnabled +// } +// } +// Rectangle { +// x: 10 +// y: 42 +// height: 53 +// width: 343 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// SettingButtonType { +// x: 10 +// y: 5 +// width: 323 +// height: 24 +// text: qsTr("OpenVPN settings") +// icon.source: "qrc:/images/settings.png" +// onClicked: { +// ServerContainersLogic.onPushButtonProtoSsOpenVpnContOpenvpnConfigClicked() +// } +// } +// SettingButtonType { +// x: 10 +// y: 27 +// width: 323 +// height: 24 +// text: qsTr("ShadowSocks settings") +// icon.source: "qrc:/images/settings.png" +// onClicked: { +// ServerContainersLogic.onPushButtonProtoSsOpenVpnContSsConfigClicked() +// } +// } +// } +// } +// Rectangle { +// id: frame_openvpn +// x: 9 +// height: 100 +// width: 363 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// visible: ServerContainersLogic.frameOpenvpnSettingsVisible +// Item { +// x: 5 +// y: 5 +// width: parent.width - 10 +// height: parent.height - 10 +// LabelType { +// anchors.left: parent.left +// width: 239 +// height: 24 +// text: qsTr("OpenVPN container") +// leftPadding: 5 +// } +// ImageButtonType { +// anchors.right: sr3.left +// anchors.rightMargin: 5 +// checkable: true +// icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" +// width: 24 +// height: 24 +// checked: ServerContainersLogic.pushButtonOpenVpnContDefaultChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonOpenVpnContDefaultChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoOpenVpnContDefaultClicked(checked) +// } + +// visible: ServerContainersLogic.pushButtonOpenVpnContDefaultVisible +// } + +// ImageButtonType { +// id: sr3 +// anchors.right: cn3.left +// anchors.rightMargin: 5 +// icon.source: "qrc:/images/share.png" +// width: 24 +// height: 24 +// visible: ServerContainersLogic.pushButtonOpenVpnContShareVisible +// onClicked: { +// ServerContainersLogic.onPushButtonProtoOpenVpnContShareClicked(false) +// } +// } +// ImageButtonType { +// id: cn3 +// anchors.right: parent.right +// checkable: true +// icon.source: checked ? "qrc:/images/connect_button_connected.png" +// : "qrc:/images/connect_button_disconnected.png" +// width: 36 +// height: 24 +// checked: ServerContainersLogic.pushButtonOpenVpnContInstallChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonOpenVpnContInstallChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoOpenVpnContInstallClicked(checked) +// } +// enabled: ServerContainersLogic.pushButtonOpenVpnContInstallEnabled +// } +// } +// Rectangle { +// x: 10 +// y: 42 +// height: 44 +// width: 343 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// SettingButtonType { +// x: 10 +// y: 10 +// width: 323 +// height: 24 +// text: qsTr("OpenVPN settings") +// icon.source: "qrc:/images/settings.png" +// onClicked: { +// ServerContainersLogic.onPushButtonProtoOpenVpnContOpenvpnConfigClicked() +// } +// } +// } +// } +// Rectangle { +// id: frame_wireguard +// x: 9 +// height: 100 +// width: 363 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// visible: ServerContainersLogic.frameWireguardVisible +// Item { +// x: 5 +// y: 5 +// width: parent.width - 10 +// height: parent.height - 10 +// LabelType { +// anchors.left: parent.left +// width: 239 +// height: 24 +// text: qsTr("WireGuard container") +// leftPadding: 5 +// } +// ImageButtonType { +// anchors.right: sr4.left +// anchors.rightMargin: 5 +// checkable: true +// icon.source: checked ? "qrc:/images/check.png" : "qrc:/images/uncheck.png" +// width: 24 +// height: 24 +// checked: ServerContainersLogic.pushButtonWireguardContDefaultChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonWireguardContDefaultChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoWireguardContDefaultClicked(checked) +// } + +// visible: ServerContainersLogic.pushButtonWireguardContDefaultVisible +// } + +// ImageButtonType { +// id: sr4 +// anchors.right: cn4.left +// anchors.rightMargin: 5 +// icon.source: "qrc:/images/share.png" +// width: 24 +// height: 24 +// visible: ServerContainersLogic.pushButtonWireguardContShareVisible +// onClicked: { +// ServerContainersLogic.onPushButtonProtoWireguardContShareClicked(false) +// } +// } +// ImageButtonType { +// id: cn4 +// anchors.right: parent.right +// checkable: true +// icon.source: checked ? "qrc:/images/connect_button_connected.png" +// : "qrc:/images/connect_button_disconnected.png" +// width: 36 +// height: 24 +// checked: ServerContainersLogic.pushButtonWireguardContInstallChecked +// onCheckedChanged: { +// ServerContainersLogic.pushButtonWireguardContInstallChecked = checked +// } +// onClicked: { +// ServerContainersLogic.onPushButtonProtoWireguardContInstallClicked(checked) +// } +// enabled: ServerContainersLogic.pushButtonWireguardContInstallEnabled +// } +// } +// Rectangle { +// id: frame_wireguard_settings +// visible: ServerContainersLogic.frameWireguardSettingsVisible +// x: 10 +// y: 42 +// height: 44 +// width: 343 +// border.width: 1 +// border.color: "lightgray" +// radius: 2 +// SettingButtonType { +// x: 10 +// y: 10 +// width: 323 +// height: 24 +// text: qsTr("WireGuard settings") +// icon.source: "qrc:/images/settings.png" +// } +// } +// } +// } +// } } diff --git a/client/ui/uilogic.cpp b/client/ui/uilogic.cpp index c6d7e57f5..56dcee8af 100644 --- a/client/ui/uilogic.cpp +++ b/client/ui/uilogic.cpp @@ -74,7 +74,7 @@ UiLogic::UiLogic(QObject *parent) : m_trayActionConnectEnabled{true}, m_dialogConnectErrorText{} { - m_allContainersModel = new AllContainersModel(this); + m_containersModel = new ContainersModel(this); m_vpnConnection = new VpnConnection(this); m_appSettingsLogic = new AppSettingsLogic(this); @@ -123,6 +123,11 @@ void UiLogic::initalizeUiLogic() goToPage(Page::Vpn, true, false); } + selectedServerIndex = m_settings.defaultServerIndex(); + goToPage(Page::ServerContainers, true, false); + //goToPage(Page::NewServerProtocols, true, false); + + // //ui->pushButton_general_settings_exit->hide(); @@ -341,6 +346,17 @@ void UiLogic::onCloseWindow() } } +QString UiLogic::containerName(int container) +{ + return amnezia::containerHumanNames().value(static_cast(container)); +} + +QString UiLogic::containerDesc(int container) +{ + return amnezia::containerDescriptions().value(static_cast(container)); + +} + //void UiLogic::showEvent(QShowEvent *event) diff --git a/client/ui/uilogic.h b/client/ui/uilogic.h index 6399b1858..1a185d69a 100644 --- a/client/ui/uilogic.h +++ b/client/ui/uilogic.h @@ -9,7 +9,7 @@ #include "pages.h" #include "protocols/vpnprotocol.h" #include "containers/containers_defs.h" -#include "models/all_containers_model.h" +#include "models/containers_model.h" #include "settings.h" @@ -38,7 +38,7 @@ class UiLogic : public QObject { Q_OBJECT - READONLY_PROPERTY(QObject *, allContainersModel) + READONLY_PROPERTY(QObject *, containersModel) Q_PROPERTY(int currentPageValue READ getCurrentPageValue WRITE setCurrentPageValue NOTIFY currentPageValueChanged) Q_PROPERTY(QString trayIconUrl READ getTrayIconUrl WRITE setTrayIconUrl NOTIFY trayIconUrlChanged) @@ -73,6 +73,10 @@ public: Q_INVOKABLE void initalizeUiLogic(); Q_INVOKABLE void onCloseWindow(); + Q_INVOKABLE QString containerName(int container); + Q_INVOKABLE QString containerDesc(int container); + + int getCurrentPageValue() const; void setCurrentPageValue(int currentPageValue);