forked from Silverfish/proton-bridge
GODT-937: Add keychain switcher to frontend
GODT-1008: Fix transparent dialog under certain conditions
This commit is contained in:
committed by
James Houlahan
parent
8b436186a4
commit
0fe69d9de1
@ -210,3 +210,13 @@ func (b *Bridge) SetUpdateChannel(channel updater.UpdateChannel) error {
|
|||||||
|
|
||||||
return b.versioner.RemoveOtherVersions(version.Version)
|
return b.versioner.RemoveOtherVersions(version.Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetKeychainApp returns current keychain helper.
|
||||||
|
func (b *Bridge) GetKeychainApp() string {
|
||||||
|
return b.settings.Get(settings.PreferredKeychainKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetKeychainApp sets current keychain helper.
|
||||||
|
func (b *Bridge) SetKeychainApp(helper string) {
|
||||||
|
b.settings.Set(settings.PreferredKeychainKey, helper)
|
||||||
|
}
|
||||||
|
|||||||
194
internal/frontend/qml/BridgeUI/DialogKeychainChange.qml
Normal file
194
internal/frontend/qml/BridgeUI/DialogKeychainChange.qml
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
// 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/>.
|
||||||
|
|
||||||
|
// Change default keychain dialog
|
||||||
|
|
||||||
|
import QtQuick 2.8
|
||||||
|
import BridgeUI 1.0
|
||||||
|
import ProtonUI 1.0
|
||||||
|
import QtQuick.Controls 2.2 as QC
|
||||||
|
import QtQuick.Layouts 1.0
|
||||||
|
|
||||||
|
Dialog {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
title : "Change which keychain Bridge uses as default"
|
||||||
|
subtitle : "Select which keychain is used (Bridge will automatically restart)"
|
||||||
|
isDialogBusy: currentIndex==1
|
||||||
|
|
||||||
|
property var selectedKeychain
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: go.selectedKeychain
|
||||||
|
onValueChanged: {
|
||||||
|
console.debug("go.selectedKeychain == ", go.selectedKeychain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: root.titleHeight + Style.dialog.heightSeparator
|
||||||
|
Layout.maximumHeight: root.titleHeight + Style.dialog.heightSeparator
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
id: keychainRadioButtons
|
||||||
|
model: go.availableKeychain
|
||||||
|
QC.RadioButton {
|
||||||
|
id: radioDelegate
|
||||||
|
text: modelData
|
||||||
|
checked: go.selectedKeychain === modelData
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
spacing: Style.main.spacing
|
||||||
|
|
||||||
|
indicator: Text {
|
||||||
|
text : radioDelegate.checked ? Style.fa.check_circle : Style.fa.circle_o
|
||||||
|
color : radioDelegate.checked ? Style.main.textBlue : Style.main.textInactive
|
||||||
|
font {
|
||||||
|
pointSize: Style.dialog.iconSize * Style.pt
|
||||||
|
family: Style.fontawesome.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contentItem: Text {
|
||||||
|
text: radioDelegate.text
|
||||||
|
color: Style.main.text
|
||||||
|
font {
|
||||||
|
pointSize: Style.dialog.fontSize * Style.pt
|
||||||
|
bold: checked
|
||||||
|
}
|
||||||
|
horizontalAlignment : Text.AlignHCenter
|
||||||
|
verticalAlignment : Text.AlignVCenter
|
||||||
|
leftPadding: Style.dialog.iconSize
|
||||||
|
}
|
||||||
|
|
||||||
|
onCheckedChanged: {
|
||||||
|
if (checked) {
|
||||||
|
root.selectedKeychain = modelData
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: Style.dialog.heightSeparator
|
||||||
|
Layout.maximumHeight: Style.dialog.heightSeparator
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: buttonRow
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
spacing: Style.dialog.spacing
|
||||||
|
ButtonRounded {
|
||||||
|
id:buttonNo
|
||||||
|
color_main: Style.dialog.text
|
||||||
|
fa_icon: Style.fa.times
|
||||||
|
text: qsTr("Cancel", "dismisses current action")
|
||||||
|
onClicked : root.hide()
|
||||||
|
}
|
||||||
|
ButtonRounded {
|
||||||
|
id: buttonYes
|
||||||
|
color_main: Style.dialog.text
|
||||||
|
color_minor: Style.main.textBlue
|
||||||
|
isOpaque: true
|
||||||
|
fa_icon: Style.fa.check
|
||||||
|
text: qsTr("Okay", "confirms and dismisses a notification")
|
||||||
|
onClicked : root.confirmed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.minimumHeight: root.titleHeight + Style.dialog.heightSeparator
|
||||||
|
Layout.maximumHeight: root.titleHeight + Style.dialog.heightSeparator
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: answ
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width : parent.width/2
|
||||||
|
color: Style.dialog.text
|
||||||
|
font {
|
||||||
|
pointSize : Style.dialog.fontSize * Style.pt
|
||||||
|
bold : true
|
||||||
|
}
|
||||||
|
text : "Default keychain is now set to " + root.selectedKeychain +
|
||||||
|
"\n\n" +
|
||||||
|
qsTr("Settings will be applied after the next start.", "notification about setting being applied after next start") +
|
||||||
|
"\n\n" +
|
||||||
|
qsTr("Bridge will now restart.", "notification about restarting")
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Shortcut {
|
||||||
|
sequence: StandardKey.Cancel
|
||||||
|
onActivated: root.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
Shortcut {
|
||||||
|
sequence: "Enter"
|
||||||
|
onActivated: root.confirmed()
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmed() {
|
||||||
|
if (selectedKeychain === go.selectedKeychain) {
|
||||||
|
root.hide()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
incrementCurrentIndex()
|
||||||
|
timer.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
timer.interval : 5000
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: timer
|
||||||
|
onTriggered: {
|
||||||
|
// This action triggers restart on the backend side.
|
||||||
|
go.selectedKeychain = selectedKeychain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -303,6 +303,10 @@ Window {
|
|||||||
id: dialogChangePort
|
id: dialogChangePort
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DialogKeychainChange {
|
||||||
|
id: dialogChangeKeychain
|
||||||
|
}
|
||||||
|
|
||||||
DialogConnectionTroubleshoot {
|
DialogConnectionTroubleshoot {
|
||||||
id: dialogConnectionTroubleshoot
|
id: dialogConnectionTroubleshoot
|
||||||
}
|
}
|
||||||
|
|||||||
@ -239,6 +239,25 @@ Item {
|
|||||||
dialogGlobal.show()
|
dialogGlobal.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ButtonIconText {
|
||||||
|
id: changeKeychain
|
||||||
|
visible: advancedSettings.isAdvanced && (go.availableKeychain.length > 1)
|
||||||
|
text: qsTr("Change keychain", "button to open dialog with default keychain selection")
|
||||||
|
leftIcon.text : Style.fa.key
|
||||||
|
rightIcon {
|
||||||
|
text : qsTr("Change", "clickable link next to change keychain button in settings")
|
||||||
|
color: Style.main.text
|
||||||
|
font {
|
||||||
|
family : changeKeychain.font.family // use default font, not font-awesome
|
||||||
|
pointSize : Style.settings.fontSize * Style.pt
|
||||||
|
underline : true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
dialogChangeKeychain.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ module BridgeUI
|
|||||||
AccountDelegate 1.0 AccountDelegate.qml
|
AccountDelegate 1.0 AccountDelegate.qml
|
||||||
Credits 1.0 Credits.qml
|
Credits 1.0 Credits.qml
|
||||||
DialogFirstStart 1.0 DialogFirstStart.qml
|
DialogFirstStart 1.0 DialogFirstStart.qml
|
||||||
|
DialogKeychainChange 1.0 DialogKeychainChange.qml
|
||||||
DialogPortChange 1.0 DialogPortChange.qml
|
DialogPortChange 1.0 DialogPortChange.qml
|
||||||
DialogYesNo 1.0 DialogYesNo.qml
|
DialogYesNo 1.0 DialogYesNo.qml
|
||||||
DialogTLSCertInfo 1.0 DialogTLSCertInfo.qml
|
DialogTLSCertInfo 1.0 DialogTLSCertInfo.qml
|
||||||
|
|||||||
@ -111,6 +111,11 @@ StackLayout {
|
|||||||
Accessible.description: title
|
Accessible.description: title
|
||||||
Accessible.focusable: true
|
Accessible.focusable: true
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (background.visible != visible) {
|
||||||
|
background.visible = visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
visible : false
|
visible : false
|
||||||
anchors {
|
anchors {
|
||||||
|
|||||||
@ -281,6 +281,9 @@ Window {
|
|||||||
|
|
||||||
property bool hasNoKeychain : true
|
property bool hasNoKeychain : true
|
||||||
|
|
||||||
|
property var availableKeychain: ["pass-app", "gnome-keyring"]
|
||||||
|
property var selectedKeychain: "gnome-keyring"
|
||||||
|
|
||||||
property string wrongCredentials
|
property string wrongCredentials
|
||||||
property string wrongMailboxPassword
|
property string wrongMailboxPassword
|
||||||
property string canNotReachAPI
|
property string canNotReachAPI
|
||||||
|
|||||||
@ -45,6 +45,7 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
"github.com/ProtonMail/proton-bridge/internal/frontend/types"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/locations"
|
"github.com/ProtonMail/proton-bridge/internal/locations"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/updater"
|
"github.com/ProtonMail/proton-bridge/internal/updater"
|
||||||
|
"github.com/ProtonMail/proton-bridge/pkg/keychain"
|
||||||
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
||||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||||
"github.com/ProtonMail/proton-bridge/pkg/ports"
|
"github.com/ProtonMail/proton-bridge/pkg/ports"
|
||||||
@ -372,6 +373,14 @@ func (s *FrontendQt) qtExecute(Procedure func(*FrontendQt) error) error {
|
|||||||
s.Qml.SetIsEarlyAccess(false)
|
s.Qml.SetIsEarlyAccess(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
availableKeychain := []string{}
|
||||||
|
for chain := range keychain.Helpers {
|
||||||
|
availableKeychain = append(availableKeychain, chain)
|
||||||
|
}
|
||||||
|
s.Qml.SetAvailableKeychain(availableKeychain)
|
||||||
|
|
||||||
|
s.Qml.SetSelectedKeychain(s.settings.Get(settings.PreferredKeychainKey))
|
||||||
|
|
||||||
// Set reporting of outgoing email without encryption.
|
// Set reporting of outgoing email without encryption.
|
||||||
s.Qml.SetIsReportingOutgoingNoEnc(s.settings.GetBool(settings.ReportOutgoingNoEncKey))
|
s.Qml.SetIsReportingOutgoingNoEnc(s.settings.GetBool(settings.ReportOutgoingNoEncKey))
|
||||||
|
|
||||||
@ -711,3 +720,16 @@ func (s *FrontendQt) setGUIIsReady() {
|
|||||||
s.initializing.Done()
|
s.initializing.Done()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FrontendQt) getKeychain() string {
|
||||||
|
return s.bridge.GetKeychainApp()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FrontendQt) setKeychain(keychain string) {
|
||||||
|
if keychain != s.bridge.GetKeychainApp() {
|
||||||
|
s.bridge.SetKeychainApp(keychain)
|
||||||
|
|
||||||
|
s.restarter.SetToRestart()
|
||||||
|
s.App.Quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -66,6 +66,9 @@ type GoQMLInterface struct {
|
|||||||
_ func() `slot:"startManualUpdate"`
|
_ func() `slot:"startManualUpdate"`
|
||||||
_ func() `slot:"guiIsReady"`
|
_ func() `slot:"guiIsReady"`
|
||||||
|
|
||||||
|
_ []string `property:"availableKeychain"`
|
||||||
|
_ string `property:"selectedKeychain"`
|
||||||
|
|
||||||
// Translations.
|
// Translations.
|
||||||
_ string `property:"wrongCredentials"`
|
_ string `property:"wrongCredentials"`
|
||||||
_ string `property:"wrongMailboxPassword"`
|
_ string `property:"wrongMailboxPassword"`
|
||||||
@ -209,4 +212,7 @@ func (s *GoQMLInterface) SetFrontend(f *FrontendQt) {
|
|||||||
s.ConnectToggleIsReportingOutgoingNoEnc(f.toggleIsReportingOutgoingNoEnc)
|
s.ConnectToggleIsReportingOutgoingNoEnc(f.toggleIsReportingOutgoingNoEnc)
|
||||||
s.ConnectShouldSendAnswer(f.shouldSendAnswer)
|
s.ConnectShouldSendAnswer(f.shouldSendAnswer)
|
||||||
s.ConnectSaveOutgoingNoEncPopupCoord(f.saveOutgoingNoEncPopupCoord)
|
s.ConnectSaveOutgoingNoEncPopupCoord(f.saveOutgoingNoEncPopupCoord)
|
||||||
|
|
||||||
|
s.ConnectSetSelectedKeychain(f.setKeychain)
|
||||||
|
s.ConnectSelectedKeychain(f.getKeychain)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,6 +61,7 @@
|
|||||||
<file alias="BubbleMenu.qml" >./qml/BridgeUI/BubbleMenu.qml</file>
|
<file alias="BubbleMenu.qml" >./qml/BridgeUI/BubbleMenu.qml</file>
|
||||||
<file alias="Credits.qml" >./qml/BridgeUI/Credits.qml</file>
|
<file alias="Credits.qml" >./qml/BridgeUI/Credits.qml</file>
|
||||||
<file alias="DialogFirstStart.qml" >./qml/BridgeUI/DialogFirstStart.qml</file>
|
<file alias="DialogFirstStart.qml" >./qml/BridgeUI/DialogFirstStart.qml</file>
|
||||||
|
<file alias="DialogKeychainChange.qml" >./qml/BridgeUI/DialogKeychainChange.qml</file>
|
||||||
<file alias="DialogPortChange.qml" >./qml/BridgeUI/DialogPortChange.qml</file>
|
<file alias="DialogPortChange.qml" >./qml/BridgeUI/DialogPortChange.qml</file>
|
||||||
<file alias="DialogYesNo.qml" >./qml/BridgeUI/DialogYesNo.qml</file>
|
<file alias="DialogYesNo.qml" >./qml/BridgeUI/DialogYesNo.qml</file>
|
||||||
<file alias="DialogTLSCertInfo.qml" >./qml/BridgeUI/DialogTLSCertInfo.qml</file>
|
<file alias="DialogTLSCertInfo.qml" >./qml/BridgeUI/DialogTLSCertInfo.qml</file>
|
||||||
|
|||||||
@ -82,6 +82,8 @@ type Bridger interface {
|
|||||||
DisallowProxy()
|
DisallowProxy()
|
||||||
GetUpdateChannel() updater.UpdateChannel
|
GetUpdateChannel() updater.UpdateChannel
|
||||||
SetUpdateChannel(updater.UpdateChannel) error
|
SetUpdateChannel(updater.UpdateChannel) error
|
||||||
|
GetKeychainApp() string
|
||||||
|
SetKeychainApp(keychain string)
|
||||||
}
|
}
|
||||||
|
|
||||||
type bridgeWrap struct {
|
type bridgeWrap struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user