Added tab navigation functional. (#721)
- Added tab navigation functional. - In basic types added parentFlickable property, which will help to ensure, that the item is visible within flickable parent during tab navigation. - Added focus state for some basic types. - In PageType qml file added lastItemTabClicked function, which will help to focus tab bar buttons when the last tab on the current page clicked. - Added Focus for back button for all pages and drawers. - Added scroll on tab for Servers ListView on PageHome.
This commit is contained in:
parent
d50e7dd3f4
commit
0e4ae26bae
66 changed files with 2269 additions and 143 deletions
|
|
@ -123,6 +123,9 @@ signals:
|
||||||
void escapePressed();
|
void escapePressed();
|
||||||
void closeTopDrawer();
|
void closeTopDrawer();
|
||||||
|
|
||||||
|
void forceTabBarActiveFocus();
|
||||||
|
void forceStackActiveFocus();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,26 @@ Button {
|
||||||
verticalOffset: 0
|
verticalOffset: 0
|
||||||
radius: 10
|
radius: 10
|
||||||
samples: 25
|
samples: 25
|
||||||
color: "#FBB26A"
|
color: root.activeFocus ? "#D7D8DB" : "#FBB26A"
|
||||||
source: backgroundCircle
|
source: backgroundCircle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShapePath {
|
||||||
|
fillColor: "transparent"
|
||||||
|
strokeColor: "#D7D8DB"
|
||||||
|
strokeWidth: root.activeFocus ? 1 : 0
|
||||||
|
capStyle: ShapePath.RoundCap
|
||||||
|
|
||||||
|
PathAngleArc {
|
||||||
|
centerX: backgroundCircle.width / 2
|
||||||
|
centerY: backgroundCircle.height / 2
|
||||||
|
radiusX: 94
|
||||||
|
radiusY: 94
|
||||||
|
startAngle: 0
|
||||||
|
sweepAngle: 360
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShapePath {
|
ShapePath {
|
||||||
fillColor: "transparent"
|
fillColor: "transparent"
|
||||||
strokeColor: {
|
strokeColor: {
|
||||||
|
|
@ -64,14 +80,14 @@ Button {
|
||||||
return defaultButtonColor
|
return defaultButtonColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strokeWidth: 3
|
strokeWidth: root.activeFocus ? 2 : 3
|
||||||
capStyle: ShapePath.RoundCap
|
capStyle: ShapePath.RoundCap
|
||||||
|
|
||||||
PathAngleArc {
|
PathAngleArc {
|
||||||
centerX: backgroundCircle.width / 2
|
centerX: backgroundCircle.width / 2
|
||||||
centerY: backgroundCircle.height / 2
|
centerY: backgroundCircle.height / 2
|
||||||
radiusX: 93
|
radiusX: 93 - (root.activeFocus ? 2 : 0)
|
||||||
radiusY: 93
|
radiusY: 93 - (root.activeFocus ? 2 : 0)
|
||||||
startAngle: 0
|
startAngle: 0
|
||||||
sweepAngle: 360
|
sweepAngle: 360
|
||||||
}
|
}
|
||||||
|
|
@ -141,4 +157,7 @@ Button {
|
||||||
ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
|
ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
|
||||||
ConnectionController.connectButtonClicked()
|
ConnectionController.connectButtonClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: this.clicked()
|
||||||
|
Keys.onReturnPressed: this.clicked()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,14 @@ DrawerType2 {
|
||||||
root.expandedHeight = content.implicitHeight + 32
|
root.expandedHeight = content.implicitHeight + 32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
|
|
@ -36,6 +44,11 @@ DrawerType2 {
|
||||||
headerText: qsTr("Add new connection")
|
headerText: qsTr("Add new connection")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: ip.rightButton
|
||||||
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: ip
|
id: ip
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -48,11 +61,14 @@ DrawerType2 {
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
|
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: qrCode.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: qrCode
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Open config file, key or QR code")
|
text: qsTr("Open config file, key or QR code")
|
||||||
|
|
@ -62,6 +78,8 @@ DrawerType2 {
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: focusItem
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,56 @@ ListView {
|
||||||
property var rootWidth
|
property var rootWidth
|
||||||
property var selectedText
|
property var selectedText
|
||||||
|
|
||||||
|
property bool a: true
|
||||||
|
|
||||||
width: rootWidth
|
width: rootWidth
|
||||||
height: menuContent.contentItem.height
|
height: menuContent.contentItem.height
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
property FlickableType parentFlickable
|
||||||
|
property var lastItemTabClicked
|
||||||
|
|
||||||
|
property int currentFocusIndex: 0
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
this.currentFocusIndex = 0
|
||||||
|
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentFocusIndex < this.count - 1) {
|
||||||
|
currentFocusIndex += 1
|
||||||
|
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
currentFocusIndex = 0
|
||||||
|
if (lastItemTabClicked && typeof lastItemTabClicked === "function") {
|
||||||
|
lastItemTabClicked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
currentFocusIndex = 0
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentFocusIndexChanged: {
|
||||||
|
if (parentFlickable) {
|
||||||
|
parentFlickable.ensureVisible(this.itemAtIndex(currentFocusIndex))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ButtonGroup {
|
ButtonGroup {
|
||||||
id: containersRadioButtonGroup
|
id: containersRadioButtonGroup
|
||||||
}
|
}
|
||||||
|
|
@ -31,6 +75,12 @@ ListView {
|
||||||
implicitWidth: rootWidth
|
implicitWidth: rootWidth
|
||||||
implicitHeight: content.implicitHeight
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
containerRadioButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
|
|
@ -76,6 +126,19 @@ ListView {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (checkable) {
|
||||||
|
checked = true
|
||||||
|
}
|
||||||
|
containerRadioButton.clicked()
|
||||||
|
}
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (checkable) {
|
||||||
|
checked = true
|
||||||
|
}
|
||||||
|
containerRadioButton.clicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {
|
DividerType {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,14 @@ DrawerType2 {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
|
|
@ -35,7 +43,13 @@ DrawerType2 {
|
||||||
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
|
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: splitTunnelingSwitch.visible ? splitTunnelingSwitch : siteBasedSplitTunnelingSwitch.rightButton
|
||||||
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: splitTunnelingSwitch
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
|
@ -45,6 +59,8 @@ DrawerType2 {
|
||||||
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
|
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: siteBasedSplitTunnelingSwitch.visible ? siteBasedSplitTunnelingSwitch.rightButton : focusItem
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||||
// root.close()
|
// root.close()
|
||||||
|
|
@ -56,6 +72,7 @@ DrawerType2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: siteBasedSplitTunnelingSwitch
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
|
@ -63,6 +80,10 @@ DrawerType2 {
|
||||||
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: appSplitTunnelingSwitch.visible ?
|
||||||
|
appSplitTunnelingSwitch.rightButton :
|
||||||
|
focusItem
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||||
root.close()
|
root.close()
|
||||||
|
|
@ -73,6 +94,7 @@ DrawerType2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: appSplitTunnelingSwitch
|
||||||
visible: isAppSplitTinnelingEnabled
|
visible: isAppSplitTinnelingEnabled
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -81,6 +103,8 @@ DrawerType2 {
|
||||||
descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: focusItem
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
||||||
root.close()
|
root.close()
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import QtQuick.Layouts
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
|
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
DrawerType2 {
|
DrawerType2 {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
|
@ -29,6 +31,14 @@ DrawerType2 {
|
||||||
root.expandedHeight = content.implicitHeight + 32
|
root.expandedHeight = content.implicitHeight + 32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Header2TextType {
|
Header2TextType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
@ -47,7 +57,13 @@ DrawerType2 {
|
||||||
text: descriptionText
|
text: descriptionText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: yesButton
|
||||||
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: yesButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
|
@ -60,9 +76,12 @@ DrawerType2 {
|
||||||
yesButtonFunction()
|
yesButtonFunction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: noButton
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: noButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
@ -81,6 +100,8 @@ DrawerType2 {
|
||||||
noButtonFunction()
|
noButtonFunction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: focusItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import QtQuick.Layouts
|
||||||
|
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
DrawerType2 {
|
DrawerType2 {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -17,8 +18,21 @@ DrawerType2 {
|
||||||
root.expandedHeight = container.implicitHeight
|
root.expandedHeight = container.implicitHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -26,15 +40,15 @@ DrawerType2 {
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
backButtonImage: "qrc:/images/controls/arrow-left.svg"
|
backButtonImage: "qrc:/images/controls/arrow-left.svg"
|
||||||
backButtonFunction: function() {
|
backButtonFunction: function() { root.close() }
|
||||||
root.close()
|
KeyNavigation.tab: listView
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
@ -71,10 +85,50 @@ DrawerType2 {
|
||||||
id: buttonGroup
|
id: buttonGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property int currentFocusIndex: 0
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
this.currentFocusIndex = 0
|
||||||
|
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentFocusIndex < this.count - 1) {
|
||||||
|
currentFocusIndex += 1
|
||||||
|
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
listViewFocusItem.forceActiveFocus()
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: listViewFocusItem
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
root.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
listViewFocusItem.forceActiveFocus()
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: root.width
|
implicitWidth: root.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
radioButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
|
|
@ -89,12 +143,18 @@ DrawerType2 {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
anchors.fill: parent
|
width: parent.width - 1
|
||||||
|
height: parent.height
|
||||||
color: radioButton.hovered ? "#2C2D30" : "#1C1D21"
|
color: radioButton.hovered ? "#2C2D30" : "#1C1D21"
|
||||||
|
border.color: radioButton.focus ? "#D7D8DB" : "transparent"
|
||||||
|
border.width: radioButton.focus ? 1 : 0
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
Behavior on border.color {
|
||||||
|
PropertyAnimation { duration: 200 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -137,6 +197,9 @@ DrawerType2 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: radioButton.clicked()
|
||||||
|
Keys.onReturnPressed: radioButton.clicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,16 +22,52 @@ ListView {
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentIndex < this.count - 1) {
|
||||||
|
this.incrementCurrentIndex()
|
||||||
|
} else {
|
||||||
|
currentIndex = 0
|
||||||
|
lastItemTabClickedSignal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
if (visible) {
|
||||||
|
if (fl.contentHeight > fl.height) {
|
||||||
|
var item = this.currentItem
|
||||||
|
if (item.y < fl.height) {
|
||||||
|
fl.contentY = item.y
|
||||||
|
} else if (item.y + item.height > fl.contentY + fl.height) {
|
||||||
|
fl.contentY = item.y + item.height - fl.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
this.currentIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: root.width
|
implicitWidth: root.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
containerRadioButton.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: containerRadioButton
|
||||||
implicitWidth: parent.width
|
implicitWidth: parent.width
|
||||||
|
|
||||||
text: name
|
text: name
|
||||||
|
|
|
||||||
|
|
@ -121,6 +121,9 @@ DrawerType2 {
|
||||||
text: qsTr("Copy")
|
text: qsTr("Copy")
|
||||||
imageSource: "qrc:/images/controls/copy.svg"
|
imageSource: "qrc:/images/controls/copy.svg"
|
||||||
|
|
||||||
|
Keys.onReturnPressed: { copyConfigTextButton.clicked() }
|
||||||
|
Keys.onEnterPressed: { copyConfigTextButton.clicked() }
|
||||||
|
|
||||||
KeyNavigation.tab: copyNativeConfigStringButton.visible ? copyNativeConfigStringButton : showSettingsButton
|
KeyNavigation.tab: copyNativeConfigStringButton.visible ? copyNativeConfigStringButton : showSettingsButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -174,11 +177,30 @@ DrawerType2 {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: parent.height * 0.9
|
expandedHeight: parent.height * 0.9
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
header.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expandedContent: Item {
|
expandedContent: Item {
|
||||||
id: configContentContainer
|
id: configContentContainer
|
||||||
|
|
||||||
implicitHeight: configContentDrawer.expandedHeight
|
implicitHeight: configContentDrawer.expandedHeight
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: configContentDrawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: copyNativeConfigStringButton
|
target: copyNativeConfigStringButton
|
||||||
function onClicked() {
|
function onClicked() {
|
||||||
|
|
@ -196,6 +218,7 @@ DrawerType2 {
|
||||||
configText.copy()
|
configText.copy()
|
||||||
configText.select(0, 0)
|
configText.select(0, 0)
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
PageController.showNotificationMessage(qsTr("Copied"))
|
||||||
|
header.forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -207,9 +230,9 @@ DrawerType2 {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
backButtonFunction: function() {
|
backButtonFunction: function() { configContentDrawer.close() }
|
||||||
configContentDrawer.close()
|
|
||||||
}
|
KeyNavigation.tab: focusItem
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -256,6 +279,7 @@ DrawerType2 {
|
||||||
height: 24
|
height: 24
|
||||||
|
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
activeFocusOnTab: false
|
||||||
|
|
||||||
color: "#D7D8DB"
|
color: "#D7D8DB"
|
||||||
selectionColor: "#633303"
|
selectionColor: "#633303"
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,19 @@ Rectangle {
|
||||||
color: "#1C1D21"
|
color: "#1C1D21"
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (focus) {
|
||||||
|
udpButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: transportProtoButtonGroup
|
id: transportProtoButtonGroup
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
HorizontalRadioButton {
|
HorizontalRadioButton {
|
||||||
|
id: udpButton
|
||||||
checked: root.currentIndex === 0
|
checked: root.currentIndex === 0
|
||||||
|
|
||||||
hoverEnabled: root.enabled
|
hoverEnabled: root.enabled
|
||||||
|
|
@ -30,12 +37,15 @@ Rectangle {
|
||||||
implicitWidth: (rootWidth - 32) / 2
|
implicitWidth: (rootWidth - 32) / 2
|
||||||
text: "UDP"
|
text: "UDP"
|
||||||
|
|
||||||
|
KeyNavigation.tab: tcpButton
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
root.currentIndex = 0
|
root.currentIndex = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalRadioButton {
|
HorizontalRadioButton {
|
||||||
|
id: tcpButton
|
||||||
checked: root.currentIndex === 1
|
checked: root.currentIndex === 1
|
||||||
|
|
||||||
hoverEnabled: root.enabled
|
hoverEnabled: root.enabled
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,12 @@ Item {
|
||||||
|
|
||||||
visible: backButtonImage !== ""
|
visible: backButtonImage !== ""
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
backButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
|
|
@ -20,6 +26,7 @@ Item {
|
||||||
anchors.leftMargin: 8
|
anchors.leftMargin: 8
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
id: backButton
|
||||||
image: backButtonImage
|
image: backButtonImage
|
||||||
imageColor: "#D7D8DB"
|
imageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
|
@ -42,4 +49,7 @@ Item {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: backButton.clicked()
|
||||||
|
Keys.onReturnPressed: backButton.clicked()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,18 +26,29 @@ Button {
|
||||||
|
|
||||||
property bool squareLeftSide: false
|
property bool squareLeftSide: false
|
||||||
|
|
||||||
|
property FlickableType parentFlickable
|
||||||
|
|
||||||
property var clickedFunc
|
property var clickedFunc
|
||||||
|
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
focusPolicy: Qt.TabFocus
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (root.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
id: focusBorder
|
id: focusBorder
|
||||||
|
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
||||||
border.width: root.activeFocus ? root.borderFocusedWidth : "transparent"
|
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ CheckBox {
|
||||||
property string checkedBorderColor: "#FBB26A"
|
property string checkedBorderColor: "#FBB26A"
|
||||||
property string checkedBorderDisabledColor: "#402102"
|
property string checkedBorderDisabledColor: "#402102"
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
|
||||||
property string checkedImageColor: "#FBB26A"
|
property string checkedImageColor: "#FBB26A"
|
||||||
property string pressedImageColor: "#A85809"
|
property string pressedImageColor: "#A85809"
|
||||||
property string defaultImageColor: "transparent"
|
property string defaultImageColor: "transparent"
|
||||||
|
|
@ -30,7 +32,24 @@ CheckBox {
|
||||||
|
|
||||||
property string imageSource: "qrc:/images/controls/check.svg"
|
property string imageSource: "qrc:/images/controls/check.svg"
|
||||||
|
|
||||||
|
property var parentFlickable
|
||||||
|
onFocusChanged: {
|
||||||
|
if (root.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hoverEnabled: enabled ? true : false
|
hoverEnabled: enabled ? true : false
|
||||||
|
focusPolicy: Qt.NoFocus
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: "transparent"
|
||||||
|
border.color: root.focus ? borderFocusedColor : "transparent"
|
||||||
|
border.width: 1
|
||||||
|
radius: 16
|
||||||
|
}
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: background
|
id: background
|
||||||
|
|
@ -59,7 +78,11 @@ CheckBox {
|
||||||
width: 24
|
width: 24
|
||||||
height: 24
|
height: 24
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: root.checked ? (root.enabled ? checkedBorderColor : checkedBorderDisabledColor) : defaultBorderColor
|
border.color: root.checked ?
|
||||||
|
(root.enabled ?
|
||||||
|
checkedBorderColor :
|
||||||
|
checkedBorderDisabledColor) :
|
||||||
|
defaultBorderColor
|
||||||
border.width: 1
|
border.width: 1
|
||||||
radius: 4
|
radius: 4
|
||||||
|
|
||||||
|
|
@ -130,6 +153,16 @@ CheckBox {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
root.checked = !root.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
root.checked = !root.checked
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import QtQuick.Controls
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
|
||||||
import "TextTypes"
|
import "TextTypes"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
@ -27,6 +28,9 @@ Item {
|
||||||
property string rootButtonBackgroundHoveredColor: "#1C1D21"
|
property string rootButtonBackgroundHoveredColor: "#1C1D21"
|
||||||
property string rootButtonBackgroundPressedColor: "#1C1D21"
|
property string rootButtonBackgroundPressedColor: "#1C1D21"
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
property string rootButtonHoveredBorderColor: "#494B50"
|
property string rootButtonHoveredBorderColor: "#494B50"
|
||||||
property string rootButtonDefaultBorderColor: "#2C2D30"
|
property string rootButtonDefaultBorderColor: "#2C2D30"
|
||||||
property string rootButtonPressedBorderColor: "#D7D8DB"
|
property string rootButtonPressedBorderColor: "#D7D8DB"
|
||||||
|
|
@ -42,44 +46,70 @@ Item {
|
||||||
signal open
|
signal open
|
||||||
signal close
|
signal close
|
||||||
|
|
||||||
|
function popupClosedFunc() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
this.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property var parentFlickable
|
||||||
|
onFocusChanged: {
|
||||||
|
if (root.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
implicitWidth: rootButtonContent.implicitWidth
|
implicitWidth: rootButtonContent.implicitWidth
|
||||||
implicitHeight: rootButtonContent.implicitHeight
|
implicitHeight: rootButtonContent.implicitHeight
|
||||||
|
|
||||||
onOpen: {
|
onOpen: {
|
||||||
menu.open()
|
menu.open()
|
||||||
rootButtonBackground.border.color = rootButtonPressedBorderColor
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose: {
|
onClose: {
|
||||||
menu.close()
|
menu.close()
|
||||||
rootButtonBackground.border.color = rootButtonDefaultBorderColor
|
|
||||||
}
|
|
||||||
|
|
||||||
onEnabledChanged: {
|
|
||||||
if (enabled) {
|
|
||||||
rootButtonBackground.color = rootButtonBackgroundColor
|
|
||||||
rootButtonBackground.border.color = rootButtonDefaultBorderColor
|
|
||||||
} else {
|
|
||||||
rootButtonBackground.color = "transparent"
|
|
||||||
rootButtonBackground.border.color = rootButtonHoveredBorderColor
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: rootButtonBackground
|
id: focusBorder
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
||||||
|
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
||||||
anchors.fill: rootButtonContent
|
anchors.fill: rootButtonContent
|
||||||
|
|
||||||
radius: 16
|
radius: 16
|
||||||
color: root.enabled ? rootButtonBackgroundColor : "transparent"
|
|
||||||
border.color: root.enabled ? rootButtonDefaultBorderColor : rootButtonHoveredBorderColor
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
Behavior on border.color {
|
|
||||||
PropertyAnimation { duration: 200 }
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on color {
|
Rectangle {
|
||||||
PropertyAnimation { duration: 200 }
|
id: rootButtonBackground
|
||||||
|
|
||||||
|
anchors.fill: focusBorder
|
||||||
|
anchors.margins: root.activeFocus ? 2 : 0
|
||||||
|
radius: root.activeFocus ? 14 : 16
|
||||||
|
|
||||||
|
color: {
|
||||||
|
if (root.enabled) {
|
||||||
|
if (root.pressed) {
|
||||||
|
return root.rootButtonBackgroundPressedColor
|
||||||
|
}
|
||||||
|
return root.hovered ? root.rootButtonBackgroundHoveredColor : root.rootButtonBackgroundColor
|
||||||
|
} else {
|
||||||
|
return "transparent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
border.color: rootButtonDefaultBorderColor
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
PropertyAnimation { duration: 200 }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
PropertyAnimation { duration: 200 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,6 +137,7 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonTextType {
|
ButtonTextType {
|
||||||
|
id: buttonText
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
horizontalAlignment: Text.AlignLeft
|
horizontalAlignment: Text.AlignLeft
|
||||||
|
|
@ -136,26 +167,6 @@ Item {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
hoverEnabled: root.enabled ? true : false
|
hoverEnabled: root.enabled ? true : false
|
||||||
|
|
||||||
onEntered: {
|
|
||||||
if (menu.isClosed) {
|
|
||||||
rootButtonBackground.border.color = rootButtonHoveredBorderColor
|
|
||||||
rootButtonBackground.color = rootButtonBackgroundHoveredColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: {
|
|
||||||
if (menu.isClosed) {
|
|
||||||
rootButtonBackground.border.color = rootButtonDefaultBorderColor
|
|
||||||
rootButtonBackground.color = rootButtonBackgroundColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onPressed: {
|
|
||||||
if (menu.isClosed) {
|
|
||||||
rootButtonBackground.color = pressed ? rootButtonBackgroundPressedColor : entered ? rootButtonHoveredBorderColor : rootButtonDefaultBorderColor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (rootButtonClickedFunction && typeof rootButtonClickedFunction === "function") {
|
if (rootButtonClickedFunction && typeof rootButtonClickedFunction === "function") {
|
||||||
rootButtonClickedFunction()
|
rootButtonClickedFunction()
|
||||||
|
|
@ -173,11 +184,27 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: drawerParent.height * drawerHeight
|
expandedHeight: drawerParent.height * drawerHeight
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
root.popupClosedFunc()
|
||||||
|
}
|
||||||
|
|
||||||
expandedContent: Item {
|
expandedContent: Item {
|
||||||
id: container
|
id: container
|
||||||
|
|
||||||
implicitHeight: menu.expandedHeight
|
implicitHeight: menu.expandedHeight
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: menu
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: header
|
id: header
|
||||||
|
|
||||||
|
|
@ -187,14 +214,15 @@ Item {
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
backButtonImage: root.headerBackButtonImage
|
backButtonImage: root.headerBackButtonImage
|
||||||
backButtonFunction: function() {
|
backButtonFunction: function() { menu.close() }
|
||||||
menu.close()
|
KeyNavigation.tab: listViewLoader.item
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
id: flickable
|
||||||
anchors.top: header.bottom
|
anchors.top: header.bottom
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
contentHeight: col.implicitHeight
|
contentHeight: col.implicitHeight
|
||||||
|
|
@ -221,9 +249,28 @@ Item {
|
||||||
Loader {
|
Loader {
|
||||||
id: listViewLoader
|
id: listViewLoader
|
||||||
sourceComponent: root.listView
|
sourceComponent: root.listView
|
||||||
|
|
||||||
|
onLoaded: {
|
||||||
|
listViewLoader.item.parentFlickable = flickable
|
||||||
|
listViewLoader.item.lastItemTabClicked = function() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (menu.isClosed) {
|
||||||
|
menu.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (menu.isClosed) {
|
||||||
|
menu.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,14 @@ import "../Config"
|
||||||
Flickable {
|
Flickable {
|
||||||
id: fl
|
id: fl
|
||||||
|
|
||||||
|
function ensureVisible(item) {
|
||||||
|
if (item.y < fl.contentY) {
|
||||||
|
fl.contentY = item.y
|
||||||
|
} else if (item.y + item.height > fl.contentY + fl.height) {
|
||||||
|
fl.contentY = item.y + item.height - fl.height + 40 // 40 is a bottom margin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ Item {
|
||||||
property string actionButtonImage
|
property string actionButtonImage
|
||||||
property var actionButtonFunction
|
property var actionButtonFunction
|
||||||
|
|
||||||
|
property alias actionButton: headerActionButton
|
||||||
|
|
||||||
property string headerText
|
property string headerText
|
||||||
property string descriptionText
|
property string descriptionText
|
||||||
|
|
||||||
|
|
@ -60,4 +62,16 @@ Item {
|
||||||
visible: root.descriptionText !== ""
|
visible: root.descriptionText !== ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
||||||
|
actionButtonFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
||||||
|
actionButtonFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,16 @@ Item {
|
||||||
property string actionButtonImage
|
property string actionButtonImage
|
||||||
property var actionButtonFunction
|
property var actionButtonFunction
|
||||||
|
|
||||||
|
property alias actionButton: headerActionButton
|
||||||
|
|
||||||
property string headerText
|
property string headerText
|
||||||
property int headerTextMaximumLineCount: 2
|
property int headerTextMaximumLineCount: 2
|
||||||
property int headerTextElide: Qt.ElideRight
|
property int headerTextElide: Qt.ElideRight
|
||||||
|
|
||||||
property string descriptionText
|
property string descriptionText
|
||||||
|
|
||||||
|
focus: true
|
||||||
|
|
||||||
implicitWidth: content.implicitWidth
|
implicitWidth: content.implicitWidth
|
||||||
implicitHeight: content.implicitHeight
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -67,4 +71,16 @@ Item {
|
||||||
visible: root.descriptionText !== ""
|
visible: root.descriptionText !== ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
||||||
|
actionButtonFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (actionButtonFunction && typeof actionButtonFunction === "function") {
|
||||||
|
actionButtonFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ RadioButton {
|
||||||
property string checkedBorderColor: "#FBB26A"
|
property string checkedBorderColor: "#FBB26A"
|
||||||
property string defaultBodredColor: "transparent"
|
property string defaultBodredColor: "transparent"
|
||||||
property string checkedDisabledBorderColor: "#84603D"
|
property string checkedDisabledBorderColor: "#84603D"
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
property int borderWidth: 0
|
property int borderWidth: 0
|
||||||
|
|
||||||
implicitWidth: content.implicitWidth
|
implicitWidth: content.implicitWidth
|
||||||
|
|
@ -47,6 +48,8 @@ RadioButton {
|
||||||
return root.pressedBorderColor
|
return root.pressedBorderColor
|
||||||
} else if (root.checked) {
|
} else if (root.checked) {
|
||||||
return root.checkedBorderColor
|
return root.checkedBorderColor
|
||||||
|
} else if (root.activeFocus) {
|
||||||
|
return root.borderFocusedColor
|
||||||
}
|
}
|
||||||
return root.defaultBodredColor
|
return root.defaultBodredColor
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -58,7 +61,7 @@ RadioButton {
|
||||||
}
|
}
|
||||||
|
|
||||||
border.width: {
|
border.width: {
|
||||||
if(root.checked) {
|
if(root.checked || root.activeFocus) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return root.pressed ? 1 : 0
|
return root.pressed ? 1 : 0
|
||||||
|
|
@ -97,4 +100,12 @@ RadioButton {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
this.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
this.clicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,26 @@ Button {
|
||||||
property alias backgroundColor: background.color
|
property alias backgroundColor: background.color
|
||||||
property alias backgroundRadius: background.radius
|
property alias backgroundRadius: background.radius
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
focus: true
|
||||||
|
focusPolicy: Qt.TabFocus
|
||||||
|
|
||||||
icon.source: image
|
icon.source: image
|
||||||
icon.color: root.enabled ? imageColor : disableImageColor
|
icon.color: root.enabled ? imageColor : disableImageColor
|
||||||
|
|
||||||
|
property Flickable parentFlickable
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (root.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on icon.color {
|
Behavior on icon.color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
|
@ -31,6 +46,9 @@ Button {
|
||||||
id: background
|
id: background
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
||||||
|
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
||||||
|
|
||||||
color: {
|
color: {
|
||||||
if (root.enabled) {
|
if (root.enabled) {
|
||||||
if (root.pressed) {
|
if (root.pressed) {
|
||||||
|
|
@ -44,6 +62,9 @@ Button {
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
Behavior on border.color {
|
||||||
|
PropertyAnimation { duration: 200 }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,18 @@ Item {
|
||||||
property string leftImageSource
|
property string leftImageSource
|
||||||
property bool isLeftImageHoverEnabled: true //todo separete this qml file to 3
|
property bool isLeftImageHoverEnabled: true //todo separete this qml file to 3
|
||||||
|
|
||||||
|
property alias rightButton: rightImage
|
||||||
|
property FlickableType parentFlickable
|
||||||
|
|
||||||
property string textColor: "#d7d8db"
|
property string textColor: "#d7d8db"
|
||||||
property string textDisabledColor: "#878B91"
|
property string textDisabledColor: "#878B91"
|
||||||
property string descriptionColor: "#878B91"
|
property string descriptionColor: "#878B91"
|
||||||
property string descriptionDisabledColor: "#494B50"
|
property string descriptionDisabledColor: "#494B50"
|
||||||
property real textOpacity: 1.0
|
property real textOpacity: 1.0
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
property string rightImageColor: "#d7d8db"
|
property string rightImageColor: "#d7d8db"
|
||||||
|
|
||||||
property bool descriptionOnTop: false
|
property bool descriptionOnTop: false
|
||||||
|
|
@ -32,6 +38,25 @@ Item {
|
||||||
implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
|
implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
|
||||||
implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
|
implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (root.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: rightImage
|
||||||
|
function onFocusChanged() {
|
||||||
|
if (rightImage.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: content
|
id: content
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -163,6 +188,9 @@ Item {
|
||||||
anchors.fill: root
|
anchors.fill: root
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
||||||
|
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
||||||
|
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
|
|
@ -207,4 +235,16 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (clickedFunction && typeof clickedFunction === "function") {
|
||||||
|
clickedFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (clickedFunction && typeof clickedFunction === "function") {
|
||||||
|
clickedFunction()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,47 @@ ListView {
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
property FlickableType parentFlickable
|
||||||
|
property var lastItemTabClicked
|
||||||
|
|
||||||
|
property int currentFocusIndex: 0
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
this.currentFocusIndex = 0
|
||||||
|
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentFocusIndex < this.count - 1) {
|
||||||
|
currentFocusIndex += 1
|
||||||
|
} else {
|
||||||
|
currentFocusIndex = 0
|
||||||
|
}
|
||||||
|
this.itemAtIndex(currentFocusIndex).forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
root.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentFocusIndexChanged: {
|
||||||
|
if (parentFlickable) {
|
||||||
|
parentFlickable.ensureVisible(this.itemAtIndex(currentFocusIndex))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ButtonGroup {
|
ButtonGroup {
|
||||||
id: buttonGroup
|
id: buttonGroup
|
||||||
}
|
}
|
||||||
|
|
@ -40,6 +81,12 @@ ListView {
|
||||||
implicitWidth: rootWidth
|
implicitWidth: rootWidth
|
||||||
implicitHeight: content.implicitHeight
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
radioButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
|
|
@ -54,12 +101,18 @@ ListView {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
anchors.fill: parent
|
width: parent.width - 1
|
||||||
|
height: parent.height
|
||||||
color: radioButton.hovered ? "#2C2D30" : "#1C1D21"
|
color: radioButton.hovered ? "#2C2D30" : "#1C1D21"
|
||||||
|
border.color: radioButton.focus ? "#D7D8DB" : "transparent"
|
||||||
|
border.width: radioButton.focus ? 1 : 0
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
Behavior on border.color {
|
||||||
|
PropertyAnimation { duration: 200 }
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -117,5 +170,13 @@ ListView {
|
||||||
root.selectedText = name
|
root.selectedText = name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
radioButton.clicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
radioButton.clicked()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,28 @@ Item {
|
||||||
|
|
||||||
property var defaultActiveFocusItem: null
|
property var defaultActiveFocusItem: null
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible && !GC.isMobile()) {
|
||||||
|
timer.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function lastItemTabClicked(focusItem) {
|
||||||
|
if (GC.isMobile()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (focusItem) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
PageController.forceTabBarActiveFocus()
|
||||||
|
} else {
|
||||||
|
if (defaultActiveFocusItem) {
|
||||||
|
defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
PageController.forceTabBarActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MouseArea {
|
// MouseArea {
|
||||||
// id: globalMouseArea
|
// id: globalMouseArea
|
||||||
// z: 99
|
// z: 99
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,14 @@ Popup {
|
||||||
color: Qt.rgba(14/255, 14/255, 17/255, 0.8)
|
color: Qt.rgba(14/255, 14/255, 17/255, 0.8)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onOpened: {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
PageController.forceStackActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|
@ -52,7 +60,13 @@ Popup {
|
||||||
text: root.text
|
text: root.text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: closeButton
|
||||||
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: closeButton
|
||||||
visible: closeButtonVisible
|
visible: closeButtonVisible
|
||||||
|
|
||||||
implicitHeight: 32
|
implicitHeight: 32
|
||||||
|
|
@ -66,6 +80,8 @@ Popup {
|
||||||
borderWidth: 0
|
borderWidth: 0
|
||||||
|
|
||||||
text: qsTr("Close")
|
text: qsTr("Close")
|
||||||
|
KeyNavigation.tab: focusItem
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
root.close()
|
root.close()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,9 @@ Switch {
|
||||||
property string defaultIndicatorColor: "transparent"
|
property string defaultIndicatorColor: "transparent"
|
||||||
property string checkedDisabledIndicatorColor: "#402102"
|
property string checkedDisabledIndicatorColor: "#402102"
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
property string checkedIndicatorBorderColor: "#633303"
|
property string checkedIndicatorBorderColor: "#633303"
|
||||||
property string defaultIndicatorBorderColor: "#494B50"
|
property string defaultIndicatorBorderColor: "#494B50"
|
||||||
property string checkedDisabledIndicatorBorderColor: "#402102"
|
property string checkedDisabledIndicatorBorderColor: "#402102"
|
||||||
|
|
@ -31,6 +34,16 @@ Switch {
|
||||||
property string defaultIndicatorBackgroundColor: "transparent"
|
property string defaultIndicatorBackgroundColor: "transparent"
|
||||||
|
|
||||||
hoverEnabled: enabled ? true : false
|
hoverEnabled: enabled ? true : false
|
||||||
|
focusPolicy: Qt.TabFocus
|
||||||
|
|
||||||
|
property FlickableType parentFlickable: null
|
||||||
|
onFocusChanged: {
|
||||||
|
if (root.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: switcher
|
id: switcher
|
||||||
|
|
@ -44,8 +57,9 @@ Switch {
|
||||||
radius: 16
|
radius: 16
|
||||||
color: root.checked ? (root.enabled ? root.checkedIndicatorColor : root.checkedDisabledIndicatorColor)
|
color: root.checked ? (root.enabled ? root.checkedIndicatorColor : root.checkedDisabledIndicatorColor)
|
||||||
: root.defaultIndicatorColor
|
: root.defaultIndicatorColor
|
||||||
border.color: root.checked ? (root.enabled ? root.checkedIndicatorBorderColor : root.checkedDisabledIndicatorBorderColor)
|
|
||||||
: root.defaultIndicatorBorderColor
|
border.color: root.activeFocus ? root.borderFocusedColor : (root.checked ? (root.enabled ? root.checkedIndicatorBorderColor : root.checkedDisabledIndicatorBorderColor)
|
||||||
|
: root.defaultIndicatorBorderColor)
|
||||||
|
|
||||||
Behavior on color {
|
Behavior on color {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
|
|
@ -114,4 +128,14 @@ Switch {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
root.checked = !root.checked
|
||||||
|
root.checkedChanged()
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
root.checked = !root.checked
|
||||||
|
root.checkedChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,15 @@ TabButton {
|
||||||
|
|
||||||
property string textColor: "#D7D8DB"
|
property string textColor: "#D7D8DB"
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
property bool isSelected: false
|
property bool isSelected: false
|
||||||
|
|
||||||
implicitHeight: 48
|
implicitHeight: 48
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
focusPolicy: Qt.TabFocus
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
id: background
|
id: background
|
||||||
|
|
@ -22,6 +26,9 @@ TabButton {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
||||||
|
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 1
|
height: 1
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,13 @@ TabButton {
|
||||||
|
|
||||||
property bool isSelected: false
|
property bool isSelected: false
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
|
property var clickedFunc
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
focusPolicy: Qt.TabFocus
|
||||||
|
|
||||||
icon.source: image
|
icon.source: image
|
||||||
icon.color: isSelected ? selectedColor : defaultColor
|
icon.color: isSelected ? selectedColor : defaultColor
|
||||||
|
|
@ -21,6 +27,11 @@ TabButton {
|
||||||
id: background
|
id: background
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
radius: 10
|
||||||
|
|
||||||
|
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
|
||||||
|
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
@ -28,4 +39,22 @@ TabButton {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: {
|
||||||
|
if (root.clickedFunc && typeof root.clickedFunc === "function") {
|
||||||
|
root.clickedFunc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: {
|
||||||
|
if (root.clickedFunc && typeof root.clickedFunc === "function") {
|
||||||
|
root.clickedFunc()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (root.clickedFunc && typeof root.clickedFunc === "function") {
|
||||||
|
root.clickedFunc()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ Rectangle {
|
||||||
border.color: getBorderColor(borderNormalColor)
|
border.color: getBorderColor(borderNormalColor)
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
||||||
|
property FlickableType parentFlickable: null
|
||||||
|
onFocusChanged: {
|
||||||
|
if (root.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: parentMouse
|
id: parentMouse
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ Item {
|
||||||
|
|
||||||
property alias errorText: errorField.text
|
property alias errorText: errorField.text
|
||||||
property bool checkEmptyText: false
|
property bool checkEmptyText: false
|
||||||
|
property bool rightButtonClickedOnEnter: false
|
||||||
|
|
||||||
property string buttonText
|
property string buttonText
|
||||||
property string buttonImageSource
|
property string buttonImageSource
|
||||||
|
|
@ -36,6 +37,18 @@ Item {
|
||||||
implicitWidth: content.implicitWidth
|
implicitWidth: content.implicitWidth
|
||||||
implicitHeight: content.implicitHeight
|
implicitHeight: content.implicitHeight
|
||||||
|
|
||||||
|
property FlickableType parentFlickable
|
||||||
|
Connections {
|
||||||
|
target: textField
|
||||||
|
function onFocusChanged() {
|
||||||
|
if (textField.activeFocus) {
|
||||||
|
if (root.parentFlickable) {
|
||||||
|
root.parentFlickable.ensureVisible(root)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: content
|
id: content
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
@ -188,10 +201,22 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onEnterPressed: {
|
Keys.onEnterPressed: {
|
||||||
KeyNavigation.tab.forceActiveFocus();
|
if (root.rightButtonClickedOnEnter && root.clickedFunc && typeof root.clickedFunc === "function") {
|
||||||
|
clickedFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KeyNavigation.tab) {
|
||||||
|
KeyNavigation.tab.forceActiveFocus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onReturnPressed: {
|
Keys.onReturnPressed: {
|
||||||
KeyNavigation.tab.forceActiveFocus();
|
if (root.rightButtonClickedOnEnter &&root.clickedFunc && typeof root.clickedFunc === "function") {
|
||||||
|
clickedFunc()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KeyNavigation.tab) {
|
||||||
|
KeyNavigation.tab.forceActiveFocus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,23 @@ RadioButton {
|
||||||
property string textColor: "#D7D8DB"
|
property string textColor: "#D7D8DB"
|
||||||
property string selectedTextColor: "#FBB26A"
|
property string selectedTextColor: "#FBB26A"
|
||||||
|
|
||||||
|
property string borderFocusedColor: "#D7D8DB"
|
||||||
|
property int borderFocusedWidth: 1
|
||||||
|
|
||||||
property string imageSource
|
property string imageSource
|
||||||
property bool showImage
|
property bool showImage
|
||||||
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
focusPolicy: Qt.TabFocus
|
||||||
|
|
||||||
indicator: Rectangle {
|
indicator: Rectangle {
|
||||||
id: background
|
id: background
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
border.color: root.focus ? root.borderFocusedColor : "transparent"
|
||||||
|
border.width: root.focus ? root.borderFocusedWidth : 0
|
||||||
|
|
||||||
implicitWidth: 56
|
implicitWidth: 56
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
@ -51,6 +58,10 @@ RadioButton {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
PropertyAnimation { duration: 200 }
|
||||||
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
source: {
|
source: {
|
||||||
if (showImage) {
|
if (showImage) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: PageController
|
target: PageController
|
||||||
|
|
||||||
|
|
@ -38,7 +40,15 @@ PageType {
|
||||||
anchors.topMargin: 34
|
anchors.topMargin: 34
|
||||||
anchors.bottomMargin: 34
|
anchors.bottomMargin: 34
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: loggingButton.visible ?
|
||||||
|
loggingButton :
|
||||||
|
connectButton
|
||||||
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: loggingButton
|
||||||
property bool isLoggingEnabled: SettingsController.isLoggingEnabled
|
property bool isLoggingEnabled: SettingsController.isLoggingEnabled
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
@ -55,6 +65,11 @@ PageType {
|
||||||
visible: isLoggingEnabled ? true : false
|
visible: isLoggingEnabled ? true : false
|
||||||
text: qsTr("Logging enabled")
|
text: qsTr("Logging enabled")
|
||||||
|
|
||||||
|
Keys.onEnterPressed: loggingButton.clicked()
|
||||||
|
Keys.onReturnPressed: loggingButton.clicked()
|
||||||
|
|
||||||
|
KeyNavigation.tab: connectButton
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
PageController.goToPage(PageEnum.PageSettingsLogging)
|
PageController.goToPage(PageEnum.PageSettingsLogging)
|
||||||
}
|
}
|
||||||
|
|
@ -64,9 +79,11 @@ PageType {
|
||||||
id: connectButton
|
id: connectButton
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
KeyNavigation.tab: splitTunnelingButton
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: splitTunnelingButton
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||||
Layout.bottomMargin: 34
|
Layout.bottomMargin: 34
|
||||||
leftPadding: 16
|
leftPadding: 16
|
||||||
|
|
@ -90,6 +107,11 @@ PageType {
|
||||||
imageSource: isSplitTunnelingEnabled ? "qrc:/images/controls/split-tunneling.svg" : ""
|
imageSource: isSplitTunnelingEnabled ? "qrc:/images/controls/split-tunneling.svg" : ""
|
||||||
rightImageSource: "qrc:/images/controls/chevron-down.svg"
|
rightImageSource: "qrc:/images/controls/chevron-down.svg"
|
||||||
|
|
||||||
|
Keys.onEnterPressed: splitTunnelingButton.clicked()
|
||||||
|
Keys.onReturnPressed: splitTunnelingButton.clicked()
|
||||||
|
|
||||||
|
KeyNavigation.tab: drawer
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
homeSplitTunnelingDrawer.open()
|
homeSplitTunnelingDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
@ -97,6 +119,12 @@ PageType {
|
||||||
HomeSplitTunnelingDrawer {
|
HomeSplitTunnelingDrawer {
|
||||||
id: homeSplitTunnelingDrawer
|
id: homeSplitTunnelingDrawer
|
||||||
parent: root
|
parent: root
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -107,11 +135,26 @@ PageType {
|
||||||
id: drawer
|
id: drawer
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
collapsedContent: Item {
|
collapsedContent: Item {
|
||||||
implicitHeight: Qt.platform.os !== "ios" ? root.height * 0.9 : screen.height * 0.77
|
implicitHeight: Qt.platform.os !== "ios" ? root.height * 0.9 : screen.height * 0.77
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
drawer.expandedHeight = implicitHeight
|
drawer.expandedHeight = implicitHeight
|
||||||
}
|
}
|
||||||
|
Connections {
|
||||||
|
target: drawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onActiveFocusChanged() {
|
||||||
|
if (drawer.activeFocus && !drawer.isOpened) {
|
||||||
|
collapsedButtonChevron.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: collapsed
|
id: collapsed
|
||||||
|
|
||||||
|
|
@ -178,6 +221,8 @@ PageType {
|
||||||
text: ServersModel.defaultServerName
|
text: ServersModel.defaultServerName
|
||||||
horizontalAlignment: Qt.AlignHCenter
|
horizontalAlignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
KeyNavigation.tab: tabBar
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
PropertyAnimation { duration: 200 }
|
PropertyAnimation { duration: 200 }
|
||||||
}
|
}
|
||||||
|
|
@ -201,6 +246,11 @@ PageType {
|
||||||
topPadding: 4
|
topPadding: 4
|
||||||
bottomPadding: 3
|
bottomPadding: 3
|
||||||
|
|
||||||
|
Keys.onEnterPressed: collapsedButtonChevron.clicked()
|
||||||
|
Keys.onReturnPressed: collapsedButtonChevron.clicked()
|
||||||
|
Keys.onTabPressed: lastItemTabClicked()
|
||||||
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (drawer.isCollapsed) {
|
if (drawer.isCollapsed) {
|
||||||
drawer.open()
|
drawer.open()
|
||||||
|
|
@ -217,6 +267,16 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: drawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onIsCollapsedChanged() {
|
||||||
|
if (!drawer.isCollapsed) {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: serversMenuHeader
|
id: serversMenuHeader
|
||||||
|
|
||||||
|
|
@ -230,6 +290,11 @@ PageType {
|
||||||
|
|
||||||
visible: !ServersModel.isDefaultServerFromApi
|
visible: !ServersModel.isDefaultServerFromApi
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem1
|
||||||
|
KeyNavigation.tab: containersDropDown
|
||||||
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
id: containersDropDown
|
id: containersDropDown
|
||||||
|
|
||||||
|
|
@ -252,9 +317,16 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
drawerParent: root
|
drawerParent: root
|
||||||
|
KeyNavigation.tab: serversMenuContent
|
||||||
|
|
||||||
listView: HomeContainersListView {
|
listView: HomeContainersListView {
|
||||||
|
id: containersListView
|
||||||
rootWidth: root.width
|
rootWidth: root.width
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (containersDropDown.visible && !GC.isMobile()) {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ServersModel
|
target: ServersModel
|
||||||
|
|
@ -317,9 +389,43 @@ PageType {
|
||||||
policy: serversMenuContent.height >= serversMenuContent.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
|
policy: serversMenuContent.height >= serversMenuContent.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
property int focusItemIndex: 0
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
serversMenuContent.focusItemIndex = 0
|
||||||
|
serversMenuContent.itemAtIndex(focusItemIndex).forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocusItemIndexChanged: {
|
||||||
|
const focusedElement = serversMenuContent.itemAtIndex(focusItemIndex)
|
||||||
|
if (focusedElement) {
|
||||||
|
if (focusedElement.y + focusedElement.height > serversMenuContent.height) {
|
||||||
|
serversMenuContent.contentY = focusedElement.y + focusedElement.height - serversMenuContent.height
|
||||||
|
} else {
|
||||||
|
serversMenuContent.contentY = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Keys.onUpPressed: scrollBar.decrease()
|
Keys.onUpPressed: scrollBar.decrease()
|
||||||
Keys.onDownPressed: scrollBar.increase()
|
Keys.onDownPressed: scrollBar.increase()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: drawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onIsCollapsedChanged() {
|
||||||
|
if (drawer.isCollapsed) {
|
||||||
|
const item = serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex)
|
||||||
|
if (item) { item.serverRadioButtonProperty.focus = false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ServersModel
|
target: ServersModel
|
||||||
function onDefaultServerIndexChanged(serverIndex) {
|
function onDefaultServerIndexChanged(serverIndex) {
|
||||||
|
|
@ -333,10 +439,17 @@ PageType {
|
||||||
id: menuContentDelegate
|
id: menuContentDelegate
|
||||||
|
|
||||||
property variant delegateData: model
|
property variant delegateData: model
|
||||||
|
property VerticalRadioButton serverRadioButtonProperty: serverRadioButton
|
||||||
|
|
||||||
implicitWidth: serversMenuContent.width
|
implicitWidth: serversMenuContent.width
|
||||||
implicitHeight: serverRadioButtonContent.implicitHeight
|
implicitHeight: serverRadioButtonContent.implicitHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
serverRadioButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: serverRadioButtonContent
|
id: serverRadioButtonContent
|
||||||
|
|
||||||
|
|
@ -377,9 +490,14 @@ PageType {
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: serverInfoButton.forceActiveFocus()
|
||||||
|
Keys.onEnterPressed: serverRadioButton.clicked()
|
||||||
|
Keys.onReturnPressed: serverRadioButton.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
id: serverInfoButton
|
||||||
image: "qrc:/images/controls/settings.svg"
|
image: "qrc:/images/controls/settings.svg"
|
||||||
imageColor: "#D7D8DB"
|
imageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
|
@ -388,6 +506,18 @@ PageType {
|
||||||
|
|
||||||
z: 1
|
z: 1
|
||||||
|
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (serversMenuContent.focusItemIndex < serversMenuContent.count - 1) {
|
||||||
|
serversMenuContent.focusItemIndex++
|
||||||
|
serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex).forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
serversMenuContent.contentY = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Keys.onEnterPressed: serverInfoButton.clicked()
|
||||||
|
Keys.onReturnPressed: serverInfoButton.clicked()
|
||||||
|
|
||||||
onClicked: function() {
|
onClicked: function() {
|
||||||
ServersModel.processedIndex = index
|
ServersModel.processedIndex = index
|
||||||
PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,18 @@ PageType {
|
||||||
|
|
||||||
defaultActiveFocusItem: listview.currentItem.portTextField.textField
|
defaultActiveFocusItem: listview.currentItem.portTextField.textField
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
onFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
fl.ensureVisible(focusItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -28,12 +38,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listview.currentItem.portTextField.textField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -47,8 +59,6 @@ PageType {
|
||||||
enabled: ServersModel.isProcessedServerHasWriteAccess()
|
enabled: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
|
|
||||||
|
|
||||||
id: listview
|
id: listview
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
|
@ -94,6 +104,7 @@ PageType {
|
||||||
textFieldText: port
|
textFieldText: port
|
||||||
textField.maximumLength: 5
|
textField.maximumLength: 5
|
||||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== port) {
|
if (textFieldText !== port) {
|
||||||
|
|
@ -103,7 +114,7 @@ PageType {
|
||||||
|
|
||||||
checkEmptyText: true
|
checkEmptyText: true
|
||||||
|
|
||||||
KeyNavigation.tab: junkPacketCountTextField.textField
|
KeyNavigation.tab: mtuTextField.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
|
|
@ -124,6 +135,7 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checkEmptyText: true
|
checkEmptyText: true
|
||||||
|
KeyNavigation.tab: junkPacketCountTextField.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
|
|
@ -134,6 +146,7 @@ PageType {
|
||||||
headerText: "Jc - Junk packet count"
|
headerText: "Jc - Junk packet count"
|
||||||
textFieldText: junkPacketCount
|
textFieldText: junkPacketCount
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText === "") {
|
if (textFieldText === "") {
|
||||||
|
|
@ -158,6 +171,7 @@ PageType {
|
||||||
headerText: "Jmin - Junk packet minimum size"
|
headerText: "Jmin - Junk packet minimum size"
|
||||||
textFieldText: junkPacketMinSize
|
textFieldText: junkPacketMinSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== junkPacketMinSize) {
|
if (textFieldText !== junkPacketMinSize) {
|
||||||
|
|
@ -178,6 +192,7 @@ PageType {
|
||||||
headerText: "Jmax - Junk packet maximum size"
|
headerText: "Jmax - Junk packet maximum size"
|
||||||
textFieldText: junkPacketMaxSize
|
textFieldText: junkPacketMaxSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== junkPacketMaxSize) {
|
if (textFieldText !== junkPacketMaxSize) {
|
||||||
|
|
@ -198,6 +213,7 @@ PageType {
|
||||||
headerText: "S1 - Init packet junk size"
|
headerText: "S1 - Init packet junk size"
|
||||||
textFieldText: initPacketJunkSize
|
textFieldText: initPacketJunkSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== initPacketJunkSize) {
|
if (textFieldText !== initPacketJunkSize) {
|
||||||
|
|
@ -218,6 +234,7 @@ PageType {
|
||||||
headerText: "S2 - Response packet junk size"
|
headerText: "S2 - Response packet junk size"
|
||||||
textFieldText: responsePacketJunkSize
|
textFieldText: responsePacketJunkSize
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== responsePacketJunkSize) {
|
if (textFieldText !== responsePacketJunkSize) {
|
||||||
|
|
@ -238,6 +255,7 @@ PageType {
|
||||||
headerText: "H1 - Init packet magic header"
|
headerText: "H1 - Init packet magic header"
|
||||||
textFieldText: initPacketMagicHeader
|
textFieldText: initPacketMagicHeader
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== initPacketMagicHeader) {
|
if (textFieldText !== initPacketMagicHeader) {
|
||||||
|
|
@ -258,6 +276,7 @@ PageType {
|
||||||
headerText: "H2 - Response packet magic header"
|
headerText: "H2 - Response packet magic header"
|
||||||
textFieldText: responsePacketMagicHeader
|
textFieldText: responsePacketMagicHeader
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== responsePacketMagicHeader) {
|
if (textFieldText !== responsePacketMagicHeader) {
|
||||||
|
|
@ -278,6 +297,7 @@ PageType {
|
||||||
headerText: "H4 - Transport packet magic header"
|
headerText: "H4 - Transport packet magic header"
|
||||||
textFieldText: transportPacketMagicHeader
|
textFieldText: transportPacketMagicHeader
|
||||||
textField.validator: IntValidator { bottom: 0 }
|
textField.validator: IntValidator { bottom: 0 }
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== transportPacketMagicHeader) {
|
if (textFieldText !== transportPacketMagicHeader) {
|
||||||
|
|
@ -294,6 +314,7 @@ PageType {
|
||||||
id: underloadPacketMagicHeaderTextField
|
id: underloadPacketMagicHeaderTextField
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
headerText: "H3 - Underload packet magic header"
|
headerText: "H3 - Underload packet magic header"
|
||||||
textFieldText: underloadPacketMagicHeader
|
textFieldText: underloadPacketMagicHeader
|
||||||
|
|
@ -312,6 +333,7 @@ PageType {
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: saveRestartButton
|
id: saveRestartButton
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
|
|
@ -330,7 +352,9 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
|
||||||
onClicked: {
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
|
clickedFunc: function() {
|
||||||
if (AwgConfigModel.isHeadersEqual(underloadPacketMagicHeaderTextField.textField.text,
|
if (AwgConfigModel.isHeadersEqual(underloadPacketMagicHeaderTextField.textField.text,
|
||||||
transportPacketMagicHeaderTextField.textField.text,
|
transportPacketMagicHeaderTextField.textField.text,
|
||||||
responsePacketMagicHeaderTextField.textField.text,
|
responsePacketMagicHeaderTextField.textField.text,
|
||||||
|
|
@ -362,6 +386,9 @@ PageType {
|
||||||
InstallController.updateContainer(AwgConfigModel.getConfig())
|
InstallController.updateContainer(AwgConfigModel.getConfig())
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
saveRestartButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,13 @@ PageType {
|
||||||
|
|
||||||
defaultActiveFocusItem: listview.currentItem.trafficFromField.textField
|
defaultActiveFocusItem: listview.currentItem.trafficFromField.textField
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -27,12 +32,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listview.currentItem.trafficFromField.textField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -123,7 +130,7 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: saveRestartButton
|
KeyNavigation.tab: cipherDropDown
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
|
|
@ -135,6 +142,7 @@ PageType {
|
||||||
headerText: qsTr("Cipher")
|
headerText: qsTr("Cipher")
|
||||||
|
|
||||||
drawerParent: root
|
drawerParent: root
|
||||||
|
KeyNavigation.tab: saveRestartButton
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
id: cipherListView
|
id: cipherListView
|
||||||
|
|
@ -175,6 +183,7 @@ PageType {
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,18 @@ PageType {
|
||||||
|
|
||||||
defaultActiveFocusItem: listview.currentItem.vpnAddressSubnetTextField.textField
|
defaultActiveFocusItem: listview.currentItem.vpnAddressSubnetTextField.textField
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
fl.ensureVisible(focusItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -28,12 +38,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listview.currentItem.vpnAddressSubnetTextField.textField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -90,13 +102,14 @@ PageType {
|
||||||
headerText: qsTr("VPN address subnet")
|
headerText: qsTr("VPN address subnet")
|
||||||
textFieldText: subnetAddress
|
textFieldText: subnetAddress
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: transportProtoSelector
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== subnetAddress) {
|
if (textFieldText !== subnetAddress) {
|
||||||
subnetAddress = textFieldText
|
subnetAddress = textFieldText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: portTextField.enabled ? portTextField.textField : saveRestartButton
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ParagraphTextType {
|
ParagraphTextType {
|
||||||
|
|
@ -107,6 +120,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
TransportProtoSelector {
|
TransportProtoSelector {
|
||||||
|
id: transportProtoSelector
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
rootWidth: root.width
|
rootWidth: root.width
|
||||||
|
|
@ -117,6 +131,8 @@ PageType {
|
||||||
return transportProto === "tcp" ? 1 : 0
|
return transportProto === "tcp" ? 1 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: portTextField.enabled ? portTextField.textField : autoNegotiateEncryprionSwitcher
|
||||||
|
|
||||||
onCurrentIndexChanged: {
|
onCurrentIndexChanged: {
|
||||||
if (transportProto === "tcp" && currentIndex === 0) {
|
if (transportProto === "tcp" && currentIndex === 0) {
|
||||||
transportProto = "udp"
|
transportProto = "udp"
|
||||||
|
|
@ -131,6 +147,7 @@ PageType {
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 40
|
Layout.topMargin: 40
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
enabled: isPortEditable
|
enabled: isPortEditable
|
||||||
|
|
||||||
|
|
@ -145,7 +162,7 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: saveRestartButton
|
KeyNavigation.tab: autoNegotiateEncryprionSwitcher
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
|
@ -153,6 +170,7 @@ PageType {
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
text: qsTr("Auto-negotiate encryption")
|
text: qsTr("Auto-negotiate encryption")
|
||||||
checked: autoNegotiateEncryprion
|
checked: autoNegotiateEncryprion
|
||||||
|
|
@ -162,6 +180,10 @@ PageType {
|
||||||
autoNegotiateEncryprion = checked
|
autoNegotiateEncryprion = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: hashDropDown.enabled ?
|
||||||
|
hashDropDown :
|
||||||
|
tlsAuthCheckBox
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
|
|
@ -175,6 +197,10 @@ PageType {
|
||||||
headerText: qsTr("Hash")
|
headerText: qsTr("Hash")
|
||||||
|
|
||||||
drawerParent: root
|
drawerParent: root
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: cipherDropDown.enabled ?
|
||||||
|
cipherDropDown :
|
||||||
|
tlsAuthCheckBox
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
id: hashListView
|
id: hashListView
|
||||||
|
|
@ -223,6 +249,9 @@ PageType {
|
||||||
headerText: qsTr("Cipher")
|
headerText: qsTr("Cipher")
|
||||||
|
|
||||||
drawerParent: root
|
drawerParent: root
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
|
KeyNavigation.tab: tlsAuthCheckBox
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
id: cipherListView
|
id: cipherListView
|
||||||
|
|
@ -261,24 +290,40 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
id: contentRect
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
Layout.preferredHeight: checkboxLayout.implicitHeight
|
Layout.preferredHeight: checkboxLayout.implicitHeight
|
||||||
color: "#1C1D21"
|
color: "#1C1D21"
|
||||||
radius: 16
|
radius: 16
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tlsAuthCheckBox
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
|
||||||
|
function onFocusChanged() {
|
||||||
|
if (tlsAuthCheckBox.activeFocus) {
|
||||||
|
fl.ensureVisible(contentRect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: checkboxLayout
|
id: checkboxLayout
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
CheckBoxType {
|
CheckBoxType {
|
||||||
|
id: tlsAuthCheckBox
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("TLS auth")
|
text: qsTr("TLS auth")
|
||||||
checked: tlsAuth
|
checked: tlsAuth
|
||||||
|
|
||||||
|
KeyNavigation.tab: blockDnsCheckBox
|
||||||
|
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked !== tlsAuth) {
|
if (checked !== tlsAuth) {
|
||||||
|
console.log("tlsAuth changed to: " + checked)
|
||||||
tlsAuth = checked
|
tlsAuth = checked
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -287,11 +332,14 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
CheckBoxType {
|
CheckBoxType {
|
||||||
|
id: blockDnsCheckBox
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Block DNS requests outside of VPN")
|
text: qsTr("Block DNS requests outside of VPN")
|
||||||
checked: blockDns
|
checked: blockDns
|
||||||
|
|
||||||
|
KeyNavigation.tab: additionalClientCommandsSwitcher
|
||||||
|
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked !== blockDns) {
|
if (checked !== blockDns) {
|
||||||
blockDns = checked
|
blockDns = checked
|
||||||
|
|
@ -305,6 +353,10 @@ PageType {
|
||||||
id: additionalClientCommandsSwitcher
|
id: additionalClientCommandsSwitcher
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: additionalClientCommandsTextArea.visible ?
|
||||||
|
additionalClientCommandsTextArea.textArea :
|
||||||
|
additionalServerCommandsSwitcher
|
||||||
|
|
||||||
checked: additionalClientCommands !== ""
|
checked: additionalClientCommands !== ""
|
||||||
|
|
||||||
|
|
@ -318,10 +370,13 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextAreaType {
|
TextAreaType {
|
||||||
|
id: additionalClientCommandsTextArea
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
visible: additionalClientCommandsSwitcher.checked
|
visible: additionalClientCommandsSwitcher.checked
|
||||||
|
KeyNavigation.tab: additionalServerCommandsSwitcher
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
textAreaText: additionalClientCommands
|
textAreaText: additionalClientCommands
|
||||||
placeholderText: qsTr("Commands:")
|
placeholderText: qsTr("Commands:")
|
||||||
|
|
@ -337,6 +392,10 @@ PageType {
|
||||||
id: additionalServerCommandsSwitcher
|
id: additionalServerCommandsSwitcher
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: additionalServerCommandsTextArea.visible ?
|
||||||
|
additionalServerCommandsTextArea.textArea :
|
||||||
|
saveRestartButton
|
||||||
|
|
||||||
checked: additionalServerCommands !== ""
|
checked: additionalServerCommands !== ""
|
||||||
|
|
||||||
|
|
@ -350,6 +409,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextAreaType {
|
TextAreaType {
|
||||||
|
id: additionalServerCommandsTextArea
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
|
@ -357,7 +417,8 @@ PageType {
|
||||||
|
|
||||||
textAreaText: additionalServerCommands
|
textAreaText: additionalServerCommands
|
||||||
placeholderText: qsTr("Commands:")
|
placeholderText: qsTr("Commands:")
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: saveRestartButton
|
||||||
textArea.onEditingFinished: {
|
textArea.onEditingFinished: {
|
||||||
if (additionalServerCommands !== textAreaText) {
|
if (additionalServerCommands !== textAreaText) {
|
||||||
additionalServerCommands = textAreaText
|
additionalServerCommands = textAreaText
|
||||||
|
|
@ -373,6 +434,8 @@ PageType {
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
parentFlickable: fl
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: header
|
id: header
|
||||||
|
|
||||||
|
|
@ -28,6 +35,8 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listView
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
|
@ -55,16 +64,29 @@ PageType {
|
||||||
anchors.topMargin: 32
|
anchors.topMargin: 32
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
|
id: listView
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: contentItem.height
|
height: contentItem.height
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
model: ProtocolsModel
|
model: ProtocolsModel
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (focus) {
|
||||||
|
listView.currentIndex = 0
|
||||||
|
listView.currentItem.focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: parent.width
|
implicitWidth: parent.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
property alias focusItem: button
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
|
|
@ -81,6 +103,8 @@ PageType {
|
||||||
configContentDrawer.open()
|
configContentDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: removeButton
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: button
|
anchors.fill: button
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
@ -95,14 +119,33 @@ PageType {
|
||||||
|
|
||||||
expandedHeight: root.height * 0.9
|
expandedHeight: root.height * 0.9
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
parent: root
|
parent: root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
expandedContent: Item {
|
expandedContent: Item {
|
||||||
implicitHeight: configContentDrawer.expandedHeight
|
implicitHeight: configContentDrawer.expandedHeight
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: configContentDrawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem1
|
||||||
|
KeyNavigation.tab: backButton1
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton1
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -112,10 +155,12 @@ PageType {
|
||||||
backButtonFunction: function() {
|
backButtonFunction: function() {
|
||||||
configContentDrawer.close()
|
configContentDrawer.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: focusItem1
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButton1.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
@ -180,6 +225,7 @@ PageType {
|
||||||
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
||||||
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
||||||
|
|
@ -191,6 +237,9 @@ PageType {
|
||||||
InstallController.removeProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,17 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
defaultActiveFocusItem: listview.currentItem.portTextField.textField
|
defaultActiveFocusItem: listview.currentItem.focusItemId.enabled ?
|
||||||
|
listview.currentItem.focusItemId.textField :
|
||||||
|
focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -27,12 +34,16 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listview.currentItem.focusItemId.enabled ?
|
||||||
|
listview.currentItem.focusItemId.textField :
|
||||||
|
focusItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -60,7 +71,11 @@ PageType {
|
||||||
implicitWidth: listview.width
|
implicitWidth: listview.width
|
||||||
implicitHeight: col.implicitHeight
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
property alias portTextField: portTextField
|
property var focusItemId: portTextField.enabled ?
|
||||||
|
portTextField :
|
||||||
|
cipherDropDown.enabled ?
|
||||||
|
cipherDropDown :
|
||||||
|
saveRestartButton
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: col
|
id: col
|
||||||
|
|
@ -99,7 +114,7 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: saveRestartButton
|
KeyNavigation.tab: cipherDropDown
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
|
|
@ -113,6 +128,7 @@ PageType {
|
||||||
headerText: qsTr("Cipher")
|
headerText: qsTr("Cipher")
|
||||||
|
|
||||||
drawerParent: root
|
drawerParent: root
|
||||||
|
KeyNavigation.tab: saveRestartButton
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
id: cipherListView
|
id: cipherListView
|
||||||
|
|
@ -155,6 +171,7 @@ PageType {
|
||||||
enabled: isPortEditable | isCipherEditable
|
enabled: isPortEditable | isCipherEditable
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,15 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: listview
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -25,12 +32,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listview
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -54,7 +63,16 @@ PageType {
|
||||||
|
|
||||||
model: WireGuardConfigModel
|
model: WireGuardConfigModel
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
listview.itemAtIndex(0)?.focusItemId.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
|
property alias focusItemId: portTextField.textField
|
||||||
|
|
||||||
implicitWidth: listview.width
|
implicitWidth: listview.width
|
||||||
implicitHeight: col.implicitHeight
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
|
|
@ -85,6 +103,8 @@ PageType {
|
||||||
textField.maximumLength: 5
|
textField.maximumLength: 5
|
||||||
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
textField.validator: IntValidator { bottom: 1; top: 65535 }
|
||||||
|
|
||||||
|
KeyNavigation.tab: mtuTextField.textField
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== port) {
|
if (textFieldText !== port) {
|
||||||
port = textFieldText
|
port = textFieldText
|
||||||
|
|
@ -103,6 +123,8 @@ PageType {
|
||||||
textFieldText: mtu
|
textFieldText: mtu
|
||||||
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
textField.validator: IntValidator { bottom: 576; top: 65535 }
|
||||||
|
|
||||||
|
KeyNavigation.tab: saveButton
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText === "") {
|
if (textFieldText === "") {
|
||||||
textFieldText = "0"
|
textFieldText = "0"
|
||||||
|
|
@ -115,6 +137,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: saveButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
@ -124,6 +147,8 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
||||||
|
|
@ -134,7 +159,11 @@ PageType {
|
||||||
|
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||||
InstallController.updateContainer(WireGuardConfigModel.getConfig())
|
InstallController.updateContainer(WireGuardConfigModel.getConfig())
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: saveButton.clicked()
|
||||||
|
Keys.onReturnPressed: saveButton.clicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,15 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: listview
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -26,12 +33,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listview
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -55,7 +64,16 @@ PageType {
|
||||||
|
|
||||||
model: XrayConfigModel
|
model: XrayConfigModel
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
listview.itemAtIndex(0)?.focusItemId.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
|
property alias focusItemId: textFieldWithHeaderType.textField
|
||||||
|
|
||||||
implicitWidth: listview.width
|
implicitWidth: listview.width
|
||||||
implicitHeight: col.implicitHeight
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
|
|
@ -77,12 +95,15 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
|
id: textFieldWithHeaderType
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
|
|
||||||
headerText: qsTr("Disguised as traffic from")
|
headerText: qsTr("Disguised as traffic from")
|
||||||
textFieldText: site
|
textFieldText: site
|
||||||
|
|
||||||
|
KeyNavigation.tab: basicButton
|
||||||
|
|
||||||
textField.onEditingFinished: {
|
textField.onEditingFinished: {
|
||||||
if (textFieldText !== site) {
|
if (textFieldText !== site) {
|
||||||
var tmpText = textFieldText
|
var tmpText = textFieldText
|
||||||
|
|
@ -99,12 +120,15 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: basicButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
|
|
||||||
|
|
@ -115,7 +139,11 @@ PageType {
|
||||||
|
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||||
InstallController.updateContainer(XrayConfigModel.getConfig())
|
InstallController.updateContainer(XrayConfigModel.getConfig())
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onEnterPressed: basicButton.clicked()
|
||||||
|
Keys.onReturnPressed: basicButton.clicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,15 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -25,12 +32,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: removeButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -62,6 +71,8 @@ PageType {
|
||||||
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
Keys.onTabPressed: root.lastItemTabClicked()
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
||||||
var yesButtonText = qsTr("Continue")
|
var yesButtonText = qsTr("Continue")
|
||||||
|
|
@ -78,6 +89,9 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
removeButton.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
|
|
@ -23,8 +25,13 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -33,12 +40,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: listview
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -62,10 +71,18 @@ PageType {
|
||||||
|
|
||||||
model: SftpConfigModel
|
model: SftpConfigModel
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (focus) {
|
||||||
|
listview.currentItem.focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: listview.width
|
implicitWidth: listview.width
|
||||||
implicitHeight: col.implicitHeight
|
implicitHeight: col.implicitHeight
|
||||||
|
|
||||||
|
property alias focusItem: hostLabel.rightButton
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: col
|
id: col
|
||||||
|
|
||||||
|
|
@ -84,9 +101,13 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: hostLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: portLabel.rightButton
|
||||||
|
|
||||||
text: qsTr("Host")
|
text: qsTr("Host")
|
||||||
descriptionText: ServersModel.getProcessedServerData("hostName")
|
descriptionText: ServersModel.getProcessedServerData("hostName")
|
||||||
|
|
||||||
|
|
@ -98,10 +119,14 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
GC.copyToClipBoard(descriptionText)
|
GC.copyToClipBoard(descriptionText)
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
PageController.showNotificationMessage(qsTr("Copied"))
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
this.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: portLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Port")
|
text: qsTr("Port")
|
||||||
|
|
@ -109,16 +134,23 @@ PageType {
|
||||||
|
|
||||||
descriptionOnTop: true
|
descriptionOnTop: true
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: usernameLabel.rightButton
|
||||||
|
|
||||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
rightImageColor: "#D7D8DB"
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
GC.copyToClipBoard(descriptionText)
|
GC.copyToClipBoard(descriptionText)
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
PageController.showNotificationMessage(qsTr("Copied"))
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
this.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: usernameLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("User name")
|
text: qsTr("User name")
|
||||||
|
|
@ -126,16 +158,23 @@ PageType {
|
||||||
|
|
||||||
descriptionOnTop: true
|
descriptionOnTop: true
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: passwordLabel.rightButton
|
||||||
|
|
||||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
rightImageColor: "#D7D8DB"
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
GC.copyToClipBoard(descriptionText)
|
GC.copyToClipBoard(descriptionText)
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
PageController.showNotificationMessage(qsTr("Copied"))
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
this.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: passwordLabel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Password")
|
text: qsTr("Password")
|
||||||
|
|
@ -143,16 +182,29 @@ PageType {
|
||||||
|
|
||||||
descriptionOnTop: true
|
descriptionOnTop: true
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (mountButton.visible) {
|
||||||
|
mountButton.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
detailedInstructionsButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
rightImageColor: "#D7D8DB"
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
GC.copyToClipBoard(descriptionText)
|
GC.copyToClipBoard(descriptionText)
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
PageController.showNotificationMessage(qsTr("Copied"))
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
this.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: mountButton
|
||||||
visible: !GC.isMobile()
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -168,13 +220,16 @@ PageType {
|
||||||
textColor: "#D7D8DB"
|
textColor: "#D7D8DB"
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: detailedInstructionsButton
|
||||||
|
|
||||||
text: qsTr("Mount folder on device")
|
text: qsTr("Mount folder on device")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
InstallController.mountSftpDrive(port, password, username)
|
InstallController.mountSftpDrive(port, password, username)
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ParagraphTextType {
|
ParagraphTextType {
|
||||||
|
|
@ -216,6 +271,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: detailedInstructionsButton
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
|
|
@ -229,12 +285,16 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Detailed instructions")
|
text: qsTr("Detailed instructions")
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
KeyNavigation.tab: removeButton
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: removeButton
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
|
|
@ -245,6 +305,9 @@ PageType {
|
||||||
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
pressedColor: Qt.rgba(1, 1, 1, 0.12)
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
parentFlickable: fl
|
||||||
|
Keys.onTabPressed: lastItemTabClicked()
|
||||||
|
|
||||||
text: qsTr("Remove SFTP and all data stored there")
|
text: qsTr("Remove SFTP and all data stored there")
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
|
|
@ -257,6 +320,9 @@ PageType {
|
||||||
InstallController.removeProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
removeButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
|
|
@ -24,8 +26,13 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -34,12 +41,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: websiteName.rightButton
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight
|
contentHeight: content.implicitHeight
|
||||||
|
|
||||||
|
|
@ -61,6 +70,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: websiteName
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
|
|
||||||
|
|
@ -77,9 +87,14 @@ PageType {
|
||||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||||
rightImageColor: "#D7D8DB"
|
rightImageColor: "#D7D8DB"
|
||||||
|
|
||||||
|
KeyNavigation.tab: removeButton
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
GC.copyToClipBoard(descriptionText)
|
GC.copyToClipBoard(descriptionText)
|
||||||
PageController.showNotificationMessage(qsTr("Copied"))
|
PageController.showNotificationMessage(qsTr("Copied"))
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
this.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,6 +128,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: removeButton
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
Layout.leftMargin: 8
|
Layout.leftMargin: 8
|
||||||
|
|
@ -125,6 +141,8 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Remove website")
|
text: qsTr("Remove website")
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
var headerText = qsTr("The site with all data will be removed from the tor network.")
|
var headerText = qsTr("The site with all data will be removed from the tor network.")
|
||||||
var yesButtonText = qsTr("Continue")
|
var yesButtonText = qsTr("Continue")
|
||||||
|
|
@ -135,6 +153,9 @@ PageType {
|
||||||
InstallController.removeProcessedContainer()
|
InstallController.removeProcessedContainer()
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
removeButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ import "../Config"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: header
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -29,15 +31,19 @@ PageType {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
id: header
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
||||||
headerText: qsTr("Settings")
|
headerText: qsTr("Settings")
|
||||||
|
|
||||||
|
KeyNavigation.tab: account.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: account
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
|
@ -48,11 +54,14 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsServersList)
|
PageController.goToPage(PageEnum.PageSettingsServersList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: connection.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: connection
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Connection")
|
text: qsTr("Connection")
|
||||||
|
|
@ -62,11 +71,14 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsConnection)
|
PageController.goToPage(PageEnum.PageSettingsConnection)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: application.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: application
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Application")
|
text: qsTr("Application")
|
||||||
|
|
@ -76,11 +88,14 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsApplication)
|
PageController.goToPage(PageEnum.PageSettingsApplication)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: backup.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: backup
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Backup")
|
text: qsTr("Backup")
|
||||||
|
|
@ -90,6 +105,8 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsBackup)
|
PageController.goToPage(PageEnum.PageSettingsBackup)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: about.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
@ -105,18 +122,23 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsAbout)
|
PageController.goToPage(PageEnum.PageSettingsAbout)
|
||||||
}
|
}
|
||||||
|
KeyNavigation.tab: close
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: close
|
||||||
visible: GC.isDesktop()
|
visible: GC.isDesktop()
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: about.height
|
Layout.preferredHeight: about.height
|
||||||
|
|
||||||
text: qsTr("Close application")
|
text: qsTr("Close application")
|
||||||
leftImageSource: "qrc:/images/controls/x-circle.svg"
|
leftImageSource: "qrc:/images/controls/x-circle.svg"
|
||||||
isLeftImageHoverEnabled: false
|
isLeftImageHoverEnabled: false
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(header)
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.closeApplication()
|
PageController.closeApplication()
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,19 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (focusItem.activeFocus) {
|
||||||
|
fl.contentY = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -20,6 +33,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: telegramButton
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -82,6 +97,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: telegramButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
|
@ -89,6 +105,9 @@ PageType {
|
||||||
descriptionText: qsTr("To discuss features")
|
descriptionText: qsTr("To discuss features")
|
||||||
leftImageSource: "qrc:/images/controls/telegram.svg"
|
leftImageSource: "qrc:/images/controls/telegram.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: mailButton
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
Qt.openUrlExternally(qsTr("https://t.me/amnezia_vpn_en"))
|
Qt.openUrlExternally(qsTr("https://t.me/amnezia_vpn_en"))
|
||||||
}
|
}
|
||||||
|
|
@ -97,40 +116,55 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: mailButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Mail")
|
text: qsTr("Mail")
|
||||||
descriptionText: qsTr("For reviews and bug reports")
|
descriptionText: qsTr("For reviews and bug reports")
|
||||||
leftImageSource: "qrc:/images/controls/mail.svg"
|
leftImageSource: "qrc:/images/controls/mail.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: githubButton
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: githubButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Github")
|
text: qsTr("Github")
|
||||||
leftImageSource: "qrc:/images/controls/github.svg"
|
leftImageSource: "qrc:/images/controls/github.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: websiteButton
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
Qt.openUrlExternally(qsTr("https://github.com/amnezia-vpn/amnezia-client"))
|
Qt.openUrlExternally(qsTr("https://github.com/amnezia-vpn/amnezia-client"))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: websiteButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Website")
|
text: qsTr("Website")
|
||||||
leftImageSource: "qrc:/images/controls/amnezia.svg"
|
leftImageSource: "qrc:/images/controls/amnezia.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: checkUpdatesButton
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
Qt.openUrlExternally(qsTr("https://amnezia.org"))
|
Qt.openUrlExternally(qsTr("https://amnezia.org"))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
@ -146,6 +180,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: checkUpdatesButton
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.topMargin: 8
|
Layout.topMargin: 8
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
|
|
@ -159,12 +194,16 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Check for updates")
|
text: qsTr("Check for updates")
|
||||||
|
|
||||||
|
KeyNavigation.tab: privacyPolicyButton
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: privacyPolicyButton
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
Layout.topMargin: -15
|
Layout.topMargin: -15
|
||||||
|
|
@ -178,6 +217,9 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Privacy Policy")
|
text: qsTr("Privacy Policy")
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked()
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
Qt.openUrlExternally("https://amnezia.org/en/policy")
|
Qt.openUrlExternally("https://amnezia.org/en/policy")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
property bool pageEnabled
|
property bool pageEnabled
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
@ -63,6 +65,11 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: header
|
id: header
|
||||||
|
|
||||||
|
|
@ -73,6 +80,8 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: switcher
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -93,6 +102,10 @@ PageType {
|
||||||
|
|
||||||
enabled: root.pageEnabled
|
enabled: root.pageEnabled
|
||||||
|
|
||||||
|
KeyNavigation.tab: selector.enabled ?
|
||||||
|
selector :
|
||||||
|
searchField.textField
|
||||||
|
|
||||||
checked: AppSplitTunnelingModel.isTunnelingEnabled
|
checked: AppSplitTunnelingModel.isTunnelingEnabled
|
||||||
onToggled: {
|
onToggled: {
|
||||||
AppSplitTunnelingModel.toggleSplitTunneling(checked)
|
AppSplitTunnelingModel.toggleSplitTunneling(checked)
|
||||||
|
|
@ -116,6 +129,8 @@ PageType {
|
||||||
|
|
||||||
enabled: Qt.platform.os === "android" && root.pageEnabled
|
enabled: Qt.platform.os === "android" && root.pageEnabled
|
||||||
|
|
||||||
|
KeyNavigation.tab: searchField.textField
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
rootWidth: root.width
|
rootWidth: root.width
|
||||||
|
|
||||||
|
|
@ -251,6 +266,9 @@ PageType {
|
||||||
textFieldPlaceholderText: qsTr("application name")
|
textFieldPlaceholderText: qsTr("application name")
|
||||||
buttonImageSource: "qrc:/images/controls/plus.svg"
|
buttonImageSource: "qrc:/images/controls/plus.svg"
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
rightButtonClickedOnEnter: true
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
searchField.focus = false
|
searchField.focus = false
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,53 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
function getNextComponentInFocusChain(componentId) {
|
||||||
|
const componentsList = [focusItem,
|
||||||
|
backButton,
|
||||||
|
switcher,
|
||||||
|
switcherAutoStart,
|
||||||
|
switcherAutoConnect,
|
||||||
|
switcherStartMinimized,
|
||||||
|
labelWithButtonLanguage,
|
||||||
|
labelWithButtonLogging,
|
||||||
|
labelWithButtonReset,
|
||||||
|
]
|
||||||
|
|
||||||
|
const idx = componentsList.indexOf(componentId)
|
||||||
|
|
||||||
|
if (idx === -1) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let nextIndex = idx + 1
|
||||||
|
if (nextIndex >= componentsList.length) {
|
||||||
|
nextIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (componentsList[nextIndex].visible) {
|
||||||
|
if ((nextIndex) >= 6) {
|
||||||
|
return componentsList[nextIndex].rightButton
|
||||||
|
} else {
|
||||||
|
return componentsList[nextIndex]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return getNextComponentInFocusChain(componentsList[nextIndex])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(focusItem)
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (focusItem.activeFocus) {
|
||||||
|
fl.contentY = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -20,6 +67,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(backButton)
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -44,6 +93,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
id: switcher
|
||||||
visible: GC.isMobile()
|
visible: GC.isMobile()
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -57,6 +107,9 @@ PageType {
|
||||||
SettingsController.toggleScreenshotsEnabled(checked)
|
SettingsController.toggleScreenshotsEnabled(checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(switcher)
|
||||||
|
parentFlickable: fl
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {
|
DividerType {
|
||||||
|
|
@ -64,6 +117,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
id: switcherAutoStart
|
||||||
visible: !GC.isMobile()
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -72,6 +126,9 @@ PageType {
|
||||||
text: qsTr("Auto start")
|
text: qsTr("Auto start")
|
||||||
descriptionText: qsTr("Launch the application every time the device is starts")
|
descriptionText: qsTr("Launch the application every time the device is starts")
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(switcherAutoStart)
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
checked: SettingsController.isAutoStartEnabled()
|
checked: SettingsController.isAutoStartEnabled()
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked !== SettingsController.isAutoStartEnabled()) {
|
if (checked !== SettingsController.isAutoStartEnabled()) {
|
||||||
|
|
@ -85,6 +142,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
id: switcherAutoConnect
|
||||||
visible: !GC.isMobile()
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -93,6 +151,9 @@ PageType {
|
||||||
text: qsTr("Auto connect")
|
text: qsTr("Auto connect")
|
||||||
descriptionText: qsTr("Connect to VPN on app start")
|
descriptionText: qsTr("Connect to VPN on app start")
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(switcherAutoConnect)
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
checked: SettingsController.isAutoConnectEnabled()
|
checked: SettingsController.isAutoConnectEnabled()
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked !== SettingsController.isAutoConnectEnabled()) {
|
if (checked !== SettingsController.isAutoConnectEnabled()) {
|
||||||
|
|
@ -106,6 +167,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
id: switcherStartMinimized
|
||||||
visible: !GC.isMobile()
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -114,6 +176,9 @@ PageType {
|
||||||
text: qsTr("Start minimized")
|
text: qsTr("Start minimized")
|
||||||
descriptionText: qsTr("Launch application minimized")
|
descriptionText: qsTr("Launch application minimized")
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(switcherStartMinimized)
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
checked: SettingsController.isStartMinimizedEnabled()
|
checked: SettingsController.isStartMinimizedEnabled()
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked !== SettingsController.isStartMinimizedEnabled()) {
|
if (checked !== SettingsController.isStartMinimizedEnabled()) {
|
||||||
|
|
@ -127,12 +192,16 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButtonLanguage
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Language")
|
text: qsTr("Language")
|
||||||
descriptionText: LanguageModel.currentLanguageName
|
descriptionText: LanguageModel.currentLanguageName
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(labelWithButtonLanguage)
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
selectLanguageDrawer.open()
|
selectLanguageDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
@ -142,12 +211,16 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButtonLogging
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Logging")
|
text: qsTr("Logging")
|
||||||
descriptionText: SettingsController.isLoggingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
descriptionText: SettingsController.isLoggingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.getNextComponentInFocusChain(labelWithButtonLogging)
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsLogging)
|
PageController.goToPage(PageEnum.PageSettingsLogging)
|
||||||
}
|
}
|
||||||
|
|
@ -156,12 +229,16 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButtonReset
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Reset settings and remove all data from the application")
|
text: qsTr("Reset settings and remove all data from the application")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked()
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Reset settings and remove all data from the application?")
|
var headerText = qsTr("Reset settings and remove all data from the application?")
|
||||||
var descriptionText = qsTr("All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.")
|
var descriptionText = qsTr("All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.")
|
||||||
|
|
@ -176,8 +253,15 @@ PageType {
|
||||||
SettingsController.clearSettings()
|
SettingsController.clearSettings()
|
||||||
PageController.replaceStartPage()
|
PageController.replaceStartPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
root.defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
root.defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -193,5 +277,11 @@ PageType {
|
||||||
|
|
||||||
width: root.width
|
width: root.width
|
||||||
height: root.height
|
height: root.height
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ import "../Controls2/TextTypes"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SettingsController
|
target: SettingsController
|
||||||
|
|
||||||
|
|
@ -34,6 +36,11 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -41,6 +48,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: makeBackupButton
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -102,9 +111,12 @@ PageType {
|
||||||
PageController.showNotificationMessage(qsTr("Backup file saved"))
|
PageController.showNotificationMessage(qsTr("Backup file saved"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: restoreBackupButton
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: restoreBackupButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: -8
|
Layout.topMargin: -8
|
||||||
|
|
||||||
|
|
@ -124,6 +136,8 @@ PageType {
|
||||||
restoreBackup(filePath)
|
restoreBackup(filePath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,15 @@ import "../Config"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
|
property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -20,6 +27,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: amneziaDnsSwitch
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -44,6 +53,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
id: amneziaDnsSwitch
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: 16
|
Layout.margins: 16
|
||||||
|
|
||||||
|
|
@ -56,11 +66,14 @@ PageType {
|
||||||
SettingsController.toggleAmneziaDns(checked)
|
SettingsController.toggleAmneziaDns(checked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: dnsServersButton.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: dnsServersButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("DNS servers")
|
text: qsTr("DNS servers")
|
||||||
|
|
@ -70,11 +83,14 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsDns)
|
PageController.goToPage(PageEnum.PageSettingsDns)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: splitTunnelingButton.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: splitTunnelingButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Site-based split tunneling")
|
text: qsTr("Site-based split tunneling")
|
||||||
|
|
@ -84,6 +100,10 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: splitTunnelingButton2.visible ?
|
||||||
|
splitTunnelingButton2.forceActiveFocus() :
|
||||||
|
lastItemTabClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {
|
DividerType {
|
||||||
|
|
@ -91,6 +111,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: splitTunnelingButton2
|
||||||
visible: root.isAppSplitTinnelingEnabled
|
visible: root.isAppSplitTinnelingEnabled
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -102,6 +123,8 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {
|
DividerType {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,11 @@ PageType {
|
||||||
|
|
||||||
defaultActiveFocusItem: primaryDns.textField
|
defaultActiveFocusItem: primaryDns.textField
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -22,6 +27,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: root.defaultActiveFocusItem
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -87,10 +94,11 @@ PageType {
|
||||||
regularExpression: InstallController.ipAddressRegExp()
|
regularExpression: InstallController.ipAddressRegExp()
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyNavigation.tab: saveButton
|
KeyNavigation.tab: restoreDefaultButton
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: restoreDefaultButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
defaultColor: "transparent"
|
defaultColor: "transparent"
|
||||||
|
|
@ -113,12 +121,21 @@ PageType {
|
||||||
SettingsController.secondaryDns = "1.0.0.1"
|
SettingsController.secondaryDns = "1.0.0.1"
|
||||||
secondaryDns.textFieldText = SettingsController.secondaryDns
|
secondaryDns.textFieldText = SettingsController.secondaryDns
|
||||||
PageController.showNotificationMessage(qsTr("Settings have been reset"))
|
PageController.showNotificationMessage(qsTr("Settings have been reset"))
|
||||||
|
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: saveButton
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
|
@ -137,6 +154,8 @@ PageType {
|
||||||
}
|
}
|
||||||
PageController.showNotificationMessage(qsTr("Settings saved"))
|
PageController.showNotificationMessage(qsTr("Settings saved"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,13 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -34,6 +41,8 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: switcher
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -62,12 +71,14 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
}
|
}
|
||||||
|
|
||||||
SwitcherType {
|
SwitcherType {
|
||||||
|
id: switcher
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
text: qsTr("Save logs")
|
text: qsTr("Save logs")
|
||||||
|
|
||||||
checked: SettingsController.isLoggingEnabled
|
checked: SettingsController.isLoggingEnabled
|
||||||
|
KeyNavigation.tab: openFolderButton
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if (checked !== SettingsController.isLoggingEnabled) {
|
if (checked !== SettingsController.isLoggingEnabled) {
|
||||||
SettingsController.isLoggingEnabled = checked
|
SettingsController.isLoggingEnabled = checked
|
||||||
|
|
@ -84,14 +95,18 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
visible: !GC.isMobile()
|
visible: !GC.isMobile()
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
id: openFolderButton
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
implicitWidth: 56
|
implicitWidth: 56
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
|
|
||||||
image: "qrc:/images/controls/folder-open.svg"
|
image: "qrc:/images/controls/folder-open.svg"
|
||||||
|
KeyNavigation.tab: saveButton
|
||||||
|
|
||||||
onClicked: SettingsController.openLogsFolder()
|
onClicked: SettingsController.openLogsFolder()
|
||||||
|
Keys.onReturnPressed: openFolderButton.clicked()
|
||||||
|
Keys.onEnterPressed: openFolderButton.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptionTextType {
|
CaptionTextType {
|
||||||
|
|
@ -108,13 +123,17 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
Layout.preferredWidth: root.width / ( GC.isMobile() ? 2 : 3 )
|
Layout.preferredWidth: root.width / ( GC.isMobile() ? 2 : 3 )
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
id: saveButton
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
implicitWidth: 56
|
implicitWidth: 56
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
|
|
||||||
image: "qrc:/images/controls/save.svg"
|
image: "qrc:/images/controls/save.svg"
|
||||||
|
KeyNavigation.tab: clearButton
|
||||||
|
|
||||||
|
Keys.onReturnPressed: saveButton.clicked()
|
||||||
|
Keys.onEnterPressed: saveButton.clicked()
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var fileName = ""
|
var fileName = ""
|
||||||
if (GC.isMobile()) {
|
if (GC.isMobile()) {
|
||||||
|
|
@ -149,13 +168,17 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
Layout.preferredWidth: root.width / ( GC.isMobile() ? 2 : 3 )
|
Layout.preferredWidth: root.width / ( GC.isMobile() ? 2 : 3 )
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
id: clearButton
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
implicitWidth: 56
|
implicitWidth: 56
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
|
|
||||||
image: "qrc:/images/controls/delete.svg"
|
image: "qrc:/images/controls/delete.svg"
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
|
Keys.onReturnPressed: clearButton.clicked()
|
||||||
|
Keys.onEnterPressed: clearButton.clicked()
|
||||||
onClicked: function() {
|
onClicked: function() {
|
||||||
var headerText = qsTr("Clear logs?")
|
var headerText = qsTr("Clear logs?")
|
||||||
var yesButtonText = qsTr("Continue")
|
var yesButtonText = qsTr("Continue")
|
||||||
|
|
@ -166,8 +189,14 @@ disabled after 14 days, and all log files will be deleted.")
|
||||||
SettingsController.clearLogs()
|
SettingsController.clearLogs()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
PageController.showNotificationMessage(qsTr("Logs have been cleaned up"))
|
PageController.showNotificationMessage(qsTr("Logs have been cleaned up"))
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,17 @@ import ProtocolEnum 1.0
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
import "../Components"
|
import "../Components"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
signal lastItemTabClickedSignal()
|
||||||
|
|
||||||
|
onFocusChanged: content.isServerWithWriteAccess ?
|
||||||
|
labelWithButton.forceActiveFocus() :
|
||||||
|
labelWithButton3.forceActiveFocus()
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: InstallController
|
target: InstallController
|
||||||
|
|
||||||
|
|
@ -85,12 +92,15 @@ PageType {
|
||||||
property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
|
property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButton
|
||||||
visible: content.isServerWithWriteAccess
|
visible: content.isServerWithWriteAccess
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Check the server for previously installed Amnezia services")
|
text: qsTr("Check the server for previously installed Amnezia services")
|
||||||
descriptionText: qsTr("Add them to the application if they were not displayed")
|
descriptionText: qsTr("Add them to the application if they were not displayed")
|
||||||
|
|
||||||
|
KeyNavigation.tab: labelWithButton2
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
InstallController.scanServerForInstalledContainers()
|
InstallController.scanServerForInstalledContainers()
|
||||||
|
|
@ -103,12 +113,15 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButton2
|
||||||
visible: content.isServerWithWriteAccess
|
visible: content.isServerWithWriteAccess
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Reboot server")
|
text: qsTr("Reboot server")
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
KeyNavigation.tab: labelWithButton3
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Do you want to reboot the server?")
|
var headerText = qsTr("Do you want to reboot the server?")
|
||||||
var descriptionText = qsTr("The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?")
|
var descriptionText = qsTr("The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?")
|
||||||
|
|
@ -123,8 +136,14 @@ PageType {
|
||||||
InstallController.rebootProcessedServer()
|
InstallController.rebootProcessedServer()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton5.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton2.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -136,11 +155,22 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButton3
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Remove server from application")
|
text: qsTr("Remove server from application")
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (content.isServerWithWriteAccess) {
|
||||||
|
labelWithButton4.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
labelWithButton5.visible ?
|
||||||
|
labelWithButton5.forceActiveFocus() :
|
||||||
|
lastItemTabClickedSignal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Do you want to remove the server from application?")
|
var headerText = qsTr("Do you want to remove the server from application?")
|
||||||
var descriptionText = qsTr("All installed AmneziaVPN services will still remain on the server.")
|
var descriptionText = qsTr("All installed AmneziaVPN services will still remain on the server.")
|
||||||
|
|
@ -155,8 +185,14 @@ PageType {
|
||||||
InstallController.removeProcessedServer()
|
InstallController.removeProcessedServer()
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton5.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton3.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -166,12 +202,17 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButton4
|
||||||
visible: content.isServerWithWriteAccess
|
visible: content.isServerWithWriteAccess
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Clear server from Amnezia software")
|
text: qsTr("Clear server from Amnezia software")
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
Keys.onTabPressed: labelWithButton5.visible ?
|
||||||
|
labelWithButton5.forceActiveFocus() :
|
||||||
|
root.lastItemTabClickedSignal()
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Do you want to clear server from Amnezia software?")
|
var headerText = qsTr("Do you want to clear server from Amnezia software?")
|
||||||
var descriptionText = qsTr("All users whom you shared a connection with will no longer be able to connect to it.")
|
var descriptionText = qsTr("All users whom you shared a connection with will no longer be able to connect to it.")
|
||||||
|
|
@ -185,8 +226,14 @@ PageType {
|
||||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||||
InstallController.removeAllContainers()
|
InstallController.removeAllContainers()
|
||||||
}
|
}
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton5.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton4.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -198,12 +245,15 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: labelWithButton5
|
||||||
visible: ServersModel.getProcessedServerData("isServerFromApi")
|
visible: ServersModel.getProcessedServerData("isServerFromApi")
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Reset API config")
|
text: qsTr("Reset API config")
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
||||||
|
Keys.onTabPressed: root.lastItemTabClickedSignal()
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var headerText = qsTr("Do you want to reset API config?")
|
var headerText = qsTr("Do you want to reset API config?")
|
||||||
var descriptionText = ""
|
var descriptionText = ""
|
||||||
|
|
@ -218,8 +268,15 @@ PageType {
|
||||||
InstallController.removeApiConfig(ServersModel.processedIndex)
|
InstallController.removeApiConfig(ServersModel.processedIndex)
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton5.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
labelWithButton5.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: PageController
|
target: PageController
|
||||||
|
|
||||||
|
|
@ -37,6 +39,11 @@ PageType {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: header
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
|
@ -46,15 +53,26 @@ PageType {
|
||||||
id: header
|
id: header
|
||||||
model: proxyServersModel
|
model: proxyServersModel
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onFocusChanged: {
|
||||||
|
header.itemAt(0).focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
delegate: ColumnLayout {
|
delegate: ColumnLayout {
|
||||||
|
|
||||||
|
property alias focusItem: backButton
|
||||||
|
|
||||||
id: content
|
id: content
|
||||||
|
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: headerContent.actionButton
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
id: headerContent
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
|
@ -70,6 +88,8 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: tabBar
|
||||||
|
|
||||||
actionButtonFunction: function() {
|
actionButtonFunction: function() {
|
||||||
serverNameEditDrawer.open()
|
serverNameEditDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
@ -83,6 +103,12 @@ PageType {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: root.height * 0.35
|
expandedHeight: root.height * 0.35
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
headerContent.actionButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expandedContent: ColumnLayout {
|
expandedContent: ColumnLayout {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -99,6 +125,11 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem1
|
||||||
|
KeyNavigation.tab: serverName.textField
|
||||||
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
id: serverName
|
id: serverName
|
||||||
|
|
||||||
|
|
@ -117,6 +148,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
KeyNavigation.tab: focusItem1
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
if (serverName.textFieldText === "") {
|
if (serverName.textFieldText === "") {
|
||||||
|
|
@ -129,12 +161,6 @@ PageType {
|
||||||
serverNameEditDrawer.close()
|
serverNameEditDrawer.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (header.itemAt(0) && !GC.isMobile()) {
|
|
||||||
defaultActiveFocusItem = serverName.textField
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -152,25 +178,52 @@ PageType {
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
protocolsTab.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TabButtonType {
|
TabButtonType {
|
||||||
|
id: protocolsTab
|
||||||
visible: protocolsPage.installedProtocolsCount
|
visible: protocolsPage.installedProtocolsCount
|
||||||
width: protocolsPage.installedProtocolsCount ? undefined : 0
|
width: protocolsPage.installedProtocolsCount ? undefined : 0
|
||||||
isSelected: tabBar.currentIndex === 0
|
isSelected: tabBar.currentIndex === 0
|
||||||
text: qsTr("Protocols")
|
text: qsTr("Protocols")
|
||||||
|
|
||||||
|
KeyNavigation.tab: servicesTab
|
||||||
|
Keys.onReturnPressed: tabBar.currentIndex = 0
|
||||||
|
Keys.onEnterPressed: tabBar.currentIndex = 0
|
||||||
}
|
}
|
||||||
TabButtonType {
|
TabButtonType {
|
||||||
|
id: servicesTab
|
||||||
visible: servicesPage.installedServicesCount
|
visible: servicesPage.installedServicesCount
|
||||||
width: servicesPage.installedServicesCount ? undefined : 0
|
width: servicesPage.installedServicesCount ? undefined : 0
|
||||||
isSelected: tabBar.currentIndex === 1
|
isSelected: tabBar.currentIndex === 1
|
||||||
text: qsTr("Services")
|
text: qsTr("Services")
|
||||||
|
|
||||||
|
KeyNavigation.tab: dataTab
|
||||||
|
Keys.onReturnPressed: tabBar.currentIndex = 1
|
||||||
|
Keys.onEnterPressed: tabBar.currentIndex = 1
|
||||||
}
|
}
|
||||||
TabButtonType {
|
TabButtonType {
|
||||||
|
id: dataTab
|
||||||
isSelected: tabBar.currentIndex === 2
|
isSelected: tabBar.currentIndex === 2
|
||||||
text: qsTr("Management")
|
text: qsTr("Management")
|
||||||
|
|
||||||
|
Keys.onReturnPressed: tabBar.currentIndex = 2
|
||||||
|
Keys.onEnterPressed: tabBar.currentIndex = 2
|
||||||
|
KeyNavigation.tab: stackView.currentIndex === 0 ?
|
||||||
|
protocolsPage :
|
||||||
|
stackView.currentIndex === 1 ?
|
||||||
|
servicesPage :
|
||||||
|
dataPage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StackLayout {
|
StackLayout {
|
||||||
|
id: stackView
|
||||||
Layout.preferredWidth: root.width
|
Layout.preferredWidth: root.width
|
||||||
Layout.preferredHeight: root.height - tabBar.implicitHeight - header.implicitHeight
|
Layout.preferredHeight: root.height - tabBar.implicitHeight - header.implicitHeight
|
||||||
|
|
||||||
|
|
@ -179,14 +232,22 @@ PageType {
|
||||||
PageSettingsServerProtocols {
|
PageSettingsServerProtocols {
|
||||||
id: protocolsPage
|
id: protocolsPage
|
||||||
stackView: root.stackView
|
stackView: root.stackView
|
||||||
|
|
||||||
|
onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
|
||||||
}
|
}
|
||||||
PageSettingsServerServices {
|
PageSettingsServerServices {
|
||||||
id: servicesPage
|
id: servicesPage
|
||||||
stackView: root.stackView
|
stackView: root.stackView
|
||||||
|
|
||||||
|
onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
|
||||||
}
|
}
|
||||||
PageSettingsServerData {
|
PageSettingsServerData {
|
||||||
|
id: dataPage
|
||||||
stackView: root.stackView
|
stackView: root.stackView
|
||||||
|
|
||||||
|
onLastItemTabClickedSignal: lastItemTabClicked(focusItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,13 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: header
|
id: header
|
||||||
|
|
||||||
|
|
@ -28,6 +35,8 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: protocols
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
|
@ -47,7 +56,28 @@ PageType {
|
||||||
interactive: true
|
interactive: true
|
||||||
model: ProtocolsModel
|
model: ProtocolsModel
|
||||||
|
|
||||||
|
property int currentFocusIndex: 0
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
this.currentFocusIndex = 0
|
||||||
|
protocols.itemAtIndex(currentFocusIndex).focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentFocusIndex < this.count - 1) {
|
||||||
|
currentFocusIndex += 1
|
||||||
|
protocols.itemAtIndex(currentFocusIndex).focusItem.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
clearCacheButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
|
property var focusItem: button.rightButton
|
||||||
|
|
||||||
implicitWidth: protocols.width
|
implicitWidth: protocols.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
|
@ -95,6 +125,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
KeyNavigation.tab: removeButton
|
||||||
|
|
||||||
text: qsTr("Clear %1 profile").arg(ContainersModel.getProcessedContainerName())
|
text: qsTr("Clear %1 profile").arg(ContainersModel.getProcessedContainerName())
|
||||||
|
|
||||||
|
|
@ -116,6 +147,9 @@ PageType {
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -142,6 +176,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
||||||
textColor: "#EB5757"
|
textColor: "#EB5757"
|
||||||
|
|
@ -163,6 +198,9 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -184,3 +222,4 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@ PageType {
|
||||||
|
|
||||||
property var installedProtocolsCount
|
property var installedProtocolsCount
|
||||||
|
|
||||||
|
onFocusChanged: settingsContainersListView.forceActiveFocus()
|
||||||
|
signal lastItemTabClickedSignal()
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -35,6 +38,7 @@ PageType {
|
||||||
|
|
||||||
SettingsContainersListView {
|
SettingsContainersListView {
|
||||||
id: settingsContainersListView
|
id: settingsContainersListView
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ServersModel
|
target: ServersModel
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@ PageType {
|
||||||
|
|
||||||
property var installedServicesCount
|
property var installedServicesCount
|
||||||
|
|
||||||
|
onFocusChanged: settingsContainersListView.forceActiveFocus()
|
||||||
|
signal lastItemTabClickedSignal()
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -35,6 +38,7 @@ PageType {
|
||||||
|
|
||||||
SettingsContainersListView {
|
SettingsContainersListView {
|
||||||
id: settingsContainersListView
|
id: settingsContainersListView
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ServersModel
|
target: ServersModel
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,13 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: header
|
id: header
|
||||||
|
|
||||||
|
|
@ -27,6 +34,8 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: servers
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
|
@ -39,6 +48,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
id: fl
|
||||||
anchors.top: header.bottom
|
anchors.top: header.bottom
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
contentHeight: col.implicitHeight
|
contentHeight: col.implicitHeight
|
||||||
|
|
@ -59,10 +69,36 @@ PageType {
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focus: true
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentIndex < servers.count - 1) {
|
||||||
|
servers.incrementCurrentIndex()
|
||||||
|
} else {
|
||||||
|
servers.currentIndex = 0
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
root.lastItemTabClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
fl.ensureVisible(this.currentItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
currentIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: servers.width
|
implicitWidth: servers.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
onFocusChanged: {
|
||||||
|
if (focus) {
|
||||||
|
server.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
|
|
@ -75,6 +111,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: name
|
text: name
|
||||||
|
parentFlickable: fl
|
||||||
descriptionText: {
|
descriptionText: {
|
||||||
var servicesNameString = ""
|
var servicesNameString = ""
|
||||||
var servicesName = ServersModel.getAllInstalledServicesName(index)
|
var servicesName = ServersModel.getAllInstalledServicesName(index)
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,11 @@ PageType {
|
||||||
|
|
||||||
defaultActiveFocusItem: searchField.textField
|
defaultActiveFocusItem: searchField.textField
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
property bool pageEnabled
|
property bool pageEnabled
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
@ -92,6 +97,8 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: switcher
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -112,11 +119,17 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: 16
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
checked: SitesModel.isTunnelingEnabled
|
function onToggledFunc() {
|
||||||
onToggled: {
|
SitesModel.toggleSplitTunneling(this.checked)
|
||||||
SitesModel.toggleSplitTunneling(checked)
|
|
||||||
selector.text = root.routeModesModel[getRouteModesModelIndex()].name
|
selector.text = root.routeModesModel[getRouteModesModelIndex()].name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checked: SitesModel.isTunnelingEnabled
|
||||||
|
onToggled: { onToggledFunc() }
|
||||||
|
Keys.onEnterPressed: { onToggledFunc() }
|
||||||
|
Keys.onReturnPressed: { onToggledFunc() }
|
||||||
|
|
||||||
|
KeyNavigation.tab: selector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -165,10 +178,17 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: {
|
||||||
|
return sites.count > 0 ?
|
||||||
|
sites :
|
||||||
|
searchField.textField
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
id: fl
|
||||||
anchors.top: header.bottom
|
anchors.top: header.bottom
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
contentHeight: col.implicitHeight + addSiteButton.implicitHeight + addSiteButton.anchors.bottomMargin + addSiteButton.anchors.topMargin
|
contentHeight: col.implicitHeight + addSiteButton.implicitHeight + addSiteButton.anchors.bottomMargin + addSiteButton.anchors.topMargin
|
||||||
|
|
@ -208,10 +228,29 @@ PageType {
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focus: true
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentIndex < this.count - 1) {
|
||||||
|
this.incrementCurrentIndex()
|
||||||
|
} else {
|
||||||
|
currentIndex = 0
|
||||||
|
searchField.textField.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
fl.ensureVisible(currentItem)
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: sites.width
|
implicitWidth: sites.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
site.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
|
|
@ -220,6 +259,7 @@ PageType {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: site
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: url
|
text: url
|
||||||
|
|
@ -234,8 +274,14 @@ PageType {
|
||||||
|
|
||||||
var yesButtonFunction = function() {
|
var yesButtonFunction = function() {
|
||||||
SitesController.removeSite(proxySitesModel.mapToSource(index))
|
SitesController.removeSite(proxySitesModel.mapToSource(index))
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
site.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
site.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -246,6 +292,7 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,9 +320,11 @@ PageType {
|
||||||
id: searchField
|
id: searchField
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
rightButtonClickedOnEnter: true
|
||||||
|
|
||||||
textFieldPlaceholderText: qsTr("website or IP")
|
textFieldPlaceholderText: qsTr("website or IP")
|
||||||
buttonImageSource: "qrc:/images/controls/plus.svg"
|
buttonImageSource: "qrc:/images/controls/plus.svg"
|
||||||
|
KeyNavigation.tab: GC.isMobile() ? focusItem : addSiteButtonImage
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
|
|
@ -286,6 +335,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
id: addSiteButtonImage
|
||||||
implicitWidth: 56
|
implicitWidth: 56
|
||||||
implicitHeight: 56
|
implicitHeight: 56
|
||||||
|
|
||||||
|
|
@ -295,6 +345,11 @@ PageType {
|
||||||
onClicked: function () {
|
onClicked: function () {
|
||||||
moreActionsDrawer.open()
|
moreActionsDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onReturnPressed: addSiteButtonImage.clicked()
|
||||||
|
Keys.onEnterPressed: addSiteButtonImage.clicked()
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -304,6 +359,12 @@ PageType {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: parent.height * 0.4375
|
expandedHeight: parent.height * 0.4375
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (root.defaultActiveFocusItem && !GC.isMobile()) {
|
||||||
|
root.defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expandedContent: ColumnLayout {
|
expandedContent: ColumnLayout {
|
||||||
id: moreActionsDrawerContent
|
id: moreActionsDrawerContent
|
||||||
|
|
||||||
|
|
@ -311,6 +372,25 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: moreActionsDrawer
|
||||||
|
|
||||||
|
function onOpened() {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onActiveFocusChanged() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem1
|
||||||
|
KeyNavigation.tab: importSitesButton.rightButton
|
||||||
|
}
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.margins: 16
|
Layout.margins: 16
|
||||||
|
|
@ -319,6 +399,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: importSitesButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Import")
|
text: qsTr("Import")
|
||||||
|
|
@ -327,14 +408,19 @@ PageType {
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
importSitesDrawer.open()
|
importSitesDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: exportSitesButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: exportSitesButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Save site list")
|
text: qsTr("Save site list")
|
||||||
|
|
||||||
|
KeyNavigation.tab: focusItem1
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var fileName = ""
|
var fileName = ""
|
||||||
if (GC.isMobile()) {
|
if (GC.isMobile()) {
|
||||||
|
|
@ -365,9 +451,28 @@ PageType {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: parent.height * 0.4375
|
expandedHeight: parent.height * 0.4375
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
moreActionsDrawer.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expandedContent: Item {
|
expandedContent: Item {
|
||||||
implicitHeight: importSitesDrawer.expandedHeight
|
implicitHeight: importSitesDrawer.expandedHeight
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: importSitesDrawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem2.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem2
|
||||||
|
KeyNavigation.tab: importSitesDrawerBackButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: importSitesDrawerBackButton
|
id: importSitesDrawerBackButton
|
||||||
|
|
||||||
|
|
@ -376,6 +481,8 @@ PageType {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
|
KeyNavigation.tab: importSitesButton2
|
||||||
|
|
||||||
backButtonFunction: function() {
|
backButtonFunction: function() {
|
||||||
importSitesDrawer.close()
|
importSitesDrawer.close()
|
||||||
}
|
}
|
||||||
|
|
@ -404,9 +511,11 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: importSitesButton2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Replace site list")
|
text: qsTr("Replace site list")
|
||||||
|
KeyNavigation.tab: importSitesButton3
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var fileName = SystemController.getFileName(qsTr("Open sites file"),
|
var fileName = SystemController.getFileName(qsTr("Open sites file"),
|
||||||
|
|
@ -420,8 +529,10 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: importSitesButton3
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: qsTr("Add imported sites to existing ones")
|
text: qsTr("Add imported sites to existing ones")
|
||||||
|
KeyNavigation.tab: focusItem2
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var fileName = SystemController.getFileName(qsTr("Open sites file"),
|
var fileName = SystemController.getFileName(qsTr("Open sites file"),
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -37,8 +39,15 @@ PageType {
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
|
KeyNavigation.tab: fileButton.rightButton
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
|
@ -61,6 +70,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: fileButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
|
|
||||||
|
|
@ -68,6 +78,8 @@ PageType {
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: qrButton.visible ? qrButton.rightButton : textButton.rightButton
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
var nameFilter = !ServersModel.getServersCount() ? "Config or backup files (*.vpn *.ovpn *.conf *.json *.backup)" :
|
var nameFilter = !ServersModel.getServersCount() ? "Config or backup files (*.vpn *.ovpn *.conf *.json *.backup)" :
|
||||||
"Config files (*.vpn *.ovpn *.conf *.json)"
|
"Config files (*.vpn *.ovpn *.conf *.json)"
|
||||||
|
|
@ -83,6 +95,7 @@ PageType {
|
||||||
DividerType {}
|
DividerType {}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: qrButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
visible: SettingsController.isCameraPresent()
|
visible: SettingsController.isCameraPresent()
|
||||||
|
|
||||||
|
|
@ -90,6 +103,8 @@ PageType {
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
leftImageSource: "qrc:/images/controls/qr-code.svg"
|
leftImageSource: "qrc:/images/controls/qr-code.svg"
|
||||||
|
|
||||||
|
KeyNavigation.tab: textButton.rightButton
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
ImportController.startDecodingQr()
|
ImportController.startDecodingQr()
|
||||||
if (Qt.platform.os === "ios") {
|
if (Qt.platform.os === "ios") {
|
||||||
|
|
@ -103,12 +118,15 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: textButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Key as text")
|
text: qsTr("Key as text")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
leftImageSource: "qrc:/images/controls/text-cursor.svg"
|
leftImageSource: "qrc:/images/controls/text-cursor.svg"
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardTextKey)
|
PageController.goToPage(PageEnum.PageSetupWizardTextKey)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,11 @@ PageType {
|
||||||
|
|
||||||
defaultActiveFocusItem: hostname.textField
|
defaultActiveFocusItem: hostname.textField
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -21,6 +26,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: hostname.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -107,6 +114,8 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Continue")
|
text: qsTr("Continue")
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
forceActiveFocus()
|
forceActiveFocus()
|
||||||
if (!isCredentialsFilled()) {
|
if (!isCredentialsFilled()) {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool isEasySetup: true
|
property bool isEasySetup: true
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
SortFilterProxyModel {
|
SortFilterProxyModel {
|
||||||
id: proxyContainersModel
|
id: proxyContainersModel
|
||||||
|
|
@ -32,6 +33,14 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
implicitWidth: 1
|
||||||
|
implicitHeight: 54
|
||||||
|
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -39,6 +48,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: continueButton
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -145,17 +156,14 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
implicitWidth: 1
|
|
||||||
implicitHeight: 54
|
|
||||||
}
|
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
id: continueButton
|
id: continueButton
|
||||||
|
|
||||||
implicitWidth: parent.width
|
implicitWidth: parent.width
|
||||||
|
|
||||||
text: qsTr("Continue")
|
text: qsTr("Continue")
|
||||||
|
KeyNavigation.tab: setupLaterButton
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
if (root.isEasySetup) {
|
if (root.isEasySetup) {
|
||||||
|
|
@ -184,6 +192,9 @@ PageType {
|
||||||
textColor: "#D7D8DB"
|
textColor: "#D7D8DB"
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
visible: {
|
visible: {
|
||||||
if (PageController.isTriggeredByConnectButton()) {
|
if (PageController.isTriggeredByConnectButton()) {
|
||||||
PageController.setTriggeredByConnectButton(false)
|
PageController.setTriggeredByConnectButton(false)
|
||||||
|
|
|
||||||
|
|
@ -61,12 +61,19 @@ PageType {
|
||||||
anchors.rightMargin: 16
|
anchors.rightMargin: 16
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
Layout.rightMargin: -16
|
Layout.rightMargin: -16
|
||||||
Layout.leftMargin: -16
|
Layout.leftMargin: -16
|
||||||
|
|
||||||
|
KeyNavigation.tab: showDetailsButton
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
|
@ -93,6 +100,7 @@ PageType {
|
||||||
textColor: "#FBB26A"
|
textColor: "#FBB26A"
|
||||||
|
|
||||||
text: qsTr("More detailed")
|
text: qsTr("More detailed")
|
||||||
|
KeyNavigation.tab: transportProtoSelector
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
showDetailsDrawer.open()
|
showDetailsDrawer.open()
|
||||||
|
|
@ -102,12 +110,35 @@ PageType {
|
||||||
DrawerType2 {
|
DrawerType2 {
|
||||||
id: showDetailsDrawer
|
id: showDetailsDrawer
|
||||||
parent: root
|
parent: root
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: parent.height * 0.9
|
expandedHeight: parent.height * 0.9
|
||||||
expandedContent: Item {
|
expandedContent: Item {
|
||||||
|
Connections {
|
||||||
|
target: showDetailsDrawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem2.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
implicitHeight: showDetailsDrawer.expandedHeight
|
implicitHeight: showDetailsDrawer.expandedHeight
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem2
|
||||||
|
KeyNavigation.tab: showDetailsBackButton
|
||||||
|
onFocusChanged: {
|
||||||
|
if (focusItem2.activeFocus) {
|
||||||
|
fl.contentY = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: showDetailsBackButton
|
id: showDetailsBackButton
|
||||||
|
|
||||||
|
|
@ -116,12 +147,15 @@ PageType {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 16
|
anchors.topMargin: 16
|
||||||
|
|
||||||
|
KeyNavigation.tab: showDetailsCloseButton
|
||||||
|
|
||||||
backButtonFunction: function() {
|
backButtonFunction: function() {
|
||||||
showDetailsDrawer.close()
|
showDetailsDrawer.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
id: fl
|
||||||
anchors.top: showDetailsBackButton.bottom
|
anchors.top: showDetailsBackButton.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
@ -158,17 +192,19 @@ PageType {
|
||||||
textFormat: Text.MarkdownText
|
textFormat: Text.MarkdownText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: showDetailsCloseButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.bottomMargin: 32
|
Layout.bottomMargin: 32
|
||||||
|
parentFlickable: fl
|
||||||
|
|
||||||
text: qsTr("Close")
|
text: qsTr("Close")
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem2)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
showDetailsDrawer.close()
|
showDetailsDrawer.close()
|
||||||
|
|
@ -192,6 +228,8 @@ PageType {
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
rootWidth: root.width
|
rootWidth: root.width
|
||||||
|
|
||||||
|
KeyNavigation.tab: (port.visible && port.enabled) ? port.textField : installButton
|
||||||
}
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
|
|
@ -220,6 +258,8 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Install")
|
text: qsTr("Install")
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||||
InstallController.install(dockerContainer, port.textFieldText, transportProtoSelector.currentIndex)
|
InstallController.install(dockerContainer, port.textFieldText, transportProtoSelector.currentIndex)
|
||||||
|
|
@ -241,7 +281,10 @@ PageType {
|
||||||
transportProtoSelector.visible = protocolSelectorVisible
|
transportProtoSelector.visible = protocolSelectorVisible
|
||||||
transportProtoHeader.visible = protocolSelectorVisible
|
transportProtoHeader.visible = protocolSelectorVisible
|
||||||
|
|
||||||
defaultActiveFocusItem = port.textField
|
if (port.visible && port.enabled)
|
||||||
|
defaultActiveFocusItem = port.textField
|
||||||
|
else
|
||||||
|
defaultActiveFocusItem = focusItem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,13 @@ import "../Config"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
SortFilterProxyModel {
|
SortFilterProxyModel {
|
||||||
id: proxyContainersModel
|
id: proxyContainersModel
|
||||||
sourceModel: ContainersModel
|
sourceModel: ContainersModel
|
||||||
|
|
@ -30,7 +37,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: backButton
|
id: backButtonLayout
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -39,12 +46,14 @@ PageType {
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
KeyNavigation.tab: containers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButtonLayout.bottom
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.implicitHeight + content.anchors.topMargin + content.anchors.bottomMargin
|
contentHeight: content.implicitHeight + content.anchors.topMargin + content.anchors.bottomMargin
|
||||||
|
|
||||||
|
|
@ -79,15 +88,49 @@ PageType {
|
||||||
id: containers
|
id: containers
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: containers.contentItem.height
|
height: containers.contentItem.height
|
||||||
currentIndex: -1
|
// currentIndex: -1
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
model: proxyContainersModel
|
model: proxyContainersModel
|
||||||
|
|
||||||
|
function ensureCurrentItemVisible() {
|
||||||
|
if (currentIndex >= 0) {
|
||||||
|
if (currentItem.y < fl.contentY) {
|
||||||
|
fl.contentY = currentItem.y
|
||||||
|
} else if (currentItem.y + currentItem.height + header.height > fl.contentY + fl.height) {
|
||||||
|
fl.contentY = currentItem.y + currentItem.height + header.height - fl.height + 40 // 40 is a bottom margin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (currentIndex < this.count - 1) {
|
||||||
|
this.incrementCurrentIndex()
|
||||||
|
} else {
|
||||||
|
this.currentIndex = 0
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureCurrentItemVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
currentIndex = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: containers.width
|
implicitWidth: containers.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
container.rightButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ PageType {
|
||||||
|
|
||||||
property bool isControlsDisabled: false
|
property bool isControlsDisabled: false
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: PageController
|
target: PageController
|
||||||
|
|
||||||
|
|
@ -136,7 +138,13 @@ PageType {
|
||||||
qsTr(" Helps you access blocked content without revealing your privacy, even to VPN providers.")
|
qsTr(" Helps you access blocked content without revealing your privacy, even to VPN providers.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: startButton
|
||||||
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: startButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 32
|
Layout.topMargin: 32
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
@ -147,9 +155,12 @@ PageType {
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
connectionTypeSelection.open()
|
connectionTypeSelection.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: startButton2
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: startButton2
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 8
|
Layout.topMargin: 8
|
||||||
Layout.leftMargin: 16
|
Layout.leftMargin: 16
|
||||||
|
|
@ -167,11 +178,18 @@ PageType {
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
Qt.openUrlExternally(qsTr("https://amnezia.org/instructions/0_starter-guide"))
|
Qt.openUrlExternally(qsTr("https://amnezia.org/instructions/0_starter-guide"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionTypeSelectionDrawer {
|
ConnectionTypeSelectionDrawer {
|
||||||
id: connectionTypeSelection
|
id: connectionTypeSelection
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
PageController.forceTabBarActiveFocus()
|
||||||
|
root.defaultActiveFocusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,12 @@ PageType {
|
||||||
|
|
||||||
defaultActiveFocusItem: textKey.textField
|
defaultActiveFocusItem: textKey.textField
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -30,7 +36,9 @@ PageType {
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
Layout.topMargin: 20
|
Layout.topMargin: 20
|
||||||
|
KeyNavigation.tab: textKey.textField
|
||||||
}
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
|
@ -75,6 +83,7 @@ PageType {
|
||||||
anchors.bottomMargin: 32
|
anchors.bottomMargin: 32
|
||||||
|
|
||||||
text: qsTr("Continue")
|
text: qsTr("Continue")
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
|
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,24 @@ PageType {
|
||||||
|
|
||||||
property bool showContent: false
|
property bool showContent: false
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: showContentButton
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ImportController
|
target: ImportController
|
||||||
|
|
||||||
|
|
@ -39,15 +57,6 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackButtonType {
|
|
||||||
id: backButton
|
|
||||||
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.topMargin: 20
|
|
||||||
}
|
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
id: fl
|
id: fl
|
||||||
anchors.top: backButton.bottom
|
anchors.top: backButton.bottom
|
||||||
|
|
@ -88,6 +97,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: showContentButton
|
||||||
Layout.topMargin: 16
|
Layout.topMargin: 16
|
||||||
Layout.leftMargin: -8
|
Layout.leftMargin: -8
|
||||||
implicitHeight: 32
|
implicitHeight: 32
|
||||||
|
|
@ -99,6 +109,7 @@ PageType {
|
||||||
textColor: "#FBB26A"
|
textColor: "#FBB26A"
|
||||||
|
|
||||||
text: showContent ? qsTr("Collapse content") : qsTr("Show content")
|
text: showContent ? qsTr("Collapse content") : qsTr("Show content")
|
||||||
|
KeyNavigation.tab: connectButton
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
showContent = !showContent
|
showContent = !showContent
|
||||||
|
|
@ -138,15 +149,16 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: connectButton
|
|
||||||
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: 16
|
anchors.rightMargin: 16
|
||||||
anchors.leftMargin: 16
|
anchors.leftMargin: 16
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: connectButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.bottomMargin: 32
|
Layout.bottomMargin: 32
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,8 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
id: a
|
||||||
|
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
contentHeight: content.height + 10
|
contentHeight: content.height + 10
|
||||||
|
|
@ -168,7 +170,18 @@ PageType {
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: header.actionButton
|
||||||
|
onFocusChanged: {
|
||||||
|
if (focusItem.activeFocus) {
|
||||||
|
a.contentY = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HeaderType {
|
HeaderType {
|
||||||
|
id: header
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
|
|
||||||
|
|
@ -179,6 +192,8 @@ PageType {
|
||||||
shareFullAccessDrawer.open()
|
shareFullAccessDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: connectionRadioButton
|
||||||
|
|
||||||
DrawerType2 {
|
DrawerType2 {
|
||||||
id: shareFullAccessDrawer
|
id: shareFullAccessDrawer
|
||||||
|
|
||||||
|
|
@ -186,6 +201,11 @@ PageType {
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: root.height * 0.45
|
expandedHeight: root.height * 0.45
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
clientNameTextField.textField.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expandedContent: ColumnLayout {
|
expandedContent: ColumnLayout {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
|
|
@ -195,6 +215,14 @@ PageType {
|
||||||
|
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: shareFullAccessDrawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
|
|
@ -205,17 +233,24 @@ PageType {
|
||||||
descriptionText: qsTr("Use for your own devices, or share with those you trust to manage the server.")
|
descriptionText: qsTr("Use for your own devices, or share with those you trust to manage the server.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: shareFullAccessButton.rightButton
|
||||||
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: shareFullAccessButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Share")
|
text: qsTr("Share")
|
||||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
KeyNavigation.tab: focusItem
|
||||||
|
|
||||||
clickedFunction: function() {
|
clickedFunction: function() {
|
||||||
PageController.goToPage(PageEnum.PageShareFullAccess)
|
PageController.goToPage(PageEnum.PageShareFullAccess)
|
||||||
shareFullAccessDrawer.close()
|
shareFullAccessDrawer.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -240,28 +275,38 @@ PageType {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
HorizontalRadioButton {
|
HorizontalRadioButton {
|
||||||
|
id: connectionRadioButton
|
||||||
checked: accessTypeSelector.currentIndex === 0
|
checked: accessTypeSelector.currentIndex === 0
|
||||||
|
|
||||||
implicitWidth: (root.width - 32) / 2
|
implicitWidth: (root.width - 32) / 2
|
||||||
text: qsTr("Connection")
|
text: qsTr("Connection")
|
||||||
|
|
||||||
|
KeyNavigation.tab: usersRadioButton
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
accessTypeSelector.currentIndex = 0
|
accessTypeSelector.currentIndex = 0
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
clientNameTextField.textField.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalRadioButton {
|
HorizontalRadioButton {
|
||||||
|
id: usersRadioButton
|
||||||
checked: accessTypeSelector.currentIndex === 1
|
checked: accessTypeSelector.currentIndex === 1
|
||||||
|
|
||||||
implicitWidth: (root.width - 32) / 2
|
implicitWidth: (root.width - 32) / 2
|
||||||
text: qsTr("Users")
|
text: qsTr("Users")
|
||||||
|
|
||||||
|
KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ? clientNameTextField.textField : serverSelector
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
accessTypeSelector.currentIndex = 1
|
accessTypeSelector.currentIndex = 1
|
||||||
PageController.showBusyIndicator(true)
|
PageController.showBusyIndicator(true)
|
||||||
ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(),
|
ExportController.updateClientManagementModel(ContainersModel.getProcessedContainerIndex(),
|
||||||
ServersModel.getProcessedServerCredentials())
|
ServersModel.getProcessedServerCredentials())
|
||||||
PageController.showBusyIndicator(false)
|
PageController.showBusyIndicator(false)
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -291,7 +336,8 @@ PageType {
|
||||||
|
|
||||||
checkEmptyText: true
|
checkEmptyText: true
|
||||||
|
|
||||||
KeyNavigation.tab: shareButton
|
KeyNavigation.tab: serverSelector
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
|
|
@ -311,7 +357,6 @@ PageType {
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
id: serverSelectorListView
|
id: serverSelectorListView
|
||||||
|
|
||||||
rootWidth: root.width
|
rootWidth: root.width
|
||||||
imageSource: "qrc:/images/controls/check.svg"
|
imageSource: "qrc:/images/controls/check.svg"
|
||||||
|
|
||||||
|
|
@ -356,6 +401,8 @@ PageType {
|
||||||
ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
|
ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: protocolSelector
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
|
|
@ -454,6 +501,12 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ?
|
||||||
|
exportTypeSelector :
|
||||||
|
isSearchBarVisible ?
|
||||||
|
searchTextField.textField :
|
||||||
|
usersHeader.actionButton
|
||||||
}
|
}
|
||||||
|
|
||||||
DropDownType {
|
DropDownType {
|
||||||
|
|
@ -497,6 +550,9 @@ PageType {
|
||||||
exportTypeSelector.currentIndex = currentIndex
|
exportTypeSelector.currentIndex = currentIndex
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: shareButton
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
|
@ -510,16 +566,22 @@ PageType {
|
||||||
visible: accessTypeSelector.currentIndex === 0
|
visible: accessTypeSelector.currentIndex === 0
|
||||||
|
|
||||||
text: qsTr("Share")
|
text: qsTr("Share")
|
||||||
imageSource: "qrc:/images/controls/share-2.svg"
|
imageSource: "qrc:/images/controls/share-2.svg"
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
|
parentFlickable: a
|
||||||
|
|
||||||
clickedFunc: function(){
|
clickedFunc: function(){
|
||||||
if (clientNameTextField.textFieldText !== "") {
|
if (clientNameTextField.textFieldText !== "") {
|
||||||
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
|
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
|
id: usersHeader
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
Layout.bottomMargin: 16
|
Layout.bottomMargin: 16
|
||||||
|
|
@ -531,6 +593,11 @@ PageType {
|
||||||
actionButtonFunction: function() {
|
actionButtonFunction: function() {
|
||||||
root.isSearchBarVisible = true
|
root.isSearchBarVisible = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: clientsListView.model.count > 0 ?
|
||||||
|
clientsListView.forceActiveFocus() :
|
||||||
|
lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -543,16 +610,66 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
textFieldPlaceholderText: qsTr("Search")
|
textFieldPlaceholderText: qsTr("Search")
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: root
|
||||||
|
function onIsSearchBarVisibleChanged() {
|
||||||
|
if (root.isSearchBarVisible) {
|
||||||
|
searchTextField.textField.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
searchTextField.textFieldText = ""
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
usersHeader.actionButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onEscapePressed: {
|
||||||
|
root.isSearchBarVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigateTo() {
|
||||||
|
if (GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (searchTextField.textFieldText === "") {
|
||||||
|
root.isSearchBarVisible = false
|
||||||
|
usersHeader.actionButton.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
closeSearchButton.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: { navigateTo() }
|
||||||
|
Keys.onEnterPressed: { navigateTo() }
|
||||||
|
Keys.onReturnPressed: { navigateTo() }
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageButtonType {
|
ImageButtonType {
|
||||||
|
id: closeSearchButton
|
||||||
image: "qrc:/images/controls/close.svg"
|
image: "qrc:/images/controls/close.svg"
|
||||||
imageColor: "#D7D8DB"
|
imageColor: "#D7D8DB"
|
||||||
|
|
||||||
onClicked: function() {
|
Keys.onTabPressed: {
|
||||||
root.isSearchBarVisible = false
|
if (!GC.isMobile()) {
|
||||||
searchTextField.textFieldText = ""
|
if (clientsListView.model.count > 0) {
|
||||||
|
clientsListView.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
lastItemTabClicked(focusItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clickedFunc() {
|
||||||
|
root.isSearchBarVisible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: clickedFunc()
|
||||||
|
Keys.onEnterPressed: clickedFunc()
|
||||||
|
Keys.onReturnPressed: clickedFunc()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -576,10 +693,43 @@ PageType {
|
||||||
clip: true
|
clip: true
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
||||||
|
activeFocusOnTab: true
|
||||||
|
focus: true
|
||||||
|
Keys.onTabPressed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
if (currentIndex < this.count - 1) {
|
||||||
|
this.incrementCurrentIndex()
|
||||||
|
currentItem.focusItem.forceActiveFocus()
|
||||||
|
} else {
|
||||||
|
this.currentIndex = 0
|
||||||
|
lastItemTabClicked(focusItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (focus && !GC.isMobile()) {
|
||||||
|
currentIndex = 0
|
||||||
|
currentItem.focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
if (currentItem) {
|
||||||
|
if (currentItem.y < a.contentY) {
|
||||||
|
a.contentY = currentItem.y
|
||||||
|
} else if (currentItem.y + currentItem.height + clientsListView.y > a.contentY + a.height) {
|
||||||
|
a.contentY = currentItem.y + clientsListView.y + currentItem.height - a.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
implicitWidth: clientsListView.width
|
implicitWidth: clientsListView.width
|
||||||
implicitHeight: delegateContent.implicitHeight
|
implicitHeight: delegateContent.implicitHeight
|
||||||
|
|
||||||
|
property alias focusItem: clientFocusItem.rightButton
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: delegateContent
|
id: delegateContent
|
||||||
|
|
||||||
|
|
@ -591,6 +741,7 @@ PageType {
|
||||||
anchors.leftMargin: -16
|
anchors.leftMargin: -16
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
|
id: clientFocusItem
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: clientName
|
text: clientName
|
||||||
|
|
@ -608,6 +759,12 @@ PageType {
|
||||||
|
|
||||||
parent: root
|
parent: root
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: root.height * 0.5
|
expandedHeight: root.height * 0.5
|
||||||
|
|
||||||
|
|
@ -621,6 +778,14 @@ PageType {
|
||||||
|
|
||||||
spacing: 8
|
spacing: 8
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: clientInfoDrawer
|
||||||
|
enabled: !GC.isMobile()
|
||||||
|
function onOpened() {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Header2Type {
|
Header2Type {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.bottomMargin: 24
|
Layout.bottomMargin: 24
|
||||||
|
|
@ -629,7 +794,13 @@ PageType {
|
||||||
descriptionText: qsTr("Creation date: ") + creationDate
|
descriptionText: qsTr("Creation date: ") + creationDate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem1
|
||||||
|
KeyNavigation.tab: renameButton
|
||||||
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: renameButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 24
|
Layout.topMargin: 24
|
||||||
|
|
||||||
|
|
@ -642,6 +813,8 @@ PageType {
|
||||||
|
|
||||||
text: qsTr("Rename")
|
text: qsTr("Rename")
|
||||||
|
|
||||||
|
KeyNavigation.tab: revokeButton
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
clientNameEditDrawer.open()
|
clientNameEditDrawer.open()
|
||||||
}
|
}
|
||||||
|
|
@ -654,6 +827,12 @@ PageType {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
expandedHeight: root.height * 0.35
|
expandedHeight: root.height * 0.35
|
||||||
|
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expandedContent: ColumnLayout {
|
expandedContent: ColumnLayout {
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|
@ -670,6 +849,11 @@ PageType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem2
|
||||||
|
KeyNavigation.tab: clientNameEditor.textField
|
||||||
|
}
|
||||||
|
|
||||||
TextFieldWithHeaderType {
|
TextFieldWithHeaderType {
|
||||||
id: clientNameEditor
|
id: clientNameEditor
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
@ -687,6 +871,7 @@ PageType {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: qsTr("Save")
|
text: qsTr("Save")
|
||||||
|
KeyNavigation.tab: focusItem2
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
if (clientNameEditor.textFieldText === "") {
|
if (clientNameEditor.textFieldText === "") {
|
||||||
|
|
@ -709,6 +894,7 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: revokeButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
defaultColor: "transparent"
|
defaultColor: "transparent"
|
||||||
|
|
@ -719,6 +905,7 @@ PageType {
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
|
|
||||||
text: qsTr("Revoke")
|
text: qsTr("Revoke")
|
||||||
|
KeyNavigation.tab: focusItem1
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
var headerText = qsTr("Revoke the config for a user - %1?").arg(clientName)
|
var headerText = qsTr("Revoke the config for a user - %1?").arg(clientName)
|
||||||
|
|
@ -731,6 +918,9 @@ PageType {
|
||||||
root.revokeConfig(index)
|
root.revokeConfig(index)
|
||||||
}
|
}
|
||||||
var noButtonFunction = function() {
|
var noButtonFunction = function() {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem1.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||||
|
|
@ -748,6 +938,11 @@ PageType {
|
||||||
id: shareConnectionDrawer
|
id: shareConnectionDrawer
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
clientNameTextField.textField.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,18 @@ import "./"
|
||||||
import "../Controls2"
|
import "../Controls2"
|
||||||
import "../Controls2/TextTypes"
|
import "../Controls2/TextTypes"
|
||||||
import "../Components"
|
import "../Components"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: focusItem
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: focusItem
|
||||||
|
KeyNavigation.tab: backButton
|
||||||
|
}
|
||||||
|
|
||||||
BackButtonType {
|
BackButtonType {
|
||||||
id: backButton
|
id: backButton
|
||||||
|
|
||||||
|
|
@ -23,6 +31,8 @@ PageType {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.topMargin: 20
|
anchors.topMargin: 20
|
||||||
|
|
||||||
|
KeyNavigation.tab: serverSelector
|
||||||
}
|
}
|
||||||
|
|
||||||
FlickableType {
|
FlickableType {
|
||||||
|
|
@ -74,6 +84,8 @@ PageType {
|
||||||
descriptionText: qsTr("Server")
|
descriptionText: qsTr("Server")
|
||||||
headerText: qsTr("Server")
|
headerText: qsTr("Server")
|
||||||
|
|
||||||
|
KeyNavigation.tab: shareButton
|
||||||
|
|
||||||
listView: ListViewWithRadioButtonType {
|
listView: ListViewWithRadioButtonType {
|
||||||
id: serverSelectorListView
|
id: serverSelectorListView
|
||||||
|
|
||||||
|
|
@ -100,7 +112,7 @@ PageType {
|
||||||
|
|
||||||
shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
|
shareConnectionDrawer.headerText = qsTr("Accessing ") + serverSelector.text
|
||||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
|
shareConnectionDrawer.configContentHeaderText = qsTr("File with accessing settings to ") + serverSelector.text
|
||||||
serverSelector.close()
|
// serverSelector.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|
@ -117,12 +129,15 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicButtonType {
|
BasicButtonType {
|
||||||
|
id: shareButton
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 40
|
Layout.topMargin: 40
|
||||||
|
|
||||||
text: qsTr("Share")
|
text: qsTr("Share")
|
||||||
imageSource: "qrc:/images/controls/share-2.svg"
|
imageSource: "qrc:/images/controls/share-2.svg"
|
||||||
|
|
||||||
|
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||||
|
|
||||||
clickedFunc: function() {
|
clickedFunc: function() {
|
||||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||||
|
|
@ -149,5 +164,10 @@ PageType {
|
||||||
id: shareConnectionDrawer
|
id: shareConnectionDrawer
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
onClosed: {
|
||||||
|
if (!GC.isMobile()) {
|
||||||
|
focusItem.forceActiveFocus()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import "../Components"
|
||||||
PageType {
|
PageType {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
defaultActiveFocusItem: homeTabButton
|
||||||
|
|
||||||
property bool isControlsDisabled: false
|
property bool isControlsDisabled: false
|
||||||
property bool isTabBarDisabled: false
|
property bool isTabBarDisabled: false
|
||||||
|
|
||||||
|
|
@ -82,6 +84,16 @@ PageType {
|
||||||
PageController.closePage()
|
PageController.closePage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onForceTabBarActiveFocus() {
|
||||||
|
homeTabButton.focus = true
|
||||||
|
tabBar.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onForceStackActiveFocus() {
|
||||||
|
homeTabButton.focus = true
|
||||||
|
tabBarStackView.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
@ -211,13 +223,19 @@ PageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
TabImageButtonType {
|
TabImageButtonType {
|
||||||
|
id: homeTabButton
|
||||||
isSelected: tabBar.currentIndex === 0
|
isSelected: tabBar.currentIndex === 0
|
||||||
image: "qrc:/images/controls/home.svg"
|
image: "qrc:/images/controls/home.svg"
|
||||||
onClicked: {
|
clickedFunc: function () {
|
||||||
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
|
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
|
||||||
ServersModel.processedIndex = ServersModel.defaultIndex
|
ServersModel.processedIndex = ServersModel.defaultIndex
|
||||||
|
tabBar.currentIndex = 0
|
||||||
tabBar.previousIndex = 0
|
tabBar.previousIndex = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: shareTabButton
|
||||||
|
Keys.onEnterPressed: this.clicked()
|
||||||
|
Keys.onReturnPressed: this.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
TabImageButtonType {
|
TabImageButtonType {
|
||||||
|
|
@ -238,27 +256,37 @@ PageType {
|
||||||
|
|
||||||
isSelected: tabBar.currentIndex === 1
|
isSelected: tabBar.currentIndex === 1
|
||||||
image: "qrc:/images/controls/share-2.svg"
|
image: "qrc:/images/controls/share-2.svg"
|
||||||
onClicked: {
|
clickedFunc: function () {
|
||||||
tabBarStackView.goToTabBarPage(PageEnum.PageShare)
|
tabBarStackView.goToTabBarPage(PageEnum.PageShare)
|
||||||
|
tabBar.currentIndex = 1
|
||||||
tabBar.previousIndex = 1
|
tabBar.previousIndex = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: settingsTabButton
|
||||||
}
|
}
|
||||||
|
|
||||||
TabImageButtonType {
|
TabImageButtonType {
|
||||||
|
id: settingsTabButton
|
||||||
isSelected: tabBar.currentIndex === 2
|
isSelected: tabBar.currentIndex === 2
|
||||||
image: "qrc:/images/controls/settings-2.svg"
|
image: "qrc:/images/controls/settings-2.svg"
|
||||||
onClicked: {
|
clickedFunc: function () {
|
||||||
tabBarStackView.goToTabBarPage(PageEnum.PageSettings)
|
tabBarStackView.goToTabBarPage(PageEnum.PageSettings)
|
||||||
|
tabBar.currentIndex = 2
|
||||||
tabBar.previousIndex = 2
|
tabBar.previousIndex = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyNavigation.tab: plusTabButton
|
||||||
}
|
}
|
||||||
|
|
||||||
TabImageButtonType {
|
TabImageButtonType {
|
||||||
|
id: plusTabButton
|
||||||
isSelected: tabBar.currentIndex === 3
|
isSelected: tabBar.currentIndex === 3
|
||||||
image: "qrc:/images/controls/plus.svg"
|
image: "qrc:/images/controls/plus.svg"
|
||||||
onClicked: {
|
clickedFunc: function () {
|
||||||
connectionTypeSelection.open()
|
connectionTypeSelection.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keys.onTabPressed: PageController.forceStackActiveFocus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,6 +294,7 @@ PageType {
|
||||||
id: connectionTypeSelection
|
id: connectionTypeSelection
|
||||||
|
|
||||||
onAboutToHide: {
|
onAboutToHide: {
|
||||||
|
PageController.forceTabBarActiveFocus()
|
||||||
tabBar.setCurrentIndex(tabBar.previousIndex)
|
tabBar.setCurrentIndex(tabBar.previousIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue