mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-21 17:46:48 +00:00
GODT-1346: GODT-1340 GODT-1315 QML changes
GODT-1365: Create ComboBox component GODT-1338: GODT-1343 Help view buttons GODT-1340: Not crashing, user list updating in main thread. GODT-1345: adding panic handlers
This commit is contained in:
@ -48,9 +48,9 @@ Item {
|
||||
if (root.usedFraction < .75) return root.colorScheme.signal_warning
|
||||
return root.colorScheme.signal_danger
|
||||
}
|
||||
property real usedFraction: root.user.totalBytes ? root.user.usedBytes / root.user.totalBytes : 0
|
||||
property string totalSpace: root.spaceWithUnits(root.user.totalBytes)
|
||||
property string usedSpace: root.spaceWithUnits(root.user.usedBytes)
|
||||
property real usedFraction: root.user && root.user.totalBytes ? Math.abs(root.user.usedBytes / root.user.totalBytes) : 0
|
||||
property string totalSpace: root.spaceWithUnits(root.user ? root.user.totalBytes : 0)
|
||||
property string usedSpace: root.spaceWithUnits(root.user ? root.user.usedBytes : 0)
|
||||
|
||||
function spaceWithUnits(bytes){
|
||||
if (bytes*1 !== bytes ) return "0 kB"
|
||||
@ -96,7 +96,7 @@ Item {
|
||||
Label {
|
||||
colorScheme: root.colorScheme
|
||||
anchors.fill: parent
|
||||
text: root.user.avatarText.toUpperCase()
|
||||
text: root.user ? root.user.avatarText.toUpperCase(): ""
|
||||
type: {
|
||||
switch (root.type) {
|
||||
case AccountDelegate.SmallView: return Label.Body
|
||||
@ -128,7 +128,7 @@ Item {
|
||||
)
|
||||
|
||||
colorScheme: root.colorScheme
|
||||
text: user.username
|
||||
text: root.user ? user.username : ""
|
||||
type: {
|
||||
switch (root.type) {
|
||||
case AccountDelegate.SmallView: return Label.Body
|
||||
@ -143,7 +143,7 @@ Item {
|
||||
RowLayout {
|
||||
Label {
|
||||
colorScheme: root.colorScheme
|
||||
text: user.loggedIn ? root.usedSpace : qsTr("Signed out")
|
||||
text: root.user && root.user.loggedIn ? root.usedSpace : qsTr("Signed out")
|
||||
color: root.usedSpaceColor
|
||||
type: {
|
||||
switch (root.type) {
|
||||
@ -155,7 +155,7 @@ Item {
|
||||
|
||||
Label {
|
||||
colorScheme: root.colorScheme
|
||||
text: user.loggedIn ? " / " + root.totalSpace : ""
|
||||
text: root.user && root.user.loggedIn ? " / " + root.totalSpace : ""
|
||||
color: root.colorScheme.text_weak
|
||||
type: {
|
||||
switch (root.type) {
|
||||
@ -168,7 +168,7 @@ Item {
|
||||
|
||||
|
||||
Rectangle {
|
||||
visible: root.type == AccountDelegate.LargeView && user.loggedIn
|
||||
visible: root.user ? root.type == AccountDelegate.LargeView : false
|
||||
width: 140
|
||||
height: 4
|
||||
radius: 3
|
||||
@ -177,6 +177,7 @@ Item {
|
||||
Rectangle {
|
||||
radius: 3
|
||||
color: root.usedSpaceColor
|
||||
visible: root.user ? parent.visible && root.user.loggedIn : false
|
||||
anchors {
|
||||
top : parent.top
|
||||
bottom : parent.bottom
|
||||
|
||||
@ -21,246 +21,216 @@ import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
|
||||
ScrollView {
|
||||
Item {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
property var backend
|
||||
property var notifications
|
||||
property var user
|
||||
|
||||
clip: true
|
||||
contentWidth: pane.width
|
||||
contentHeight: pane.height
|
||||
|
||||
property int _leftRightMargins: 64
|
||||
property int _topBottomMargins: 68
|
||||
property int _spacing: 22
|
||||
|
||||
Rectangle {
|
||||
anchors {
|
||||
bottom: pane.bottom
|
||||
}
|
||||
color: root.colorScheme.background_weak
|
||||
width: root.width
|
||||
height: configuration.height + root._topBottomMargins
|
||||
}
|
||||
|
||||
signal showSignIn()
|
||||
signal showSetupGuide(var user, string address)
|
||||
|
||||
ColumnLayout {
|
||||
id: pane
|
||||
property int _leftMargin: 64
|
||||
property int _rightMargin: 64
|
||||
property int _topMargin: 32
|
||||
property int _detailsTopMargin: 25
|
||||
property int _bottomMargin: 12
|
||||
property int _spacing: 20
|
||||
property int _lineWidth: 1
|
||||
|
||||
width: root.width
|
||||
ScrollView {
|
||||
clip: true
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
spacing: root._spacing
|
||||
Layout.topMargin: root._topBottomMargins
|
||||
Layout.leftMargin: root._leftRightMargins
|
||||
Layout.rightMargin: root._leftRightMargins
|
||||
Layout.maximumWidth: root.width - 2*root._leftRightMargins
|
||||
width: root.width
|
||||
spacing: 0
|
||||
|
||||
Rectangle {
|
||||
id: topRectangle
|
||||
color: root.colorScheme.background_norm
|
||||
|
||||
implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
|
||||
implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin
|
||||
|
||||
RowLayout { // account delegate with action buttons
|
||||
Layout.fillWidth: true
|
||||
|
||||
AccountDelegate {
|
||||
Layout.fillWidth: true
|
||||
colorScheme: root.colorScheme
|
||||
user: root.user
|
||||
type: AccountDelegate.LargeView
|
||||
enabled: root.user.loggedIn
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: root._spacing
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Sign out")
|
||||
secondary: true
|
||||
visible: root.user.loggedIn
|
||||
onClicked: root.user.logout()
|
||||
}
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: root._leftMargin
|
||||
anchors.rightMargin: root._rightMargin
|
||||
anchors.topMargin: root._topMargin
|
||||
anchors.bottomMargin: root._bottomMargin
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Sign in")
|
||||
secondary: true
|
||||
visible: !root.user.loggedIn
|
||||
enabled: !root.user.loggedIn
|
||||
onClicked: root.parent.rightContent.showSignIn()
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
colorScheme: root.colorScheme
|
||||
icon.source: "icons/ic-trash.svg"
|
||||
secondary: true
|
||||
visible: true
|
||||
enabled: true
|
||||
onClicked: root.user.remove()
|
||||
RowLayout { // account delegate with action buttons
|
||||
Layout.fillWidth: true
|
||||
|
||||
AccountDelegate {
|
||||
Layout.fillWidth: true
|
||||
colorScheme: root.colorScheme
|
||||
user: root.user
|
||||
type: AccountDelegate.LargeView
|
||||
enabled: root.user ? root.user.loggedIn : false
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Sign out")
|
||||
secondary: true
|
||||
visible: root.user ? root.user.loggedIn : false
|
||||
onClicked: {
|
||||
if (!root.user) return
|
||||
root.user.logout()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Sign in")
|
||||
secondary: true
|
||||
visible: root.user ? !root.user.loggedIn : false
|
||||
onClicked: {
|
||||
if (!root.user) return
|
||||
root.parent.rightContent.showSignIn()
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
colorScheme: root.colorScheme
|
||||
icon.source: "icons/ic-trash.svg"
|
||||
secondary: true
|
||||
onClicked: {
|
||||
if (!root.user) return
|
||||
root.user.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: root._lineWidth
|
||||
color: root.colorScheme.border_weak
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Email clients")
|
||||
actionText: qsTr("Configure")
|
||||
description: qsTr("Proton Mail Bridge works with email clients that support IMAP/SMPT to send and receive messages. Using the mailbox details below, you can (re)configure your client at any point.")
|
||||
type: SettingsItem.Button
|
||||
enabled: root.user ? root.user.loggedIn : false
|
||||
visible: root.user ? !root.user.splitMode || root.user.addresses.length==1 : false
|
||||
showSeparator: splitMode.visible
|
||||
onClicked: {
|
||||
if (!root.user) return
|
||||
root.showSetupGuide(root.user, user.addresses[0])
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
id: splitMode
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Split addresses")
|
||||
description: qsTr("Split addresses allows you to configure multiple email addresses individually. Changing its mode will require you to delete your accounts(s) from your email client and begin the setup process from scratch.")
|
||||
type: SettingsItem.Toggle
|
||||
checked: root.user ? root.user.splitMode : false
|
||||
visible: root.user ? root.user.addresses.length > 1 : false
|
||||
enabled: root.user ? root.user.loggedIn : false
|
||||
showSeparator: addressSelector.visible
|
||||
onClicked: {
|
||||
if (!splitMode.checked){
|
||||
root.notifications.askEnableSplitMode(user)
|
||||
} else {
|
||||
root.user.toggleSplitMode(!splitMode.checked)
|
||||
}
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
enabled: root.user ? root.user.loggedIn : false
|
||||
visible: root.user ? root.user.splitMode : false
|
||||
|
||||
ComboBox {
|
||||
id: addressSelector
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
model: root.user ? root.user.addresses : null
|
||||
}
|
||||
|
||||
Button {
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Configure")
|
||||
secondary: true
|
||||
onClicked: {
|
||||
if (!root.user) return
|
||||
root.showSetupGuide(root.user, addressSelector.displayText)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: root.colorScheme.background_weak
|
||||
|
||||
implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
|
||||
implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin
|
||||
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
color: root.colorScheme.border_weak
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Email clients")
|
||||
actionText: qsTr("Configure")
|
||||
description: "MISSING WIREFRAME" // TODO
|
||||
type: SettingsItem.Button
|
||||
enabled: root.user.loggedIn
|
||||
visible: !root.user.splitMode
|
||||
onClicked: root.showSetupGuide(root.user,user.addresses[0])
|
||||
}
|
||||
ColumnLayout {
|
||||
id: configuration
|
||||
|
||||
SettingsItem {
|
||||
id: splitMode
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Split addresses")
|
||||
description: qsTr("Split addresses allows you to configure multiple email addresses individually. Changing its mode will require you to delete your accounts(s) from your email client and begin the setup process from scratch.")
|
||||
type: SettingsItem.Toggle
|
||||
checked: root.user.splitMode
|
||||
visible: root.user.addresses.length > 1
|
||||
enabled: root.user.loggedIn
|
||||
onClicked: {
|
||||
if (!splitMode.checked){
|
||||
root.notifications.askEnableSplitMode(user)
|
||||
} else {
|
||||
root.user.toggleSplitMode(!splitMode.checked)
|
||||
}
|
||||
}
|
||||
}
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: root._leftMargin
|
||||
anchors.rightMargin: root._rightMargin
|
||||
anchors.topMargin: root._detailsTopMargin
|
||||
anchors.bottomMargin: root._spacing
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
enabled: root.user.loggedIn
|
||||
spacing: root._spacing
|
||||
visible: root.user ? root.user.loggedIn : false
|
||||
|
||||
visible: root.user.splitMode
|
||||
|
||||
ComboBox {
|
||||
id: addressSelector
|
||||
Layout.fillWidth: true
|
||||
model: root.user.addresses
|
||||
|
||||
property var _topBottomMargins : 8
|
||||
property var _leftRightMargins : 16
|
||||
|
||||
background: RoundedRectangle {
|
||||
radiusTopLeft : 6
|
||||
radiusTopRight : 6
|
||||
radiusBottomLeft : addressSelector.down ? 0 : 6
|
||||
radiusBottomRight : addressSelector.down ? 0 : 6
|
||||
|
||||
height: addressSelector.contentItem.height
|
||||
//width: addressSelector.contentItem.width
|
||||
|
||||
fillColor : root.colorScheme.background_norm
|
||||
strokeColor : root.colorScheme.border_norm
|
||||
strokeWidth : 1
|
||||
}
|
||||
|
||||
delegate: Rectangle {
|
||||
id: listItem
|
||||
width: root.width
|
||||
height: children[0].height + 4 + 2*addressSelector._topBottomMargins
|
||||
|
||||
Label {
|
||||
anchors {
|
||||
top : parent.top
|
||||
left : parent.left
|
||||
topMargin : addressSelector._topBottomMargins + 4
|
||||
leftMargin : addressSelector._leftRightMargins
|
||||
}
|
||||
|
||||
colorScheme: root.colorScheme
|
||||
text: modelData
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
property bool isOver: false
|
||||
color: {
|
||||
if (listItem.isOver) return root.colorScheme.interaction_weak_hover
|
||||
if (addressSelector.highlightedIndex === index) return root.colorScheme.interaction_weak
|
||||
return root.colorScheme.background_norm
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: listItem.isOver = true
|
||||
onExited: listItem.isOver = false
|
||||
onClicked : {
|
||||
addressSelector.currentIndex = index
|
||||
addressSelector.popup.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: Label {
|
||||
topPadding : addressSelector._topBottomMargins+4
|
||||
bottomPadding : addressSelector._topBottomMargins
|
||||
leftPadding : addressSelector._leftRightMargins
|
||||
rightPadding : addressSelector._leftRightMargins
|
||||
property string currentAddress: addressSelector.displayText
|
||||
|
||||
Label {
|
||||
colorScheme: root.colorScheme
|
||||
text: addressSelector.displayText
|
||||
elide: Text.ElideMiddle
|
||||
text: qsTr("Mailbox details")
|
||||
type: Label.Body_semibold
|
||||
}
|
||||
|
||||
Configuration {
|
||||
colorScheme: root.colorScheme
|
||||
title: qsTr("IMAP")
|
||||
hostname: root.backend.hostname
|
||||
port: root.backend.portIMAP.toString()
|
||||
username: configuration.currentAddress
|
||||
password: root.user ? root.user.password : ""
|
||||
security: "STARTTLS"
|
||||
}
|
||||
|
||||
Configuration {
|
||||
colorScheme: root.colorScheme
|
||||
title: qsTr("SMTP")
|
||||
hostname : root.backend.hostname
|
||||
port : root.backend.portSMTP.toString()
|
||||
username : configuration.currentAddress
|
||||
password : root.user ? root.user.password : ""
|
||||
security : root.backend.useSSLforSMTP ? "SSL" : "STARTTLS"
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Configure")
|
||||
secondary: true
|
||||
onClicked: root.showSetupGuide(root.user, addressSelector.displayText)
|
||||
}
|
||||
}
|
||||
|
||||
Item {implicitHeight: 1}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: configuration
|
||||
Layout.bottomMargin: root._topBottomMargins
|
||||
Layout.leftMargin: root._leftRightMargins
|
||||
Layout.rightMargin: root._leftRightMargins
|
||||
Layout.maximumWidth: root.width - 2*root._leftRightMargins
|
||||
spacing: root._spacing
|
||||
visible: root.user.loggedIn
|
||||
|
||||
property string currentAddress: addressSelector.displayText
|
||||
|
||||
Item {height: 1}
|
||||
|
||||
Label {
|
||||
colorScheme: root.colorScheme
|
||||
text: qsTr("Mailbox details")
|
||||
type: Label.Body_semibold
|
||||
}
|
||||
|
||||
Configuration {
|
||||
colorScheme: root.colorScheme
|
||||
title: qsTr("IMAP")
|
||||
hostname: root.backend.hostname
|
||||
port: root.backend.portIMAP.toString()
|
||||
username: configuration.currentAddress
|
||||
password: root.user.password
|
||||
security: "STARTTLS"
|
||||
}
|
||||
|
||||
Configuration {
|
||||
colorScheme: root.colorScheme
|
||||
title: qsTr("SMTP")
|
||||
hostname : root.backend.hostname
|
||||
port : root.backend.portSMTP.toString()
|
||||
username : configuration.currentAddress
|
||||
password : root.user.password
|
||||
security : root.backend.useSSLforSMTP ? "SSL" : "STARTTLS"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,19 +42,6 @@ QtObject {
|
||||
backend: root.backend
|
||||
notifications: root._notifications
|
||||
|
||||
onLogin: {
|
||||
backend.login(username, password)
|
||||
}
|
||||
onLogin2FA: {
|
||||
backend.login2FA(username, code)
|
||||
}
|
||||
onLogin2Password: {
|
||||
backend.login2Password(username, password)
|
||||
}
|
||||
onLoginAbort: {
|
||||
backend.loginAbort(username)
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
backend.dockIconVisible = visible
|
||||
}
|
||||
@ -167,12 +154,10 @@ QtObject {
|
||||
break;
|
||||
case SystemTrayIcon.Context:
|
||||
case SystemTrayIcon.Trigger:
|
||||
calcStatusWindowPosition()
|
||||
toggleWindow(statusWindow)
|
||||
break
|
||||
case SystemTrayIcon.DoubleClick:
|
||||
case SystemTrayIcon.MiddleClick:
|
||||
toggleWindow(mainWindow)
|
||||
calcStatusWindowPosition()
|
||||
toggleWindow(statusWindow)
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -181,12 +166,30 @@ QtObject {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (root.backend.users.count === 0) {
|
||||
if (!root.backend) {
|
||||
console.log("backend not loaded")
|
||||
}
|
||||
|
||||
if (!root.backend.users) {
|
||||
console.log("users not loaded")
|
||||
}
|
||||
|
||||
var c = root.backend.users.count
|
||||
var u = root.backend.users.get(0)
|
||||
// DEBUG
|
||||
if (c != 0) {
|
||||
console.log("users non zero", c)
|
||||
console.log("first user", u )
|
||||
}
|
||||
|
||||
if (c === 0) {
|
||||
mainWindow.showAndRise()
|
||||
}
|
||||
|
||||
if (root.backend.users.count === 1 && root.backend.users.get(0).loggedIn === false) {
|
||||
mainWindow.showAndRise()
|
||||
if (u) {
|
||||
if (c === 1 && u.loggedIn === false) {
|
||||
mainWindow.showAndRise()
|
||||
}
|
||||
}
|
||||
|
||||
if (root.backend.showOnStartup) {
|
||||
|
||||
@ -116,10 +116,10 @@ ColumnLayout {
|
||||
Button {
|
||||
colorScheme: root.colorScheme
|
||||
text: "name/pass error"
|
||||
enabled: user !== undefined && user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordProvided
|
||||
enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordProvided
|
||||
|
||||
onClicked: {
|
||||
user.loginUsernamePasswordError()
|
||||
root.backend.loginUsernamePasswordError("")
|
||||
user.resetLoginRequests()
|
||||
}
|
||||
}
|
||||
@ -127,9 +127,9 @@ ColumnLayout {
|
||||
Button {
|
||||
colorScheme: root.colorScheme
|
||||
text: "free user error"
|
||||
enabled: user !== undefined && user.isLoginRequested
|
||||
enabled: user !== undefined //&& user.isLoginRequested
|
||||
onClicked: {
|
||||
user.loginFreeUserError()
|
||||
root.backend.loginFreeUserError("")
|
||||
user.resetLoginRequests()
|
||||
}
|
||||
}
|
||||
@ -137,9 +137,9 @@ ColumnLayout {
|
||||
Button {
|
||||
colorScheme: root.colorScheme
|
||||
text: "connection error"
|
||||
enabled: user !== undefined && user.isLoginRequested
|
||||
enabled: user !== undefined //&& user.isLoginRequested
|
||||
onClicked: {
|
||||
user.loginConnectionError()
|
||||
root.backend.loginConnectionError("")
|
||||
user.resetLoginRequests()
|
||||
}
|
||||
}
|
||||
@ -160,9 +160,9 @@ ColumnLayout {
|
||||
colorScheme: root.colorScheme
|
||||
text: "request"
|
||||
|
||||
enabled: user !== undefined && user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordRequested
|
||||
enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordRequested
|
||||
onClicked: {
|
||||
user.login2FARequested()
|
||||
root.backend.login2FARequested()
|
||||
user.isLogin2FARequested = true
|
||||
}
|
||||
}
|
||||
@ -171,9 +171,9 @@ ColumnLayout {
|
||||
colorScheme: root.colorScheme
|
||||
text: "error"
|
||||
|
||||
enabled: user !== undefined && user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided)
|
||||
enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided)
|
||||
onClicked: {
|
||||
user.login2FAError()
|
||||
root.backend.login2FAError("")
|
||||
user.isLogin2FAProvided = false
|
||||
}
|
||||
}
|
||||
@ -182,9 +182,9 @@ ColumnLayout {
|
||||
colorScheme: root.colorScheme
|
||||
text: "Abort"
|
||||
|
||||
enabled: user !== undefined && user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided)
|
||||
enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided)
|
||||
onClicked: {
|
||||
user.login2FAErrorAbort()
|
||||
root.backend.login2FAErrorAbort("")
|
||||
user.resetLoginRequests()
|
||||
}
|
||||
}
|
||||
@ -205,9 +205,9 @@ ColumnLayout {
|
||||
colorScheme: root.colorScheme
|
||||
text: "request"
|
||||
|
||||
enabled: user !== undefined && user.isLoginRequested && !user.isLogin2PasswordRequested && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
|
||||
enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2PasswordRequested && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
|
||||
onClicked: {
|
||||
user.login2PasswordRequested()
|
||||
root.backend.login2PasswordRequested("")
|
||||
user.isLogin2PasswordRequested = true
|
||||
}
|
||||
}
|
||||
@ -216,9 +216,9 @@ ColumnLayout {
|
||||
colorScheme: root.colorScheme
|
||||
text: "error"
|
||||
|
||||
enabled: user !== undefined && user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
|
||||
enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
|
||||
onClicked: {
|
||||
user.login2PasswordError()
|
||||
root.backend.login2PasswordError("")
|
||||
|
||||
user.isLogin2PasswordProvided = false
|
||||
}
|
||||
@ -228,9 +228,9 @@ ColumnLayout {
|
||||
colorScheme: root.colorScheme
|
||||
text: "Abort"
|
||||
|
||||
enabled: user !== undefined && user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
|
||||
enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
|
||||
onClicked: {
|
||||
user.login2PasswordErrorAbort()
|
||||
root.backend.login2PasswordErrorAbort("")
|
||||
user.resetLoginRequests()
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import QtQuick.Controls.impl 2.12
|
||||
|
||||
import Proton 4.0
|
||||
|
||||
ColumnLayout {
|
||||
Item {
|
||||
id: root
|
||||
Layout.fillWidth: true
|
||||
|
||||
@ -30,54 +30,60 @@ ColumnLayout {
|
||||
property string label
|
||||
property string value
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: children[0].implicitHeight
|
||||
implicitWidth: children[0].implicitWidth
|
||||
|
||||
ColumnLayout {
|
||||
Label {
|
||||
colorScheme: root.colorScheme
|
||||
text: root.label
|
||||
type: Label.Body
|
||||
}
|
||||
TextEdit {
|
||||
id: valueText
|
||||
text: root.value
|
||||
color: root.colorScheme.text_weak
|
||||
readOnly: true
|
||||
selectByMouse: true
|
||||
selectByKeyboard: true
|
||||
selectionColor: root.colorScheme.text_weak
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
width: root.width
|
||||
|
||||
Item {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ColorImage {
|
||||
source: "icons/ic-copy.svg"
|
||||
color: root.colorScheme.text_norm
|
||||
height: root.colorScheme.body_font_size
|
||||
sourceSize.height: root.colorScheme.body_font_size
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked : {
|
||||
valueText.select(0, valueText.length)
|
||||
valueText.copy()
|
||||
valueText.deselect()
|
||||
ColumnLayout {
|
||||
Label {
|
||||
colorScheme: root.colorScheme
|
||||
text: root.label
|
||||
type: Label.Body
|
||||
}
|
||||
TextEdit {
|
||||
id: valueText
|
||||
text: root.value
|
||||
color: root.colorScheme.text_weak
|
||||
readOnly: true
|
||||
selectByMouse: true
|
||||
selectByKeyboard: true
|
||||
selectionColor: root.colorScheme.text_weak
|
||||
}
|
||||
onPressed: parent.scale = 0.90
|
||||
onReleased: parent.scale = 1
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
ColorImage {
|
||||
source: "icons/ic-copy.svg"
|
||||
color: root.colorScheme.text_norm
|
||||
height: root.colorScheme.body_font_size
|
||||
sourceSize.height: root.colorScheme.body_font_size
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked : {
|
||||
valueText.select(0, valueText.length)
|
||||
valueText.copy()
|
||||
valueText.deselect()
|
||||
}
|
||||
onPressed: parent.scale = 0.90
|
||||
onReleased: parent.scale = 1
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
color: root.colorScheme.border_norm
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
color: root.colorScheme.border_norm
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,24 +28,8 @@ Item {
|
||||
property var backend
|
||||
property var notifications
|
||||
|
||||
signal login(string username, string password)
|
||||
signal login2FA(string username, string code)
|
||||
signal login2Password(string username, string password)
|
||||
signal loginAbort(string username)
|
||||
|
||||
signal showSetupGuide(var user, string address)
|
||||
|
||||
property var noUser: QtObject {
|
||||
property var avatarText: ""
|
||||
property var username: ""
|
||||
property var password: ""
|
||||
property var usedBytes: 1
|
||||
property var totalBytes: 1
|
||||
property var loggedIn: false
|
||||
property var splitMode: false
|
||||
property var addresses: []
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
@ -183,6 +167,7 @@ Item {
|
||||
onClicked: {
|
||||
var user = root.backend.users.get(index)
|
||||
accounts.currentIndex = index
|
||||
if (!user) return
|
||||
if (user.loggedIn) {
|
||||
rightContent.showAccount()
|
||||
} else {
|
||||
@ -248,8 +233,8 @@ Item {
|
||||
backend: root.backend
|
||||
notifications: root.notifications
|
||||
user: {
|
||||
if (accounts.currentIndex < 0) return root.noUser
|
||||
if (root.backend.users.count == 0) return root.noUser
|
||||
if (accounts.currentIndex < 0) return undefined
|
||||
if (root.backend.users.count == 0) return undefined
|
||||
return root.backend.users.get(accounts.currentIndex)
|
||||
}
|
||||
onShowSignIn: {
|
||||
@ -261,7 +246,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
GridLayout { // 1
|
||||
GridLayout { // 1 Sign In
|
||||
columns: 2
|
||||
|
||||
Button {
|
||||
@ -271,7 +256,10 @@ Item {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
colorScheme: root.colorScheme
|
||||
onClicked: rightContent.showAccount()
|
||||
onClicked: {
|
||||
signIn.abort()
|
||||
rightContent.showAccount()
|
||||
}
|
||||
icon.source: "icons/ic-arrow-left.svg"
|
||||
secondary: true
|
||||
horizontalPadding: 8
|
||||
@ -289,11 +277,6 @@ Item {
|
||||
|
||||
colorScheme: root.colorScheme
|
||||
backend: root.backend
|
||||
|
||||
onLogin : { root.backend.login ( username , password ) }
|
||||
onLogin2FA : { root.backend.login2FA ( username , code ) }
|
||||
onLogin2Password : { root.backend.login2Password ( username , password ) }
|
||||
onLoginAbort : { root.backend.loginAbort ( username ) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,7 +313,9 @@ Item {
|
||||
selectedAddress: {
|
||||
if (accounts.currentIndex < 0) return ""
|
||||
if (root.backend.users.count == 0) return ""
|
||||
return root.backend.users.get(accounts.currentIndex).addresses[0]
|
||||
var user = root.backend.users.get(accounts.currentIndex)
|
||||
if (!user) return ""
|
||||
return user.addresses[0]
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,6 +327,12 @@ Item {
|
||||
function showLocalCacheSettings () { rightContent.currentIndex = 5 }
|
||||
function showHelpView () { rightContent.currentIndex = 6 }
|
||||
function showBugReport () { rightContent.currentIndex = 7 }
|
||||
|
||||
Connections {
|
||||
target: root.backend
|
||||
|
||||
onLoginFinished: rightContent.showAccount()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -353,5 +344,4 @@ Item {
|
||||
signIn.username = username
|
||||
rightContent.showSignIn()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -43,6 +43,8 @@ SettingsView {
|
||||
type: SettingsItem.Toggle
|
||||
checked: root.backend.isAutomaticUpdateOn
|
||||
onClicked: root.backend.toggleAutomaticUpdate(!autoUpdate.checked)
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -62,6 +64,8 @@ SettingsView {
|
||||
autostart.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -78,6 +82,8 @@ SettingsView {
|
||||
root.notifications.askDisableBeta()
|
||||
}
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@ -117,6 +123,8 @@ SettingsView {
|
||||
type: SettingsItem.Toggle
|
||||
checked: root.backend.isDoHEnabled
|
||||
onClicked: root.backend.toggleDoH(!doh.checked)
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -128,6 +136,8 @@ SettingsView {
|
||||
description: qsTr("Choose which ports are used by default.")
|
||||
type: SettingsItem.Button
|
||||
onClicked: root.parent.showPortSettings()
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -139,6 +149,8 @@ SettingsView {
|
||||
description: qsTr("Change the protocol Bridge and your client use to connect.")
|
||||
type: SettingsItem.Button
|
||||
onClicked: root.parent.showSMTPSettings()
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -150,6 +162,8 @@ SettingsView {
|
||||
description: qsTr("Configure Bridge's local cache settings.")
|
||||
type: SettingsItem.Button
|
||||
onClicked: root.parent.showLocalCacheSettings()
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -163,6 +177,8 @@ SettingsView {
|
||||
onClicked: {
|
||||
root.notifications.askResetBridge()
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
onBack: root.parent.showAccount()
|
||||
|
||||
@ -39,7 +39,9 @@ SettingsView {
|
||||
actionIcon: "./icons/ic-external-link.svg"
|
||||
description: qsTr("Get help setting up your client with our instructions and FAQs.")
|
||||
type: SettingsItem.PrimaryButton
|
||||
onClicked: {Qt.openUrlExternally("https://protonmail.com/bridge/install")}
|
||||
onClicked: {Qt.openUrlExternally("https://protonmail.com/support/categories/bridge/")}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -55,6 +57,8 @@ SettingsView {
|
||||
}
|
||||
|
||||
Connections {target: root.backend; onCheckUpdatesFinished: checkUpdates.loading = false}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -64,7 +68,9 @@ SettingsView {
|
||||
actionText: qsTr("View logs")
|
||||
description: qsTr("Open and review logs to troubleshoot.")
|
||||
type: SettingsItem.Button
|
||||
onClicked: {Qt.openUrlExternally(root.backend.logsPath)}
|
||||
onClicked: {Qt.openUrlExternally("file://"+root.backend.logsPath)}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -78,6 +84,8 @@ SettingsView {
|
||||
root.backend.updateCurrentMailClient()
|
||||
root.parent.showBugReport()
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Label {
|
||||
@ -91,7 +99,7 @@ SettingsView {
|
||||
text: {
|
||||
var version = root.backend.version
|
||||
var license = qsTr("License")
|
||||
var licensePath = root.backend.licensePath
|
||||
var licensePath = "file://"+root.backend.licensePath
|
||||
var release= qsTr("Release notes")
|
||||
var releaseNotesLink = root.backend.releaseNotesLink
|
||||
return `<p style="text-align:center;">Proton Mail Bridge v${version}<br>
|
||||
|
||||
@ -54,6 +54,8 @@ SettingsView {
|
||||
type: SettingsItem.Toggle
|
||||
checked: root._diskCacheEnabled
|
||||
onClicked: root._diskCacheEnabled = !root._diskCacheEnabled
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
SettingsItem {
|
||||
@ -67,6 +69,8 @@ SettingsView {
|
||||
pathDialog.open()
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
FileDialog {
|
||||
id: pathDialog
|
||||
title: qsTr("Select cache location")
|
||||
|
||||
@ -41,11 +41,6 @@ ApplicationWindow {
|
||||
property var backend
|
||||
property var notifications
|
||||
|
||||
signal login(string username, string password)
|
||||
signal login2FA(string username, string code)
|
||||
signal login2Password(string username, string password)
|
||||
signal loginAbort(string username)
|
||||
|
||||
// show Setup Guide on every new user
|
||||
Connections {
|
||||
target: root.backend.users
|
||||
@ -98,7 +93,15 @@ ApplicationWindow {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (backend.users.count === 1 && backend.users.get(0).loggedIn === false) {
|
||||
var u = backend.users.get(0)
|
||||
|
||||
if (!u) {
|
||||
console.trace()
|
||||
console.log("empty user")
|
||||
return 1
|
||||
}
|
||||
|
||||
if (backend.users.count === 1 && u.loggedIn === false) {
|
||||
return 1
|
||||
}
|
||||
|
||||
@ -121,19 +124,6 @@ ApplicationWindow {
|
||||
onShowSetupGuide: {
|
||||
root.showSetup(user,address)
|
||||
}
|
||||
|
||||
onLogin: {
|
||||
root.login(username, password)
|
||||
}
|
||||
onLogin2FA: {
|
||||
root.login2FA(username, code)
|
||||
}
|
||||
onLogin2Password: {
|
||||
root.login2Password(username, password)
|
||||
}
|
||||
onLoginAbort: {
|
||||
root.loginAbort(username)
|
||||
}
|
||||
}
|
||||
|
||||
WelcomeGuide {
|
||||
@ -142,19 +132,6 @@ ApplicationWindow {
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
onLogin: {
|
||||
root.login(username, password)
|
||||
}
|
||||
onLogin2FA: {
|
||||
root.login2FA(username, code)
|
||||
}
|
||||
onLogin2Password: {
|
||||
root.login2Password(username, password)
|
||||
}
|
||||
onLoginAbort: {
|
||||
root.loginAbort(username)
|
||||
}
|
||||
}
|
||||
|
||||
SetupGuide {
|
||||
|
||||
@ -56,6 +56,8 @@ QtObject {
|
||||
root.updateSilentRestartNeeded,
|
||||
root.updateSilentError,
|
||||
root.updateIsLatestVersion,
|
||||
root.loginConnectionError,
|
||||
root.onlyPaidUsers,
|
||||
root.disableBeta,
|
||||
root.enableBeta,
|
||||
root.bugReportSendSuccess,
|
||||
@ -119,7 +121,7 @@ QtObject {
|
||||
text: qsTr("Update manually")
|
||||
|
||||
onTriggered: {
|
||||
Qt.openUrlExternally(root.backend.getLandingPage())
|
||||
Qt.openUrlExternally(root.backend.landingPageLink)
|
||||
root.updateManualReady.active = false
|
||||
}
|
||||
},
|
||||
@ -174,7 +176,7 @@ QtObject {
|
||||
text: qsTr("Update manually")
|
||||
|
||||
onTriggered: {
|
||||
Qt.openUrlExternally(root.backend.getLandingPage())
|
||||
Qt.openUrlExternally(root.backend.landingPageLink)
|
||||
root.updateManualError.active = false
|
||||
}
|
||||
},
|
||||
@ -217,7 +219,7 @@ QtObject {
|
||||
text: qsTr("Update manually")
|
||||
|
||||
onTriggered: {
|
||||
Qt.openUrlExternally(root.backend.getLandingPage())
|
||||
Qt.openUrlExternally(root.backend.landingPageLink)
|
||||
root.updateForce.active = false
|
||||
}
|
||||
},
|
||||
@ -252,7 +254,7 @@ QtObject {
|
||||
text: qsTr("Update manually")
|
||||
|
||||
onTriggered: {
|
||||
Qt.openUrlExternally(root.backend.getLandingPage())
|
||||
Qt.openUrlExternally(root.backend.landingPageLink)
|
||||
root.updateForceError.active = false
|
||||
}
|
||||
},
|
||||
@ -307,7 +309,7 @@ QtObject {
|
||||
text: qsTr("Update manually")
|
||||
|
||||
onTriggered: {
|
||||
Qt.openUrlExternally(root.backend.getLandingPage())
|
||||
Qt.openUrlExternally(root.backend.landingPageLink)
|
||||
root.updateSilentError.active = false
|
||||
}
|
||||
}
|
||||
@ -399,6 +401,52 @@ QtObject {
|
||||
]
|
||||
}
|
||||
|
||||
// login
|
||||
property Notification loginConnectionError: Notification {
|
||||
text: qsTr("Bridge is not able to contact the server, please check your internet connection.")
|
||||
icon: "./icons/ic-exclamation-circle-filled.svg"
|
||||
type: Notification.NotificationType.Danger
|
||||
group: Notifications.Group.Configuration
|
||||
|
||||
Connections {
|
||||
target: root.backend
|
||||
onLoginConnectionError: {
|
||||
root.loginConnectionError.active = true
|
||||
}
|
||||
}
|
||||
|
||||
action: [
|
||||
Action {
|
||||
text: qsTr("OK")
|
||||
onTriggered: {
|
||||
root.loginConnectionError.active = false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
property Notification onlyPaidUsers: Notification {
|
||||
text: qsTr("Bridge is exclusive to our paid plans. Upgrade your account to use Bridge.")
|
||||
icon: "./icons/ic-exclamation-circle-filled.svg"
|
||||
type: Notification.NotificationType.Danger
|
||||
group: Notifications.Group.Configuration
|
||||
|
||||
Connections {
|
||||
target: root.backend
|
||||
onLoginFreeUserError: {
|
||||
root.onlyPaidUsers.active = true
|
||||
}
|
||||
}
|
||||
|
||||
action: [
|
||||
Action {
|
||||
text: qsTr("OK")
|
||||
onTriggered: {
|
||||
root.onlyPaidUsers.active = false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// Bug reports
|
||||
property Notification bugReportSendSuccess: Notification {
|
||||
@ -420,9 +468,6 @@ QtObject {
|
||||
onTriggered: {
|
||||
root.bugReportSendSuccess.active = false
|
||||
}
|
||||
},
|
||||
Action {
|
||||
text: "test"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -22,8 +22,6 @@ import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls.impl 2.12
|
||||
import QtQuick.Templates 2.12 as T
|
||||
|
||||
import "."
|
||||
|
||||
T.ApplicationWindow {
|
||||
id: root
|
||||
|
||||
|
||||
@ -19,7 +19,8 @@ import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls.impl 2.12
|
||||
import QtQuick.Templates 2.12 as T
|
||||
import "."
|
||||
|
||||
import "." as Proton
|
||||
|
||||
T.Button {
|
||||
property ColorScheme colorScheme
|
||||
@ -32,7 +33,7 @@ T.Button {
|
||||
|
||||
property bool borderless: false
|
||||
|
||||
property int labelType: Label.LabelType.Body
|
||||
property int labelType: Proton.Label.LabelType.Body
|
||||
|
||||
// TODO: store previous enabled state and restore it?
|
||||
// For now assuming that only enabled buttons could have loading state
|
||||
@ -104,7 +105,7 @@ T.Button {
|
||||
return control.display === AbstractButton.TextUnderIcon ? textImplicitHeight + iconImplicitHeight + spacing : Math.max(textImplicitHeight, iconImplicitHeight)
|
||||
}
|
||||
|
||||
Label {
|
||||
Proton.Label {
|
||||
colorScheme: root.colorScheme
|
||||
id: label
|
||||
anchors.left: labelIcon.left
|
||||
|
||||
184
internal/frontend/qml/Proton/ComboBox.qml
Normal file
184
internal/frontend/qml/Proton/ComboBox.qml
Normal file
@ -0,0 +1,184 @@
|
||||
// Copyright (c) 2021 Proton Technologies AG
|
||||
//
|
||||
// This file is part of ProtonMail Bridge.
|
||||
//
|
||||
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls.impl 2.12
|
||||
import QtQuick.Templates 2.12 as T
|
||||
|
||||
T.ComboBox {
|
||||
id: root
|
||||
|
||||
property ColorScheme colorScheme
|
||||
|
||||
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
|
||||
implicitContentWidth + leftPadding + rightPadding)
|
||||
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
|
||||
implicitContentHeight + topPadding + bottomPadding,
|
||||
implicitIndicatorHeight + topPadding + bottomPadding)
|
||||
|
||||
leftPadding: 12 + (!root.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
|
||||
rightPadding: 12 + (root.mirrored || !indicator || !indicator.visible ? 0 : indicator.width + spacing)
|
||||
|
||||
topPadding: 5
|
||||
bottomPadding: 5
|
||||
|
||||
spacing: 8
|
||||
|
||||
font.family: Style.font_family
|
||||
font.weight: Style.fontWeight_400
|
||||
font.pixelSize: Style.body_font_size
|
||||
font.letterSpacing: Style.body_letter_spacing
|
||||
|
||||
contentItem: T.TextField {
|
||||
padding: 5
|
||||
|
||||
text: root.editable ? root.editText : root.displayText
|
||||
font: root.font
|
||||
|
||||
enabled: root.editable
|
||||
autoScroll: root.editable
|
||||
readOnly: root.down
|
||||
inputMethodHints: root.inputMethodHints
|
||||
validator: root.validator
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
|
||||
color: root.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
|
||||
selectionColor: root.colorScheme.interaction_norm
|
||||
selectedTextColor: root.colorScheme.text_invert
|
||||
placeholderTextColor: root.enabled ? root.colorScheme.text_hint : root.colorScheme.text_disabled
|
||||
|
||||
background: Rectangle {
|
||||
radius: 4
|
||||
visible: root.enabled && root.editable && !root.flat
|
||||
border.color: {
|
||||
if (root.activeFocus) {
|
||||
return root.colorScheme.interaction_norm
|
||||
}
|
||||
|
||||
if (root.hovered) {
|
||||
return root.colorScheme.field_hover
|
||||
}
|
||||
|
||||
return root.colorScheme.field_norm
|
||||
}
|
||||
border.width: 1
|
||||
color: root.colorScheme.background_norm
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: 140
|
||||
implicitHeight: 36
|
||||
radius: 4
|
||||
color: {
|
||||
if (root.down) {
|
||||
return root.colorScheme.interaction_default_active
|
||||
}
|
||||
|
||||
if (root.enabled && root.hovered) {
|
||||
return root.colorScheme.interaction_default_hover
|
||||
}
|
||||
|
||||
if (!root.enabled) {
|
||||
return root.colorScheme.interaction_default
|
||||
}
|
||||
|
||||
return root.colorScheme.background_norm
|
||||
}
|
||||
|
||||
border.color: root.colorScheme.border_norm
|
||||
border.width: 1
|
||||
}
|
||||
|
||||
indicator: ColorImage {
|
||||
x: root.mirrored ? 12 : root.width - width - 12
|
||||
y: root.topPadding + (root.availableHeight - height) / 2
|
||||
color: root.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
|
||||
source: popup.visible ? "../icons/ic-chevron-up.svg" : "../icons/ic-chevron-down.svg"
|
||||
|
||||
sourceSize.width: 16
|
||||
sourceSize.height: 16
|
||||
}
|
||||
|
||||
|
||||
delegate: ItemDelegate {
|
||||
width: parent.width
|
||||
text: root.textRole ? (Array.isArray(root.model) ? modelData[root.textRole] : model[root.textRole]) : modelData
|
||||
|
||||
palette.text: root.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
|
||||
font: root.font
|
||||
|
||||
hoverEnabled: root.hoverEnabled
|
||||
|
||||
// we use highlighted to indicate currently selected delegate
|
||||
highlighted: root.currentIndex === index
|
||||
palette.highlightedText: root.enabled ? root.colorScheme.text_invert : root.colorScheme.text_disabled
|
||||
|
||||
background: PaddedRectangle {
|
||||
radius: 4
|
||||
color: {
|
||||
if (parent.down) {
|
||||
return root.colorScheme.interaction_default_active
|
||||
}
|
||||
|
||||
if (parent.highlighted) {
|
||||
return root.colorScheme.interaction_norm
|
||||
}
|
||||
|
||||
if (parent.hovered) {
|
||||
return root.colorScheme.interaction_default_hover
|
||||
}
|
||||
|
||||
return root.colorScheme.interaction_default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
popup: T.Popup {
|
||||
y: root.height
|
||||
width: root.width
|
||||
height: Math.min(contentItem.implicitHeight, root.Window.height - topMargin - bottomMargin)
|
||||
topMargin: 8
|
||||
bottomMargin: 8
|
||||
|
||||
contentItem: Item {
|
||||
implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
|
||||
implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 8
|
||||
|
||||
implicitHeight: contentHeight
|
||||
model: root.delegateModel
|
||||
currentIndex: root.highlightedIndex
|
||||
spacing: 4
|
||||
|
||||
T.ScrollIndicator.vertical: ScrollIndicator { }
|
||||
}
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: root.colorScheme.background_norm
|
||||
radius: 10
|
||||
border.color: root.colorScheme.border_weak
|
||||
border.width: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -21,8 +21,6 @@ import QtQuick.Templates 2.12 as T
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls.impl 2.12
|
||||
|
||||
import "."
|
||||
|
||||
T.Dialog {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
|
||||
@ -19,7 +19,8 @@ import QtQuick 2.13
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls.impl 2.12
|
||||
import QtQuick.Templates 2.12 as T
|
||||
import "."
|
||||
|
||||
import "." as Proton
|
||||
|
||||
T.Label {
|
||||
id: root
|
||||
@ -46,7 +47,7 @@ T.Label {
|
||||
// weight 700, size 12, height 16, spacing 0.4
|
||||
Caption_bold
|
||||
}
|
||||
property int type: Label.LabelType.Body
|
||||
property int type: Proton.Label.LabelType.Body
|
||||
|
||||
color: root.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
|
||||
palette.link: root.colorScheme.interaction_norm
|
||||
@ -56,78 +57,78 @@ T.Label {
|
||||
|
||||
font.weight: {
|
||||
switch (root.type) {
|
||||
case Label.LabelType.Heading:
|
||||
case Proton.Label.LabelType.Heading:
|
||||
return Style.fontWeight_700
|
||||
case Label.LabelType.Title:
|
||||
case Proton.Label.LabelType.Title:
|
||||
return Style.fontWeight_700
|
||||
case Label.LabelType.Lead:
|
||||
case Proton.Label.LabelType.Lead:
|
||||
return Style.fontWeight_400
|
||||
case Label.LabelType.Body:
|
||||
case Proton.Label.LabelType.Body:
|
||||
return Style.fontWeight_400
|
||||
case Label.LabelType.Body_semibold:
|
||||
case Proton.Label.LabelType.Body_semibold:
|
||||
return Style.fontWeight_600
|
||||
case Label.LabelType.Body_bold:
|
||||
case Proton.Label.LabelType.Body_bold:
|
||||
return Style.fontWeight_700
|
||||
case Label.LabelType.Caption:
|
||||
case Proton.Label.LabelType.Caption:
|
||||
return Style.fontWeight_400
|
||||
case Label.LabelType.Caption_semibold:
|
||||
case Proton.Label.LabelType.Caption_semibold:
|
||||
return Style.fontWeight_600
|
||||
case Label.LabelType.Caption_bold:
|
||||
case Proton.Label.LabelType.Caption_bold:
|
||||
return Style.fontWeight_700
|
||||
}
|
||||
}
|
||||
|
||||
font.pixelSize: {
|
||||
switch (root.type) {
|
||||
case Label.LabelType.Heading:
|
||||
case Proton.Label.LabelType.Heading:
|
||||
return Style.heading_font_size
|
||||
case Label.LabelType.Title:
|
||||
case Proton.Label.LabelType.Title:
|
||||
return Style.title_font_size
|
||||
case Label.LabelType.Lead:
|
||||
case Proton.Label.LabelType.Lead:
|
||||
return Style.lead_font_size
|
||||
case Label.LabelType.Body:
|
||||
case Label.LabelType.Body_semibold:
|
||||
case Label.LabelType.Body_bold:
|
||||
case Proton.Label.LabelType.Body:
|
||||
case Proton.Label.LabelType.Body_semibold:
|
||||
case Proton.Label.LabelType.Body_bold:
|
||||
return Style.body_font_size
|
||||
case Label.LabelType.Caption:
|
||||
case Label.LabelType.Caption_semibold:
|
||||
case Label.LabelType.Caption_bold:
|
||||
case Proton.Label.LabelType.Caption:
|
||||
case Proton.Label.LabelType.Caption_semibold:
|
||||
case Proton.Label.LabelType.Caption_bold:
|
||||
return Style.caption_font_size
|
||||
}
|
||||
}
|
||||
|
||||
lineHeight: {
|
||||
switch (root.type) {
|
||||
case Label.LabelType.Heading:
|
||||
case Proton.Label.LabelType.Heading:
|
||||
return Style.heading_line_height
|
||||
case Label.LabelType.Title:
|
||||
case Proton.Label.LabelType.Title:
|
||||
return Style.title_line_height
|
||||
case Label.LabelType.Lead:
|
||||
case Proton.Label.LabelType.Lead:
|
||||
return Style.lead_line_height
|
||||
case Label.LabelType.Body:
|
||||
case Label.LabelType.Body_semibold:
|
||||
case Label.LabelType.Body_bold:
|
||||
case Proton.Label.LabelType.Body:
|
||||
case Proton.Label.LabelType.Body_semibold:
|
||||
case Proton.Label.LabelType.Body_bold:
|
||||
return Style.body_line_height
|
||||
case Label.LabelType.Caption:
|
||||
case Label.LabelType.Caption_semibold:
|
||||
case Label.LabelType.Caption_bold:
|
||||
case Proton.Label.LabelType.Caption:
|
||||
case Proton.Label.LabelType.Caption_semibold:
|
||||
case Proton.Label.LabelType.Caption_bold:
|
||||
return Style.caption_line_height
|
||||
}
|
||||
}
|
||||
|
||||
font.letterSpacing: {
|
||||
switch (root.type) {
|
||||
case Label.LabelType.Heading:
|
||||
case Label.LabelType.Title:
|
||||
case Label.LabelType.Lead:
|
||||
case Proton.Label.LabelType.Heading:
|
||||
case Proton.Label.LabelType.Title:
|
||||
case Proton.Label.LabelType.Lead:
|
||||
return 0
|
||||
case Label.LabelType.Body:
|
||||
case Label.LabelType.Body_semibold:
|
||||
case Label.LabelType.Body_bold:
|
||||
case Proton.Label.LabelType.Body:
|
||||
case Proton.Label.LabelType.Body_semibold:
|
||||
case Proton.Label.LabelType.Body_bold:
|
||||
return Style.body_letter_spacing
|
||||
case Label.LabelType.Caption:
|
||||
case Label.LabelType.Caption_semibold:
|
||||
case Label.LabelType.Caption_bold:
|
||||
case Proton.Label.LabelType.Caption:
|
||||
case Proton.Label.LabelType.Caption_semibold:
|
||||
case Proton.Label.LabelType.Caption_bold:
|
||||
return Style.caption_letter_spacing
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,8 @@ import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls.impl 2.12
|
||||
import QtQuick.Templates 2.12 as T
|
||||
import "."
|
||||
|
||||
import "." as Proton
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@ -131,7 +132,7 @@ Item {
|
||||
border.width: 1
|
||||
}
|
||||
|
||||
Label {
|
||||
Proton.Label {
|
||||
colorScheme: root.colorScheme
|
||||
id: label
|
||||
|
||||
@ -141,10 +142,10 @@ Item {
|
||||
|
||||
color: root.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
|
||||
|
||||
type: Label.LabelType.Body_semibold
|
||||
type: Proton.Label.LabelType.Body_semibold
|
||||
}
|
||||
|
||||
Label {
|
||||
Proton.Label {
|
||||
colorScheme: root.colorScheme
|
||||
id: hint
|
||||
|
||||
@ -154,7 +155,7 @@ Item {
|
||||
|
||||
color: root.enabled ? root.colorScheme.text_weak : root.colorScheme.text_disabled
|
||||
|
||||
type: Label.LabelType.Caption
|
||||
type: Proton.Label.LabelType.Caption
|
||||
}
|
||||
|
||||
ColorImage {
|
||||
@ -168,7 +169,7 @@ Item {
|
||||
color: root.colorScheme.signal_danger
|
||||
}
|
||||
|
||||
Label {
|
||||
Proton.Label {
|
||||
colorScheme: root.colorScheme
|
||||
id: assistiveText
|
||||
|
||||
@ -189,7 +190,7 @@ Item {
|
||||
return root.colorScheme.text_weak
|
||||
}
|
||||
|
||||
type: root.error ? Label.LabelType.Caption_semibold : Label.LabelType.Caption
|
||||
type: root.error ? Proton.Label.LabelType.Caption_semibold : Proton.Label.LabelType.Caption
|
||||
}
|
||||
|
||||
ScrollView {
|
||||
|
||||
@ -21,7 +21,8 @@ import QtQuick.Controls 2.12
|
||||
import QtQuick.Controls.impl 2.12
|
||||
import QtQuick.Templates 2.12 as T
|
||||
import QtQuick.Layouts 1.12
|
||||
import "."
|
||||
|
||||
import "." as Proton
|
||||
|
||||
Item {
|
||||
id: root
|
||||
@ -128,22 +129,22 @@ Item {
|
||||
Layout.fillWidth: true
|
||||
spacing: 0
|
||||
|
||||
Label {
|
||||
Proton.Label {
|
||||
colorScheme: root.colorScheme
|
||||
id: label
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
type: Label.LabelType.Body_semibold
|
||||
type: Proton.Label.LabelType.Body_semibold
|
||||
}
|
||||
|
||||
Label {
|
||||
Proton.Label {
|
||||
colorScheme: root.colorScheme
|
||||
id: hint
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
color: root.enabled ? root.colorScheme.text_weak : root.colorScheme.text_disabled
|
||||
horizontalAlignment: Text.AlignRight
|
||||
type: Label.LabelType.Caption
|
||||
type: Proton.Label.LabelType.Caption
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,7 +271,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Proton.Button {
|
||||
colorScheme: root.colorScheme
|
||||
id: eyeButton
|
||||
|
||||
@ -299,7 +300,7 @@ Item {
|
||||
sourceSize.height: assistiveText.height
|
||||
}
|
||||
|
||||
Label {
|
||||
Proton.Label {
|
||||
colorScheme: root.colorScheme
|
||||
id: assistiveText
|
||||
|
||||
@ -319,7 +320,7 @@ Item {
|
||||
return root.colorScheme.text_weak
|
||||
}
|
||||
|
||||
type: root.error ? Label.LabelType.Caption_semibold : Label.LabelType.Caption
|
||||
type: root.error ? Proton.Label.LabelType.Caption_semibold : Proton.Label.LabelType.Caption
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,16 +20,20 @@ import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick.Controls.impl 2.13
|
||||
|
||||
RowLayout{
|
||||
Item {
|
||||
id: root
|
||||
property var colorScheme
|
||||
property bool checked
|
||||
property bool disabled
|
||||
property bool hovered
|
||||
property bool loading
|
||||
|
||||
signal clicked
|
||||
|
||||
property bool _disabled: !enabled
|
||||
|
||||
implicitHeight: children[0].implicitHeight
|
||||
implicitWidth: children[0].implicitWidth
|
||||
|
||||
Rectangle {
|
||||
id: indicator
|
||||
implicitWidth: 40
|
||||
@ -38,12 +42,12 @@ RowLayout{
|
||||
radius: 20
|
||||
color: {
|
||||
if (root.loading) return "transparent"
|
||||
if (root.disabled) return root.colorScheme.background_strong
|
||||
if (root._disabled) return root.colorScheme.background_strong
|
||||
return root.colorScheme.background_norm
|
||||
}
|
||||
border {
|
||||
width: 1
|
||||
color: (root.disabled || root.loading) ? "transparent" : colorScheme.field_norm
|
||||
color: (root._disabled || root.loading) ? "transparent" : colorScheme.field_norm
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@ -55,7 +59,7 @@ RowLayout{
|
||||
radius: 12
|
||||
color: {
|
||||
if (root.loading) return "transparent"
|
||||
if (root.disabled) return root.colorScheme.field_disabled
|
||||
if (root._disabled) return root.colorScheme.field_disabled
|
||||
|
||||
if (root.checked) {
|
||||
if (root.hovered) return root.colorScheme.interaction_norm_hover
|
||||
@ -101,7 +105,7 @@ RowLayout{
|
||||
hoverEnabled: true
|
||||
onEntered: {root.hovered = true }
|
||||
onExited: {root.hovered = false }
|
||||
onClicked: { root.clicked();}
|
||||
onClicked: { if (root.enabled) root.clicked();}
|
||||
onPressed: {root.hovered = true }
|
||||
onReleased: { root.hovered = containsMouse }
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ ColorScheme 4.0 ColorScheme.qml
|
||||
ApplicationWindow 4.0 ApplicationWindow.qml
|
||||
Button 4.0 Button.qml
|
||||
CheckBox 4.0 CheckBox.qml
|
||||
ComboBox 4.0 ComboBox.qml
|
||||
Dialog 4.0 Dialog.qml
|
||||
Label 4.0 Label.qml
|
||||
Menu 4.0 Menu.qml
|
||||
|
||||
@ -21,7 +21,7 @@ import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
|
||||
ColumnLayout {
|
||||
Item {
|
||||
id: root
|
||||
property var colorScheme
|
||||
|
||||
@ -32,36 +32,45 @@ ColumnLayout {
|
||||
property var type: SettingsItem.ActionType.Toggle
|
||||
|
||||
property bool checked: true
|
||||
property bool disabled: false
|
||||
property bool loading: false
|
||||
property bool showSeparator: true
|
||||
|
||||
property var _bottomMargin: 20
|
||||
property var _lineWidth: 1
|
||||
property var _toggleTopMargin: 6
|
||||
|
||||
signal clicked
|
||||
|
||||
spacing: 20
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: root.parent.Layout.maximumWidth
|
||||
|
||||
enum ActionType {
|
||||
Toggle = 1, Button = 2, PrimaryButton = 3
|
||||
}
|
||||
|
||||
implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
|
||||
implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
anchors.fill: parent
|
||||
spacing: 16
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Layout.bottomMargin: root._bottomMargin
|
||||
|
||||
spacing: 4
|
||||
|
||||
Label {
|
||||
id:mainLabel
|
||||
id: mainLabel
|
||||
colorScheme: root.colorScheme
|
||||
text: root.text
|
||||
type: Label.Body_semibold
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.minimumWidth: mainLabel.width
|
||||
Layout.maximumWidth: root.Layout.maximumWidth - root.spacing - (
|
||||
toggle.visible ? toggle.width : button.width
|
||||
)
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
Layout.preferredWidth: parent.width
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
colorScheme: root.colorScheme
|
||||
@ -70,15 +79,12 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
Toggle {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
Layout.topMargin: root._toggleTopMargin
|
||||
id: toggle
|
||||
colorScheme: root.colorScheme
|
||||
visible: root.type == SettingsItem.ActionType.Toggle
|
||||
visible: root.type === SettingsItem.ActionType.Toggle
|
||||
|
||||
checked: root.checked
|
||||
loading: root.loading
|
||||
@ -86,20 +92,25 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
id: button
|
||||
colorScheme: root.colorScheme
|
||||
visible: root.type == SettingsItem.Button || root.type == SettingsItem.PrimaryButton
|
||||
visible: root.type === SettingsItem.Button || root.type === SettingsItem.PrimaryButton
|
||||
text: root.actionText + (root.actionIcon != "" ? " " : "")
|
||||
loading: root.loading
|
||||
icon.source: root.actionIcon
|
||||
onClicked: { if (!root.loading) root.clicked() }
|
||||
secondary: root.type != SettingsItem.PrimaryButton
|
||||
secondary: root.type !== SettingsItem.PrimaryButton
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
anchors.left: root.left
|
||||
anchors.right: root.right
|
||||
anchors.bottom: root.bottom
|
||||
color: colorScheme.border_weak
|
||||
height: 1
|
||||
height: root._lineWidth
|
||||
visible: root.showSeparator
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import QtQuick.Controls.impl 2.13
|
||||
|
||||
import Proton 4.0
|
||||
|
||||
ScrollView {
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property var colorScheme
|
||||
@ -31,36 +31,45 @@ ScrollView {
|
||||
|
||||
signal back()
|
||||
|
||||
property int _leftRightMargins: 64
|
||||
property int _topBottomMargins: 68
|
||||
property int _spacing: 22
|
||||
property int _leftMargin: 64
|
||||
property int _rightMargin: 64
|
||||
property int _topMargin: 32
|
||||
property int _bottomMargin: 32
|
||||
property int _spacing: 20
|
||||
|
||||
clip: true
|
||||
contentWidth: pane.width
|
||||
contentHeight: pane.height
|
||||
|
||||
RowLayout{
|
||||
id: pane
|
||||
width: root.width
|
||||
ScrollView {
|
||||
clip: true
|
||||
|
||||
width:root.width
|
||||
height:root.height
|
||||
|
||||
contentWidth: content.width
|
||||
contentHeight: content.height
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
spacing: root._spacing
|
||||
Layout.maximumWidth: root.width - 2*root._leftRightMargins
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: root._topBottomMargins
|
||||
Layout.bottomMargin: root._topBottomMargins
|
||||
Layout.leftMargin: root._leftRightMargins
|
||||
Layout.rightMargin: root._leftRightMargins
|
||||
width: root.width - (root._leftMargin + root._rightMargin)
|
||||
|
||||
anchors{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: root._topMargin
|
||||
bottomMargin: root._bottomMargin
|
||||
leftMargin: root._leftMargin
|
||||
rightMargin: root._rightMargin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: backButton
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
topMargin: 10
|
||||
leftMargin: 18
|
||||
topMargin: root._topMargin
|
||||
leftMargin: (root._leftMargin-backButton.width) / 2
|
||||
}
|
||||
colorScheme: root.colorScheme
|
||||
onClicked: root.back()
|
||||
|
||||
@ -28,7 +28,6 @@ Item {
|
||||
|
||||
property ColorScheme colorScheme
|
||||
property var backend
|
||||
|
||||
property var user
|
||||
property string address
|
||||
|
||||
@ -124,7 +123,9 @@ Item {
|
||||
console.log(" TODO configure ", model.name)
|
||||
return
|
||||
}
|
||||
root.user.configureAppleMail(root.address)
|
||||
if (user) {
|
||||
root.user.configureAppleMail(root.address)
|
||||
}
|
||||
root.dismissed()
|
||||
}
|
||||
}
|
||||
@ -139,7 +140,9 @@ Item {
|
||||
flat: true
|
||||
|
||||
onClicked: {
|
||||
user.setupGuideSeen = true
|
||||
if (user) {
|
||||
user.setupGuideSeen = true
|
||||
}
|
||||
root.dismissed()
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,31 +27,27 @@ Item {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
|
||||
function abort() {
|
||||
root.loginAbort(usernameTextField.text)
|
||||
function reset() {
|
||||
stackLayout.currentIndex = 0
|
||||
loginNormalLayout.reset()
|
||||
login2FALayout.reset()
|
||||
login2PasswordLayout.reset()
|
||||
|
||||
}
|
||||
|
||||
signal login(string username, string password)
|
||||
signal login2FA(string username, string code)
|
||||
signal login2Password(string username, string password)
|
||||
signal loginAbort(string username)
|
||||
function abort() {
|
||||
root.reset()
|
||||
root.backend.loginAbort(usernameTextField.text)
|
||||
}
|
||||
|
||||
implicitHeight: children[0].implicitHeight
|
||||
implicitWidth: children[0].implicitWidth
|
||||
|
||||
property var backend
|
||||
property var window
|
||||
|
||||
property alias username: usernameTextField.text
|
||||
state: "Page 1"
|
||||
|
||||
onLoginAbort: {
|
||||
stackLayout.currentIndex = 0
|
||||
loginNormalLayout.reset()
|
||||
login2FALayout.reset()
|
||||
login2PasswordLayout.reset()
|
||||
}
|
||||
|
||||
property alias currentIndex: stackLayout.currentIndex
|
||||
|
||||
StackLayout {
|
||||
@ -83,18 +79,16 @@ Item {
|
||||
onLoginFreeUserError: {
|
||||
console.assert(stackLayout.currentIndex == 0, "Unexpected loginFreeUserError")
|
||||
stackLayout.loginFailed()
|
||||
window.notifyOnlyPaidUsers()
|
||||
}
|
||||
|
||||
onLoginConnectionError: {
|
||||
if (stackLayout.currentIndex == 0 ) {
|
||||
stackLayout.loginFailed()
|
||||
}
|
||||
window.notifyConnectionLostWhileLogin()
|
||||
}
|
||||
|
||||
onLogin2FARequested: {
|
||||
console.assert(stackLayout.currentIndex == 0, "Unexpected login2FARequested")
|
||||
|
||||
stackLayout.currentIndex = 1
|
||||
}
|
||||
onLogin2FAError: {
|
||||
@ -108,19 +102,12 @@ Item {
|
||||
}
|
||||
onLogin2FAErrorAbort: {
|
||||
console.assert(stackLayout.currentIndex == 1, "Unexpected login2FAErrorAbort")
|
||||
|
||||
stackLayout.currentIndex = 0
|
||||
loginNormalLayout.reset()
|
||||
login2FALayout.reset()
|
||||
login2PasswordLayout.reset()
|
||||
|
||||
root.reset()
|
||||
errorLabel.text = qsTr("Incorrect login credentials. Please try again.")
|
||||
passwordTextField.text = ""
|
||||
}
|
||||
|
||||
onLogin2PasswordRequested: {
|
||||
console.assert(stackLayout.currentIndex == 0 || stackLayout.currentIndex == 1, "Unexpected login2PasswordRequested")
|
||||
|
||||
stackLayout.currentIndex = 2
|
||||
}
|
||||
onLogin2PasswordError: {
|
||||
@ -134,22 +121,13 @@ Item {
|
||||
}
|
||||
onLogin2PasswordErrorAbort: {
|
||||
console.assert(stackLayout.currentIndex == 2, "Unexpected login2PasswordErrorAbort")
|
||||
|
||||
stackLayout.currentIndex = 0
|
||||
loginNormalLayout.reset()
|
||||
login2FALayout.reset()
|
||||
login2PasswordLayout.reset()
|
||||
|
||||
root.reset()
|
||||
errorLabel.text = qsTr("Incorrect login credentials. Please try again.")
|
||||
passwordTextField.text = ""
|
||||
}
|
||||
|
||||
onLoginFinished: {
|
||||
stackLayout.currentIndex = 0
|
||||
loginNormalLayout.reset()
|
||||
passwordTextField.text = ""
|
||||
login2FALayout.reset()
|
||||
login2PasswordLayout.reset()
|
||||
root.reset()
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +146,7 @@ Item {
|
||||
passwordTextField.enabled = true
|
||||
passwordTextField.error = false
|
||||
passwordTextField.assistiveText = ""
|
||||
passwordTextField.text = ""
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
@ -303,7 +282,7 @@ Item {
|
||||
enabled = false
|
||||
loading = true
|
||||
|
||||
root.login(usernameTextField.text, Qt.btoa(passwordTextField.text))
|
||||
root.backend.login(usernameTextField.text, Qt.btoa(passwordTextField.text))
|
||||
}
|
||||
}
|
||||
|
||||
@ -331,6 +310,7 @@ Item {
|
||||
twoFactorPasswordTextField.enabled = true
|
||||
twoFactorPasswordTextField.error = false
|
||||
twoFactorPasswordTextField.assistiveText = ""
|
||||
twoFactorPasswordTextField.text=""
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
@ -388,7 +368,7 @@ Item {
|
||||
enabled = false
|
||||
loading = true
|
||||
|
||||
root.login2FA(usernameTextField.text, Qt.btoa(twoFactorPasswordTextField.text))
|
||||
root.backend.login2FA(usernameTextField.text, Qt.btoa(twoFactorPasswordTextField.text))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -402,6 +382,7 @@ Item {
|
||||
secondPasswordTextField.enabled = true
|
||||
secondPasswordTextField.error = false
|
||||
secondPasswordTextField.assistiveText = ""
|
||||
secondPasswordTextField.text = ""
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
@ -460,7 +441,7 @@ Item {
|
||||
enabled = false
|
||||
loading = true
|
||||
|
||||
root.login2Password(usernameTextField.text, Qt.btoa(secondPasswordTextField.text))
|
||||
root.backend.login2Password(usernameTextField.text, Qt.btoa(secondPasswordTextField.text))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ Item {
|
||||
NotificationFilter {
|
||||
id: notificationFilter
|
||||
|
||||
source: root.notifications.all
|
||||
source: root.notifications ? root.notifications.all : undefined
|
||||
whitelist: root.notificationWhitelist
|
||||
blacklist: root.notificationBlacklist
|
||||
|
||||
@ -59,19 +59,19 @@ Item {
|
||||
label.text = topmost.text
|
||||
|
||||
switch (topmost.type) {
|
||||
case Notification.NotificationType.Danger:
|
||||
case Notification.NotificationType.Danger:
|
||||
image.color = root.colorScheme.signal_danger
|
||||
label.color = root.colorScheme.signal_danger
|
||||
break;
|
||||
case Notification.NotificationType.Warning:
|
||||
case Notification.NotificationType.Warning:
|
||||
image.color = root.colorScheme.signal_warning
|
||||
label.color = root.colorScheme.signal_warning
|
||||
break;
|
||||
case Notification.NotificationType.Success:
|
||||
case Notification.NotificationType.Success:
|
||||
image.color = root.colorScheme.signal_success
|
||||
label.color = root.colorScheme.signal_success
|
||||
break;
|
||||
case Notification.NotificationType.Info:
|
||||
case Notification.NotificationType.Info:
|
||||
image.color = root.colorScheme.signal_info
|
||||
label.color = root.colorScheme.signal_info
|
||||
break;
|
||||
|
||||
@ -198,7 +198,7 @@ Window {
|
||||
Button {
|
||||
Layout.margins: 12
|
||||
colorScheme: root.colorScheme
|
||||
visible: !viewItem.user.loggedIn
|
||||
visible: viewItem.user ? !viewItem.user.loggedIn : false
|
||||
text: qsTr("Sign in")
|
||||
onClicked: {
|
||||
root.showSignIn(viewItem.username)
|
||||
|
||||
@ -28,12 +28,6 @@ Item {
|
||||
property ColorScheme colorScheme
|
||||
|
||||
property var backend
|
||||
property var window
|
||||
|
||||
signal login(string username, string password)
|
||||
signal login2FA(string username, string code)
|
||||
signal login2Password(string username, string password)
|
||||
signal loginAbort(string username)
|
||||
|
||||
implicitHeight: children[0].implicitHeight
|
||||
implicitWidth: children[0].implicitWidth
|
||||
@ -230,22 +224,14 @@ Item {
|
||||
Layout.preferredWidth: 320
|
||||
Layout.fillWidth: true
|
||||
|
||||
onLogin: {
|
||||
root.login(username, password)
|
||||
username: {
|
||||
if (root.backend.users.count !== 1) return ""
|
||||
var user = root.backend.users.get(0)
|
||||
if (user) return ""
|
||||
if (user.loggedIn) return ""
|
||||
return user.username
|
||||
}
|
||||
onLogin2FA: {
|
||||
root.login2FA(username, code)
|
||||
}
|
||||
onLogin2Password: {
|
||||
root.login2Password(username, password)
|
||||
}
|
||||
onLoginAbort: {
|
||||
root.loginAbort(username)
|
||||
}
|
||||
|
||||
username: (backend.users.count === 1 && backend.users.get(0).loggedIn === false) ? backend.users.get(0).username : ""
|
||||
backend: root.backend
|
||||
window: root.window
|
||||
}
|
||||
|
||||
// Right margin
|
||||
|
||||
@ -20,9 +20,10 @@ import QtQuick.Window 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
import "../Proton"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
|
||||
// Primary buttons
|
||||
|
||||
@ -18,7 +18,8 @@
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import Proton 4.0
|
||||
|
||||
import "../Proton"
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
@ -20,7 +20,7 @@ import QtQuick.Window 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
import "../Proton"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
@ -33,29 +33,35 @@ RowLayout {
|
||||
|
||||
CheckBox {
|
||||
text: "Checkbox"
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "Checkbox"
|
||||
error: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "Checkbox"
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
CheckBox {
|
||||
text: ""
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: ""
|
||||
error: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: ""
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,34 +73,40 @@ RowLayout {
|
||||
CheckBox {
|
||||
text: "Checkbox"
|
||||
checked: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "Checkbox"
|
||||
checked: true
|
||||
error: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: "Checkbox"
|
||||
checked: true
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
CheckBox {
|
||||
text: ""
|
||||
checked: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: ""
|
||||
checked: true
|
||||
error: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
CheckBox {
|
||||
text: ""
|
||||
checked: true
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
100
internal/frontend/qml/tests/ComboBoxes.qml
Normal file
100
internal/frontend/qml/tests/ComboBoxes.qml
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright (c) 2021 Proton Technologies AG
|
||||
//
|
||||
// This file is part of ProtonMail Bridge.
|
||||
//
|
||||
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import QtQuick 2.13
|
||||
import QtQuick.Window 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import "../Proton"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
editable: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
colorScheme: root.colorScheme
|
||||
enabled: false
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
editable: true
|
||||
colorScheme: root.colorScheme
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
colorScheme: root.colorScheme
|
||||
LayoutMirroring.enabled: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
editable: true
|
||||
colorScheme: root.colorScheme
|
||||
LayoutMirroring.enabled: true
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
colorScheme: root.colorScheme
|
||||
enabled: false
|
||||
LayoutMirroring.enabled: true
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
Layout.fillWidth: true
|
||||
model: ["First", "Second", "Third"]
|
||||
editable: true
|
||||
colorScheme: root.colorScheme
|
||||
enabled: false
|
||||
LayoutMirroring.enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -20,9 +20,10 @@ import QtQuick.Window 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
import "../Proton"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
|
||||
ColumnLayout {
|
||||
|
||||
@ -20,9 +20,10 @@ import QtQuick.Window 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
import "../Proton"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
|
||||
ColumnLayout {
|
||||
@ -32,30 +33,36 @@ RowLayout {
|
||||
|
||||
Switch {
|
||||
text: "Toggle"
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: "Toggle"
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: "Toggle"
|
||||
loading: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: ""
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: ""
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: ""
|
||||
loading: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
}
|
||||
|
||||
@ -67,35 +74,41 @@ RowLayout {
|
||||
Switch {
|
||||
text: "Toggle"
|
||||
checked: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: "Toggle"
|
||||
checked: true
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: "Toggle"
|
||||
checked: true
|
||||
loading: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: ""
|
||||
checked: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: ""
|
||||
checked: true
|
||||
enabled: false
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
|
||||
Switch {
|
||||
text: ""
|
||||
checked: true
|
||||
loading: true
|
||||
colorScheme: root.colorScheme
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
30
internal/frontend/qml/tests/Test.qml
Normal file
30
internal/frontend/qml/tests/Test.qml
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2021 Proton Technologies AG
|
||||
//
|
||||
// This file is part of ProtonMail Bridge.
|
||||
//
|
||||
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
import QtQuick.Window 2.13
|
||||
|
||||
import "../Proton"
|
||||
|
||||
Window {
|
||||
width: 800
|
||||
height: 600
|
||||
visible: true
|
||||
TestComponents {
|
||||
anchors.fill: parent
|
||||
colorScheme: ProtonStyle.currentStyle
|
||||
}
|
||||
}
|
||||
@ -19,52 +19,68 @@ import QtQuick 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
import "../Proton"
|
||||
|
||||
Rectangle {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
color: colorScheme.background_norm
|
||||
clip: true
|
||||
|
||||
ColumnLayout {
|
||||
implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
|
||||
implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin
|
||||
|
||||
ScrollView {
|
||||
anchors.fill: parent
|
||||
|
||||
spacing: 5
|
||||
ColumnLayout {
|
||||
anchors.margins: 20
|
||||
|
||||
Buttons {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
width: root.width
|
||||
|
||||
TextFields {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
spacing: 5
|
||||
|
||||
TextAreas {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
Buttons {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
|
||||
CheckBoxes {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
CheckBoxes {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
|
||||
RadioButtons {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
ComboBoxes {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
|
||||
Switches {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
RadioButtons {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
|
||||
Switches {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
|
||||
TextAreas {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
|
||||
TextFields {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ import QtQuick.Window 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
import "../Proton"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
|
||||
@ -20,9 +20,10 @@ import QtQuick.Window 2.13
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
import Proton 4.0
|
||||
import "../Proton"
|
||||
|
||||
RowLayout {
|
||||
id: root
|
||||
property ColorScheme colorScheme
|
||||
|
||||
// Norm
|
||||
@ -148,6 +149,23 @@ RowLayout {
|
||||
placeholderText: "Placeholder"
|
||||
label: "Label"
|
||||
hint: "Hint"
|
||||
assistiveText: "Assistive text"
|
||||
}
|
||||
|
||||
TextField {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
|
||||
placeholderText: "Placeholder"
|
||||
label: "Label"
|
||||
}
|
||||
|
||||
TextField {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
|
||||
placeholderText: "Placeholder"
|
||||
hint: "Hint"
|
||||
}
|
||||
|
||||
TextField {
|
||||
@ -157,12 +175,5 @@ RowLayout {
|
||||
placeholderText: "Placeholder"
|
||||
assistiveText: "Assistive text"
|
||||
}
|
||||
|
||||
TextField {
|
||||
colorScheme: root.colorScheme
|
||||
Layout.fillWidth: true
|
||||
|
||||
placeholderText: "Placeholder"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user