GODT-1569: upgrade bridge from qt 5 to qt 6.

Fixed issues introduced by upgrading to Qt 5.15.
WIP: upgrade to Qt 6
WIP: QML fixes. [sklp-ci]
WIP: macOS font fix.
WIP: backend is a now a singleton.
WIP: remove version number of import.
WIP: fixed missing Action in qmldir.
WIP: fixed errors on program exit.
WIP: CMake detects host arch on mac if not specified.
This commit is contained in:
Xavier Michelon
2022-07-14 18:08:54 +02:00
committed by Jakub
parent 8f2e616e07
commit 664f81249c
65 changed files with 742 additions and 714 deletions

View File

@ -56,7 +56,7 @@ QString BridgeMonitor::locateBridgeExe()
for (QString const &dir: dirs) for (QString const &dir: dirs)
{ {
QFileInfo const fileInfo = QDir(dir).absoluteFilePath(exeName); QFileInfo const fileInfo(QDir(dir).absoluteFilePath(exeName));
if (fileInfo.exists() && fileInfo.isFile() && fileInfo.isExecutable()) if (fileInfo.exists() && fileInfo.isFile() && fileInfo.isExecutable())
return fileInfo.absoluteFilePath(); return fileInfo.absoluteFilePath();
} }
@ -91,7 +91,7 @@ void BridgeMonitor::run()
emit started(); emit started();
QProcess p; QProcess p;
p.start(exePath_); p.start(exePath_, QStringList());
p.waitForStarted(); p.waitForStarted();
while (!p.waitForFinished(100)) while (!p.waitForFinished(100))

View File

@ -17,15 +17,30 @@
cmake_minimum_required(VERSION 3.22) cmake_minimum_required(VERSION 3.22)
set(CMAKE_OSX_ARCHITECTURES x86_64) # needs to be set before the first project() directive.
#We rely on vcpkg for to get gRPC+Protobuf #We rely on vcpkg for to get gRPC+Protobuf
if (NOT DEFINED ENV{VCPKG_ROOT}) if (NOT DEFINED ENV{VCPKG_ROOT})
message(FATAL_ERROR "vcpkg is required. Install vcpkg and define VCPKG_ROOT to point the the vcpkg installation folder. (e.g. ~/vcpkg/") message(FATAL_ERROR "vcpkg is required. Install vcpkg and define VCPKG_ROOT to point the the vcpkg installation folder. (e.g. ~/vcpkg/")
endif() endif()
# For now we support only a single architecture for macOS (ARM64 or x86_64). We need to investigate how to build universal binaries with vcpkg.
if (APPLE) if (APPLE)
set(VCPKG_TARGET_TRIPLET x64-osx) if (NOT DEFINED CMAKE_OSX_ARCHITECTURES)
execute_process(COMMAND "uname" "-m" OUTPUT_VARIABLE UNAME_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE)
set(CMAKE_OSX_ARCHITECTURES ${UNAME_RESULT} CACHE STRING "osx_architectures")
endif()
if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
message(STATUS "Building for Apple Silicon Mac computers")
set(VCPKG_TARGET_TRIPLET arm64-osx)
elseif (CMAKE_OSX_ARCHITECTURES STREQUAL "x86_64")
message(STATUS "Building for Intel based Mac computers")
set(VCPKG_TARGET_TRIPLET x64-osx)
else ()
message(FATAL_ERROR "Unknown value for CMAKE_OSX_ARCHITECTURE. Please use one of \"arm64\" and \"x86_64\". Multiple architectures are not supported.")
endif ()
endif() endif()
if (WIN32) if (WIN32)
set(VCPKG_TARGET_TRIPLET x64-mingw-static) set(VCPKG_TARGET_TRIPLET x64-mingw-static)
endif() endif()
@ -33,16 +48,15 @@ set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CAC
project(bridge-gui LANGUAGES CXX) project(bridge-gui LANGUAGES CXX)
if (APPLE) # On macOS, we have some Objective-C++ code in DockIcon to deal with ... the dock icon. if (APPLE) # On macOS, we have some Objective-C++ code in DockIcon to deal with the dock icon.
enable_language(OBJC OBJCXX) enable_language(OBJC OBJCXX)
endif() endif()
if (NOT DEFINED ENV{QT5DIR}) if (NOT DEFINED ENV{QT6DIR})
message(FATAL_ERROR "QT5DIR needs to be defined and point to the root of your Qt5 folder (e.g. /Users/MyName/Qt/5.10.1/clang_64).") message(FATAL_ERROR "QT6DIR needs to be defined and point to the root of your Qt 6 folder (e.g. /Users/MyName/Qt/6.3.1/clang_64).")
endif() endif()
set(CMAKE_PREFIX_PATH $ENV{QT6DIR} ${CMAKE_PREFIX_PATH})
set(CMAKE_PREFIX_PATH $ENV{QT5DIR} ${CMAKE_PREFIX_PATH})
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
@ -61,7 +75,7 @@ if (APPLE) # We need to link the Cocoa framework for the dock icon.
endif() endif()
find_package(Qt5 COMPONENTS find_package(Qt6 COMPONENTS
Core Core
Quick Quick
Qml Qml
@ -136,10 +150,10 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR})
target_precompile_headers(bridge-gui PRIVATE Pch.h) target_precompile_headers(bridge-gui PRIVATE Pch.h)
target_link_libraries(bridge-gui target_link_libraries(bridge-gui
Qt5::Core Qt6::Core
Qt5::Quick Qt6::Quick
Qt5::Qml Qt6::Qml
Qt5::QuickControls2 Qt6::QuickControls2
protobuf::libprotobuf protobuf::libprotobuf
gRPC::grpc++ gRPC::grpc++
) )

View File

@ -1,5 +1,6 @@
## Prerequisite ## Prerequisite
### Linux (debian and derivates)
```` bash ```` bash
sudo apt install build-essential sudo apt install build-essential
sudo apt install tar curl zip unzip sudo apt install tar curl zip unzip
@ -7,22 +8,63 @@ sudo apt install linux-headers-$(uname -r)
sudo apt install mesa-common-dev libglu1-mesa-dev sudo apt install mesa-common-dev libglu1-mesa-dev
```` ````
## Define Qt5DIR ### macOS & WIndows
```` bash Coming soon...
export QT5DIR=/opt/Qt/5.13.0/gcc_64
````
## install vcpkg and define VCPKG_ROOT
```` bash ### Define QT6DIR
``` bash
export QT6DIR=/opt/Qt/6.3.1/gcc_64
```
### install vcpkg and define VCPKG_ROOT
``` bash
git clone https://github.com/Microsoft/vcpkg.git git clone https://github.com/Microsoft/vcpkg.git
./vcpkg/bootstrap-vcpkg.sh ./vcpkg/bootstrap-vcpkg.sh
export VCPKG_ROOT=$PWD/vcpkg export VCPKG_ROOT=$PWD/vcpkg
```` ```
## install grpc & protobuf ## install grpc & protobuf
```` bash ``` bash
./vcpkg install grpc ./vcpkg install grpc
```` ```
## Building
A simple script is provided that run the appropriate CMake command.
``` bash
./build.sh
```
## Running
Simply run from the cmake build folder (`cmake-build-debug` by default)
``` bash
./bridge-gui
```
`bridge-gui` will launch the `bridge` executable that it will try to locate in
- The working directory.
- The application directory.
- `cmd/Desktop-Bridge/`, `../cmd/Desktop-Bridge/`, `../../cmd/Desktop-Bridge`
(up to five parent folders above the current folder are inspected).
you can specify the location of the bridge executable using the `-b` or
`--bridge-exe-path` command-line parameter:
``` bash
./bridge-gui -b "~/bin/bridge"
```
you can also ask bridge-gui to connect to an already running instance of `bridge`
using the `-a` or `--attach` command line parameter.
``` bash
./bridge-gui -a
```

View File

@ -28,8 +28,6 @@
//**************************************************************************************************************************************************** //****************************************************************************************************************************************************
std::shared_ptr<QGuiApplication> initQtApplication(int argc, char *argv[]) std::shared_ptr<QGuiApplication> initQtApplication(int argc, char *argv[])
{ {
// Note the two following attributes must be set before instantiating the QCoreApplication/QGuiApplication class.
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, false);
if (QSysInfo::productType() != "windows") if (QSysInfo::productType() != "windows")
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
@ -69,22 +67,22 @@ QQmlComponent *createRootQmlComponent(QQmlApplicationEngine &engine)
{ {
QString const qrcQmlDir = "qrc:/qml"; QString const qrcQmlDir = "qrc:/qml";
qmlRegisterType<QMLBackend>("CppBackend", 1, 0, "QMLBackend"); qmlRegisterSingletonInstance("Proton", 1, 0, "Backend", &app().backend());
qmlRegisterType<UserList>("CppBackend", 1, 0, "UserList"); qmlRegisterType<UserList>("Proton", 1, 0, "UserList");
qmlRegisterType<User>("CppBackend", 1, 0, "User"); qmlRegisterType<User>("Proton", 1, 0, "User");
auto rootComponent = new QQmlComponent(&engine, &engine); auto rootComponent = new QQmlComponent(&engine, &engine);
engine.addImportPath(qrcQmlDir); engine.addImportPath(qrcQmlDir);
engine.addPluginPath(qrcQmlDir); engine.addPluginPath(qrcQmlDir);
QQuickStyle::addStylePath(qrcQmlDir);
QQuickStyle::setStyle("Proton"); QQuickStyle::setStyle("Proton");
rootComponent->loadUrl(QUrl(qrcQmlDir + "/Bridge.qml")); rootComponent->loadUrl(QUrl(qrcQmlDir + "/Bridge.qml"));
if (rootComponent->status() != QQmlComponent::Status::Ready) if (rootComponent->status() != QQmlComponent::Status::Ready)
{
app().log().error(rootComponent->errorString());
throw Exception("Could not load QML component"); throw Exception("Could not load QML component");
}
return rootComponent; return rootComponent;
} }
@ -178,9 +176,8 @@ int main(int argc, char *argv[])
app().backend().init(); app().backend().init();
QQmlApplicationEngine engine; QQmlApplicationEngine engine;
QQmlComponent *rootComponent = createRootQmlComponent(engine); std::unique_ptr<QQmlComponent> rootComponent(createRootQmlComponent(engine));
std::unique_ptr<QObject> rootObject(rootComponent->beginCreate(engine.rootContext()));
QObject *rootObject = rootComponent->beginCreate(engine.rootContext());
if (!rootObject) if (!rootObject)
throw Exception("Could not create root object."); throw Exception("Could not create root object.");
rootObject->setProperty("backend", QVariant::fromValue(&app().backend())); rootObject->setProperty("backend", QVariant::fromValue(&app().backend()));
@ -188,17 +185,23 @@ int main(int argc, char *argv[])
BridgeMonitor *bridgeMonitor = app().bridgeMonitor(); BridgeMonitor *bridgeMonitor = app().bridgeMonitor();
bool bridgeExited = false; bool bridgeExited = false;
QMetaObject::Connection connection;
if (bridgeMonitor) if (bridgeMonitor)
QObject::connect(bridgeMonitor, &BridgeMonitor::processExited, [&](int returnCode) { connection = QObject::connect(bridgeMonitor, &BridgeMonitor::processExited, [&](int returnCode) {
// GODT-1671 We need to find a 'safe' way to check if brige crashed and restart instead of just quitting. Is returnCode enough? // GODT-1671 We need to find a 'safe' way to check if brige crashed and restart instead of just quitting. Is returnCode enough?
bridgeExited = true; bridgeExited = true;// clazy:exclude=lambda-in-connect
qGuiApp->exit(returnCode); qGuiApp->exit(returnCode);
}); });
int result = QGuiApplication::exec(); int const result = QGuiApplication::exec();
QObject::disconnect(connection);
app().grpc().stopEventStream(); app().grpc().stopEventStream();
app().backend().clearUserList(); // required for proper exit. We may want to investigate why at some point.
// We manually delete the QML components to avoid warnings error due to order of deletion of C++ / JS objects and singletons.
rootObject.reset();
rootComponent.reset();
if (!bridgeExited) if (!bridgeExited)
closeBridgeApp(); closeBridgeApp();

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
Item { Item {
id: root id: root

View File

@ -15,16 +15,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
Item { Item {
id: root id: root
property ColorScheme colorScheme property ColorScheme colorScheme
property var backend
property var notifications property var notifications
property var user property var user
@ -117,7 +116,7 @@ Item {
Button { Button {
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
colorScheme: root.colorScheme colorScheme: root.colorScheme
icon.source: "icons/ic-trash.svg" icon.source: "/qml/icons/ic-trash.svg"
secondary: true secondary: true
onClicked: { onClicked: {
if (!root.user) return if (!root.user) return
@ -227,8 +226,8 @@ Item {
Configuration { Configuration {
colorScheme: root.colorScheme colorScheme: root.colorScheme
title: qsTr("IMAP") title: qsTr("IMAP")
hostname: root.backend.hostname hostname: Backend.hostname
port: root.backend.portIMAP.toString() port: Backend.portIMAP.toString()
username: configuration.currentAddress username: configuration.currentAddress
password: root.user ? root.user.password : "" password: root.user ? root.user.password : ""
security: "STARTTLS" security: "STARTTLS"
@ -237,11 +236,11 @@ Item {
Configuration { Configuration {
colorScheme: root.colorScheme colorScheme: root.colorScheme
title: qsTr("SMTP") title: qsTr("SMTP")
hostname : root.backend.hostname hostname : Backend.hostname
port : root.backend.portSMTP.toString() port : Backend.portSMTP.toString()
username : configuration.currentAddress username : configuration.currentAddress
password : root.user ? root.user.password : "" password : root.user ? root.user.password : ""
security : root.backend.useSSLforSMTP ? "SSL" : "STARTTLS" security : Backend.useSSLforSMTP ? "SSL" : "STARTTLS"
} }
} }
} }

View File

@ -15,13 +15,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
Popup { Popup {
id: root id: root
@ -119,13 +119,13 @@ Popup {
switch (root.notification.type) { switch (root.notification.type) {
case Notification.NotificationType.Info: case Notification.NotificationType.Info:
return "./icons/ic-info-circle-filled.svg" return "/qml/icons/ic-info-circle-filled.svg"
case Notification.NotificationType.Success: case Notification.NotificationType.Success:
return "./icons/ic-info-circle-filled.svg" return "/qml/icons/ic-info-circle-filled.svg"
case Notification.NotificationType.Warning: case Notification.NotificationType.Warning:
return "./icons/ic-exclamation-circle-filled.svg" return "/qml/icons/ic-exclamation-circle-filled.svg"
case Notification.NotificationType.Danger: case Notification.NotificationType.Danger:
return "./icons/ic-exclamation-circle-filled.svg" return "/qml/icons/ic-exclamation-circle-filled.svg"
} }
} }
} }

View File

@ -15,13 +15,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import Qt.labs.platform 1.1 import Qt.labs.platform
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
QtObject { QtObject {
id: root id: root
@ -33,12 +33,10 @@ QtObject {
return Math.max(lower_limit, Math.min(upper_limit, num)) return Math.max(lower_limit, Math.min(upper_limit, num))
} }
property var backend
property var title: "Proton Mail Bridge" property var title: "Proton Mail Bridge"
property Notifications _notifications: Notifications { property Notifications _notifications: Notifications {
id: notifications id: notifications
backend: root.backend
frontendMain: mainWindow frontendMain: mainWindow
frontendStatus: statusWindow frontendStatus: statusWindow
frontendTray: trayIcon frontendTray: trayIcon
@ -49,19 +47,18 @@ QtObject {
visible: false visible: false
title: root.title title: root.title
backend: root.backend
notifications: root._notifications notifications: root._notifications
onVisibleChanged: { onVisibleChanged: {
backend.dockIconVisible = visible Backend.dockIconVisible = visible
} }
Connections { Connections {
target: root.backend target: Backend
onCacheUnavailable: { function onCacheUnavailable() {
mainWindow.showAndRise() mainWindow.showAndRise()
} }
onColorSchemeNameChanged: root.setColorScheme() function onColorSchemeNameChanged(scheme) { root.setColorScheme() }
} }
} }
@ -70,7 +67,6 @@ QtObject {
visible: false visible: false
title: root.title title: root.title
backend: root.backend
notifications: root._notifications notifications: root._notifications
onShowMainWindow: { onShowMainWindow: {
@ -93,7 +89,7 @@ QtObject {
} }
onQuit: { onQuit: {
backend.quit() Backend.quit()
} }
property rect screenRect property rect screenRect
@ -157,14 +153,14 @@ QtObject {
visible: true visible: true
icon.source: getTrayIconPath() icon.source: getTrayIconPath()
icon.mask: true // make sure that systems like macOS will use proper color icon.mask: true // make sure that systems like macOS will use proper color
tooltip: `${root.title} v${backend.version}` tooltip: `${root.title} v${Backend.version}`
onActivated: { onActivated: function(reason) {
function calcStatusWindowPosition() { function calcStatusWindowPosition() {
// On some platforms (X11 / Plasma) Qt does not provide icon position and geometry info. // On some platforms (X11 / Plasma) Qt does not provide icon position and geometry info.
// In this case we rely on cursor position // In this case we rely on cursor position
var iconRect = Qt.rect(geometry.x, geometry.y, geometry.width, geometry.height) var iconRect = Qt.rect(geometry.x, geometry.y, geometry.width, geometry.height)
if (geometry.width == 0 && geometry.height == 0) { if (geometry.width == 0 && geometry.height == 0) {
var mousePos = backend.getCursorPos() var mousePos = Backend.getCursorPos()
iconRect.x = mousePos.x iconRect.x = mousePos.x
iconRect.y = mousePos.y iconRect.y = mousePos.y
iconRect.width = 0 iconRect.width = 0
@ -229,7 +225,7 @@ QtObject {
} }
function getTrayIconPath() { function getTrayIconPath() {
var color = backend.goos == "darwin" ? "mono" : "color" var color = Backend.goos == "darwin" ? "mono" : "color"
var level = "norm" var level = "norm"
if (_systrayfilter.topmost) { if (_systrayfilter.topmost) {
@ -245,25 +241,24 @@ QtObject {
break; break;
} }
} }
return `qrc:/qml/icons/systray-${color}-${level}.png`
return `./icons/systray-${color}-${level}.png`
} }
} }
Component.onCompleted: { Component.onCompleted: {
if (!root.backend) { if (!Backend) {
console.log("backend not loaded") console.log("Backend not loaded")
} }
root.setColorScheme() root.setColorScheme()
if (!root.backend.users) { if (!Backend.users) {
console.log("users not loaded") console.log("users not loaded")
} }
var c = root.backend.users.count var c = Backend.users.count
var u = root.backend.users.get(0) var u = Backend.users.get(0)
// DEBUG // DEBUG
if (c != 0) { if (c != 0) {
console.log("users non zero", c) console.log("users non zero", c)
@ -280,15 +275,15 @@ QtObject {
} }
} }
if (root.backend.showOnStartup) { if (Backend.showOnStartup) {
mainWindow.showAndRise() mainWindow.showAndRise()
} }
root.backend.guiReady() Backend.guiReady()
} }
function setColorScheme() { function setColorScheme() {
if (root.backend.colorSchemeName == "light") ProtonStyle.currentStyle = ProtonStyle.lightStyle if (Backend.colorSchemeName == "light") ProtonStyle.currentStyle = ProtonStyle.lightStyle
if (root.backend.colorSchemeName == "dark") ProtonStyle.currentStyle = ProtonStyle.darkStyle if (Backend.colorSchemeName == "dark") ProtonStyle.currentStyle = ProtonStyle.darkStyle
} }
} }

View File

@ -15,19 +15,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import Proton 4.0 import Proton
ColumnLayout { ColumnLayout {
id: root id: root
property var user property var user
property var userIndex property var userIndex
property var backend
spacing : 5 spacing : 5
@ -65,9 +64,9 @@ ColumnLayout {
} }
if (checked) { if (checked) {
if (user === backend.loginUser) { if (user === Backend.loginUser) {
var newUserObject = backend.userComponent.createObject(backend, {username: user.username, loggedIn: true, setupGuideSeen: user.setupGuideSeen}) var newUserObject = Backend.userComponent.createObject(Backend, {username: user.username, loggedIn: true, setupGuideSeen: user.setupGuideSeen})
backend.users.append( { object: newUserObject } ) Backend.users.append( { object: newUserObject } )
user.username = "" user.username = ""
user.resetLoginRequests() user.resetLoginRequests()
@ -120,7 +119,7 @@ ColumnLayout {
enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordProvided enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordProvided
onClicked: { onClicked: {
root.backend.loginUsernamePasswordError("") Backend.loginUsernamePasswordError("")
user.resetLoginRequests() user.resetLoginRequests()
} }
} }
@ -130,7 +129,7 @@ ColumnLayout {
text: "free user error" text: "free user error"
enabled: user !== undefined //&& user.isLoginRequested enabled: user !== undefined //&& user.isLoginRequested
onClicked: { onClicked: {
root.backend.loginFreeUserError() Backend.loginFreeUserError()
user.resetLoginRequests() user.resetLoginRequests()
} }
} }
@ -140,7 +139,7 @@ ColumnLayout {
text: "connection error" text: "connection error"
enabled: user !== undefined //&& user.isLoginRequested enabled: user !== undefined //&& user.isLoginRequested
onClicked: { onClicked: {
root.backend.loginConnectionError("") Backend.loginConnectionError("")
user.resetLoginRequests() user.resetLoginRequests()
} }
} }
@ -163,7 +162,7 @@ ColumnLayout {
enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordRequested enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordRequested
onClicked: { onClicked: {
root.backend.login2FARequested(user.username) Backend.login2FARequested(user.username)
user.isLogin2FARequested = true user.isLogin2FARequested = true
} }
} }
@ -174,7 +173,7 @@ ColumnLayout {
enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided) enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided)
onClicked: { onClicked: {
root.backend.login2FAError("") Backend.login2FAError("")
user.isLogin2FAProvided = false user.isLogin2FAProvided = false
} }
} }
@ -185,7 +184,7 @@ ColumnLayout {
enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided) enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided)
onClicked: { onClicked: {
root.backend.login2FAErrorAbort("") Backend.login2FAErrorAbort("")
user.resetLoginRequests() user.resetLoginRequests()
} }
} }
@ -208,7 +207,7 @@ ColumnLayout {
enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2PasswordRequested && !(user.isLogin2FARequested && !user.isLogin2FAProvided) enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2PasswordRequested && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
onClicked: { onClicked: {
root.backend.login2PasswordRequested("") Backend.login2PasswordRequested("")
user.isLogin2PasswordRequested = true user.isLogin2PasswordRequested = true
} }
} }
@ -219,7 +218,7 @@ ColumnLayout {
enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided) enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
onClicked: { onClicked: {
root.backend.login2PasswordError("") Backend.login2PasswordError("")
user.isLogin2PasswordProvided = false user.isLogin2PasswordProvided = false
} }
@ -231,7 +230,7 @@ ColumnLayout {
enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided) enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided)
onClicked: { onClicked: {
root.backend.login2PasswordErrorAbort("") Backend.login2PasswordErrorAbort("")
user.resetLoginRequests() user.resetLoginRequests()
} }
} }
@ -243,7 +242,7 @@ ColumnLayout {
text: "Login Finished" text: "Login Finished"
onClicked: { onClicked: {
root.backend.loginFinished(0+loginFinishedIndex.text) Backend.loginFinished(0+loginFinishedIndex.text)
user.resetLoginRequests() user.resetLoginRequests()
} }
} }
@ -261,7 +260,7 @@ ColumnLayout {
text: "Already logged in" text: "Already logged in"
onClicked: { onClicked: {
root.backend.loginAlreadyLoggedIn(0+loginAlreadyLoggedInIndex.text) Backend.loginAlreadyLoggedIn(0+loginAlreadyLoggedInIndex.text)
user.resetLoginRequests() user.resetLoginRequests()
} }
} }

View File

@ -15,17 +15,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import Proton 4.0 import Proton
ColumnLayout { ColumnLayout {
id: root id: root
property ColorScheme colorScheme property ColorScheme colorScheme
property var backend
property alias currentIndex: usersListView.currentIndex property alias currentIndex: usersListView.currentIndex
ListView { ListView {
@ -33,7 +32,7 @@ ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: 200 Layout.preferredWidth: 200
model: backend.usersTest model: Backend.usersTest
highlightFollowsCurrentItem: true highlightFollowsCurrentItem: true
delegate: Item { delegate: Item {
@ -74,16 +73,16 @@ ColumnLayout {
text: "+" text: "+"
onClicked: { onClicked: {
var newUserObject = backend.userComponent.createObject(backend) var newUserObject = Backend.userComponent.createObject(Backend)
newUserObject.username = backend.loginUser.username.length > 0 ? backend.loginUser.username : "test@protonmail.com" newUserObject.username = Backend.loginUser.username.length > 0 ? Backend.loginUser.username : "test@protonmail.com"
newUserObject.loggedIn = true newUserObject.loggedIn = true
newUserObject.setupGuideSeen = true // backend.loginUser.setupGuideSeen newUserObject.setupGuideSeen = true // Backend.loginUser.setupGuideSeen
backend.loginUser.username = "" Backend.loginUser.username = ""
backend.loginUser.loggedIn = false Backend.loginUser.loggedIn = false
backend.loginUser.setupGuideSeen = false Backend.loginUser.setupGuideSeen = false
backend.users.append( { object: newUserObject } ) Backend.users.append( { object: newUserObject } )
} }
} }
Button { Button {
@ -93,8 +92,8 @@ ColumnLayout {
enabled: usersListView.currentIndex != 0 enabled: usersListView.currentIndex != 0
onClicked: { onClicked: {
// var userObject = backend.users.get(usersListView.currentIndex - 1) // var userObject = Backend.users.get(usersListView.currentIndex - 1)
backend.users.remove(usersListView.currentIndex - 1) Backend.users.remove(usersListView.currentIndex - 1)
// userObject.deleteLater() // userObject.deleteLater()
} }
} }

View File

@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml.Models 2.12 import QtQml.Models
ListModel { ListModel {
// overriding get method to ignore any role and return directly object itself // overriding get method to ignore any role and return directly object itself

View File

@ -15,22 +15,22 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQml.Models 2.12 import QtQml.Models
import Qt.labs.platform 1.1 import Qt.labs.platform
import Proton 4.0 import Proton
import "./BridgeTest" import "./BridgeTest"
import BridgePreview 1.0 import BridgePreview
import Notifications 1.0 import Notifications
Window { Window {
id: root id: root

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
SettingsView { SettingsView {
id: root id: root
@ -122,7 +122,7 @@ SettingsView {
text: qsTr("View logs") text: qsTr("View logs")
secondary: true secondary: true
colorScheme: root.colorScheme colorScheme: root.colorScheme
onClicked: Qt.openUrlExternally(root.backend.logsPath) onClicked: Qt.openUrlExternally(Backend.logsPath)
} }
} }
@ -137,7 +137,7 @@ SettingsView {
font.weight: ProtonStyle.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: ProtonStyle.caption_font_size font.pixelSize: ProtonStyle.caption_font_size
font.letterSpacing: ProtonStyle.caption_letter_spacing font.letterSpacing: ProtonStyle.caption_letter_spacing
// No way to set lineHeight: Style.caption_line_height // No way to set lineHeight: ProtonStyle.caption_line_height
selectionColor: root.colorScheme.interaction_norm selectionColor: root.colorScheme.interaction_norm
selectedTextColor: root.colorScheme.text_invert selectedTextColor: root.colorScheme.text_invert
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
@ -161,13 +161,16 @@ SettingsView {
submit() submit()
} }
Connections {target: root.backend; onReportBugFinished: sendButton.loading = false } Connections {
target: Backend
function onReportBugFinished() { sendButton.loading = false }
}
} }
function setDefaultValue() { function setDefaultValue() {
description.text = "" description.text = ""
address.text = root.selectedAddress address.text = root.selectedAddress
emailClient.text = root.backend.currentEmailClient emailClient.text = Backend.currentEmailClient
includeLogs.checked = true includeLogs.checked = true
} }
@ -178,7 +181,7 @@ SettingsView {
function submit() { function submit() {
sendButton.loading = true sendButton.loading = true
root.backend.reportBug( Backend.reportBug(
description.text, description.text,
address.text, address.text,
emailClient.text, emailClient.text,

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import Proton 4.0 import Proton
Rectangle { Rectangle {
id: root id: root

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import Proton 4.0 import Proton
Item { Item {
id: root id: root
@ -61,7 +61,7 @@ Item {
} }
ColorImage { ColorImage {
source: "icons/ic-copy.svg" source: "/qml/icons/ic-copy.svg"
color: root.colorScheme.text_norm color: root.colorScheme.text_norm
height: root.colorScheme.body_font_size height: root.colorScheme.body_font_size
sourceSize.height: root.colorScheme.body_font_size sourceSize.height: root.colorScheme.body_font_size

View File

@ -15,18 +15,17 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
Item { Item {
id: root id: root
property ColorScheme colorScheme property ColorScheme colorScheme
property var backend
property var notifications property var notifications
signal showSetupGuide(var user, string address) signal showSetupGuide(var user, string address)
@ -66,7 +65,6 @@ Item {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
colorScheme: leftBar.colorScheme colorScheme: leftBar.colorScheme
backend: root.backend
notifications: root.notifications notifications: root.notifications
notificationWhitelist: Notifications.Group.Connection | Notifications.Group.ForceUpdate notificationWhitelist: Notifications.Group.Connection | Notifications.Group.ForceUpdate
@ -93,7 +91,7 @@ Item {
horizontalPadding: 0 horizontalPadding: 0
icon.source: "./icons/ic-question-circle.svg" icon.source: "/qml/icons/ic-question-circle.svg"
onClicked: rightContent.showHelpView() onClicked: rightContent.showHelpView()
} }
@ -113,7 +111,7 @@ Item {
horizontalPadding: 0 horizontalPadding: 0
icon.source: "./icons/ic-cog-wheel.svg" icon.source: "/qml/icons/ic-cog-wheel.svg"
onClicked: rightContent.showGeneralSettings() onClicked: rightContent.showGeneralSettings()
} }
@ -162,7 +160,7 @@ Item {
radius: ProtonStyle.account_row_radius radius: ProtonStyle.account_row_radius
} }
model: root.backend.users model: Backend.users
delegate: Item { delegate: Item {
width: leftBar.width - 2*accounts._leftRightMargins width: leftBar.width - 2*accounts._leftRightMargins
implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin
@ -178,13 +176,13 @@ Item {
anchors.rightMargin: 12 anchors.rightMargin: 12
colorScheme: leftBar.colorScheme colorScheme: leftBar.colorScheme
user: root.backend.users.get(index) user: Backend.users.get(index)
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
var user = root.backend.users.get(index) var user = Backend.users.get(index)
accounts.currentIndex = index accounts.currentIndex = index
if (!user) return if (!user) return
if (user.loggedIn) { if (user.loggedIn) {
@ -227,7 +225,7 @@ Item {
horizontalPadding: 0 horizontalPadding: 0
icon.source: "./icons/ic-plus.svg" icon.source: "/qml/icons/ic-plus.svg"
onClicked: { onClicked: {
signIn.username = "" signIn.username = ""
@ -250,12 +248,11 @@ Item {
AccountView { // 0 AccountView { // 0
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
notifications: root.notifications notifications: root.notifications
user: { user: {
if (accounts.currentIndex < 0) return undefined if (accounts.currentIndex < 0) return undefined
if (root.backend.users.count == 0) return undefined if (Backend.users.count == 0) return undefined
return root.backend.users.get(accounts.currentIndex) return Backend.users.get(accounts.currentIndex)
} }
onShowSignIn: { onShowSignIn: {
signIn.username = this.user.username signIn.username = this.user.username
@ -280,7 +277,7 @@ Item {
signIn.abort() signIn.abort()
rightContent.showAccount() rightContent.showAccount()
} }
icon.source: "icons/ic-arrow-left.svg" icon.source: "/qml/icons/ic-arrow-left.svg"
secondary: true secondary: true
horizontalPadding: 8 horizontalPadding: 8
} }
@ -296,13 +293,11 @@ Item {
Layout.fillHeight: true Layout.fillHeight: true
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
} }
} }
GeneralSettings { // 2 GeneralSettings { // 2
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
notifications: root.notifications notifications: root.notifications
onBack: { onBack: {
@ -312,7 +307,6 @@ Item {
KeychainSettings { // 3 KeychainSettings { // 3
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
onBack: { onBack: {
rightContent.showGeneralSettings() rightContent.showGeneralSettings()
@ -321,7 +315,6 @@ Item {
PortSettings { // 4 PortSettings { // 4
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
onBack: { onBack: {
rightContent.showGeneralSettings() rightContent.showGeneralSettings()
@ -330,7 +323,6 @@ Item {
SMTPSettings { // 5 SMTPSettings { // 5
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
onBack: { onBack: {
rightContent.showGeneralSettings() rightContent.showGeneralSettings()
@ -339,7 +331,6 @@ Item {
LocalCacheSettings { // 6 LocalCacheSettings { // 6
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
notifications: root.notifications notifications: root.notifications
onBack: { onBack: {
@ -349,7 +340,6 @@ Item {
HelpView { // 7 HelpView { // 7
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
onBack: { onBack: {
rightContent.showAccount() rightContent.showAccount()
@ -358,11 +348,10 @@ Item {
BugReportView { // 8 BugReportView { // 8
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
selectedAddress: { selectedAddress: {
if (accounts.currentIndex < 0) return "" if (accounts.currentIndex < 0) return ""
if (root.backend.users.count == 0) return "" if (Backend.users.count == 0) return ""
var user = root.backend.users.get(accounts.currentIndex) var user = Backend.users.get(accounts.currentIndex)
if (!user) return "" if (!user) return ""
return user.addresses[0] return user.addresses[0]
} }
@ -389,10 +378,10 @@ Item {
function showBugReport () { rightContent.currentIndex = 8 } function showBugReport () { rightContent.currentIndex = 8 }
Connections { Connections {
target: root.backend target: Backend
onLoginFinished: rightContent.showAccount(index) function onLoginFinished(index) { rightContent.showAccount(index) }
onLoginAlreadyLoggedIn: rightContent.showAccount(index) function onLoginAlreadyLoggedIn(index) { rightContent.showAccount(index) }
} }
} }
} }

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import "." import "."
import "./Proton" import "./Proton"

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQuick.Controls.impl 2.13 import QtQuick.Controls.impl
import Proton 4.0 import Proton
SettingsView { SettingsView {
id: root id: root
@ -43,8 +43,8 @@ SettingsView {
text: qsTr("Automatic updates") text: qsTr("Automatic updates")
description: qsTr("Bridge will automatically update in the background.") description: qsTr("Bridge will automatically update in the background.")
type: SettingsItem.Toggle type: SettingsItem.Toggle
checked: root.backend.isAutomaticUpdateOn checked: Backend.isAutomaticUpdateOn
onClicked: root.backend.toggleAutomaticUpdate(!autoUpdate.checked) onClicked: Backend.toggleAutomaticUpdate(!autoUpdate.checked)
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -55,14 +55,14 @@ SettingsView {
text: qsTr("Open on startup") text: qsTr("Open on startup")
description: qsTr("Bridge will open upon startup.") description: qsTr("Bridge will open upon startup.")
type: SettingsItem.Toggle type: SettingsItem.Toggle
checked: root.backend.isAutostartOn checked: Backend.isAutostartOn
onClicked: { onClicked: {
autostart.loading = true autostart.loading = true
root.backend.toggleAutostart(!autostart.checked) Backend.toggleAutostart(!autostart.checked)
} }
Connections{ Connections{
target: root.backend target: Backend
onToggleAutostartFinished: { function onToggleAutostartFinished() {
autostart.loading = false autostart.loading = false
} }
} }
@ -76,12 +76,12 @@ SettingsView {
text: qsTr("Beta access") text: qsTr("Beta access")
description: qsTr("Be among the first to try new features.") description: qsTr("Be among the first to try new features.")
type: SettingsItem.Toggle type: SettingsItem.Toggle
checked: root.backend.isBetaEnabled checked: Backend.isBetaEnabled
onClicked: { onClicked: {
if (!beta.checked) { if (!beta.checked) {
root.notifications.askEnableBeta() root.notifications.askEnableBeta()
} else { } else {
root.backend.toggleBeta(false) Backend.toggleBeta(false)
} }
} }
@ -92,7 +92,7 @@ SettingsView {
ColorImage { ColorImage {
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
source: root._isAdvancedShown ? "icons/ic-chevron-up.svg" : "icons/ic-chevron-down.svg" source: root._isAdvancedShown ? "/qml/icons/ic-chevron-up.svg" : "/qml/icons/ic-chevron-down.svg"
color: root.colorScheme.interaction_norm color: root.colorScheme.interaction_norm
height: root.colorScheme.body_font_size height: root.colorScheme.body_font_size
sourceSize.height: root.colorScheme.body_font_size sourceSize.height: root.colorScheme.body_font_size
@ -118,13 +118,13 @@ SettingsView {
SettingsItem { SettingsItem {
id: keychains id: keychains
visible: root._isAdvancedShown && root.backend.availableKeychain.length > 1 visible: root._isAdvancedShown && Backend.availableKeychain.length > 1
colorScheme: root.colorScheme colorScheme: root.colorScheme
text: qsTr("Change keychain") text: qsTr("Change keychain")
description: qsTr("Change which keychain Bridge uses as default") description: qsTr("Change which keychain Bridge uses as default")
actionText: qsTr("Change") actionText: qsTr("Change")
type: SettingsItem.Button type: SettingsItem.Button
checked: root.backend.isDoHEnabled checked: Backend.isDoHEnabled
onClicked: root.parent.showKeychainSettings() onClicked: root.parent.showKeychainSettings()
Layout.fillWidth: true Layout.fillWidth: true
@ -137,8 +137,8 @@ SettingsView {
text: qsTr("Alternative routing") text: qsTr("Alternative routing")
description: qsTr("If Protons servers are blocked in your location, alternative network routing will be used to reach Proton.") description: qsTr("If Protons servers are blocked in your location, alternative network routing will be used to reach Proton.")
type: SettingsItem.Toggle type: SettingsItem.Toggle
checked: root.backend.isDoHEnabled checked: Backend.isDoHEnabled
onClicked: root.backend.toggleDoH(!doh.checked) onClicked: Backend.toggleDoH(!doh.checked)
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -150,8 +150,8 @@ SettingsView {
text: qsTr("Dark mode") text: qsTr("Dark mode")
description: qsTr("Choose dark color theme.") description: qsTr("Choose dark color theme.")
type: SettingsItem.Toggle type: SettingsItem.Toggle
checked: root.backend.colorSchemeName == "dark" checked: Backend.colorSchemeName == "dark"
onClicked: root.backend.changeColorScheme( darkMode.checked ? "light" : "dark") onClicked: Backend.changeColorScheme( darkMode.checked ? "light" : "dark")
Layout.fillWidth: true Layout.fillWidth: true
} }

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
SettingsView { SettingsView {
id: root id: root
@ -38,7 +38,7 @@ SettingsView {
colorScheme: root.colorScheme colorScheme: root.colorScheme
text: qsTr("Installation and setup") text: qsTr("Installation and setup")
actionText: qsTr("Go to help topics") actionText: qsTr("Go to help topics")
actionIcon: "./icons/ic-external-link.svg" actionIcon: "/qml/icons/ic-external-link.svg"
description: qsTr("Get help setting up your client with our instructions and FAQs.") description: qsTr("Get help setting up your client with our instructions and FAQs.")
type: SettingsItem.PrimaryButton type: SettingsItem.PrimaryButton
onClicked: {Qt.openUrlExternally("https://protonmail.com/support/categories/bridge/")} onClicked: {Qt.openUrlExternally("https://protonmail.com/support/categories/bridge/")}
@ -55,10 +55,13 @@ SettingsView {
type: SettingsItem.Button type: SettingsItem.Button
onClicked: { onClicked: {
checkUpdates.loading = true checkUpdates.loading = true
root.backend.checkUpdates() Backend.checkUpdates()
} }
Connections {target: root.backend; onCheckUpdatesFinished: checkUpdates.loading = false} Connections {
target: Backend
function onCheckUpdatesFinished() { checkUpdates.loading = false }
}
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -70,7 +73,7 @@ SettingsView {
actionText: qsTr("View logs") actionText: qsTr("View logs")
description: qsTr("Open and review logs to troubleshoot.") description: qsTr("Open and review logs to troubleshoot.")
type: SettingsItem.Button type: SettingsItem.Button
onClicked: Qt.openUrlExternally(root.backend.logsPath) onClicked: Qt.openUrlExternally(Backend.logsPath)
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -83,7 +86,7 @@ SettingsView {
description: qsTr("Something not working as expected? Let us know.") description: qsTr("Something not working as expected? Let us know.")
type: SettingsItem.Button type: SettingsItem.Button
onClicked: { onClicked: {
root.backend.updateCurrentMailClient() Backend.updateCurrentMailClient()
root.parent.showBugReport() root.parent.showBugReport()
} }
@ -106,11 +109,11 @@ SettingsView {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: qsTr("Proton Mail Bridge v%1<br>© 2021 Proton AG<br>%2 %3<br>%4"). text: qsTr("Proton Mail Bridge v%1<br>© 2021 Proton AG<br>%2 %3<br>%4").
arg(root.backend.version). arg(Backend.version).
arg(link(root.backend.licensePath, qsTr("License"))). arg(link(Backend.licensePath, qsTr("License"))).
arg(link(root.backend.dependencyLicensesLink, qsTr("Dependencies"))). arg(link(Backend.dependencyLicensesLink, qsTr("Dependencies"))).
arg(link(root.backend.releaseNotesLink, qsTr("Release notes"))) arg(link(Backend.releaseNotesLink, qsTr("Release notes")))
onLinkActivated: Qt.openUrlExternally(link) onLinkActivated: function(link) { Qt.openUrlExternally(link) }
} }
} }

View File

@ -15,19 +15,19 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQuick.Controls.impl 2.13 import QtQuick.Controls.impl
import Proton 4.0 import Proton
SettingsView { SettingsView {
id: root id: root
fillHeight: false fillHeight: false
property bool _valuesChanged: keychainSelection.checkedButton && keychainSelection.checkedButton.text != root.backend.currentKeychain property bool _valuesChanged: keychainSelection.checkedButton && keychainSelection.checkedButton.text != Backend.currentKeychain
Label { Label {
colorScheme: root.colorScheme colorScheme: root.colorScheme
@ -51,7 +51,7 @@ SettingsView {
ButtonGroup{ id: keychainSelection } ButtonGroup{ id: keychainSelection }
Repeater { Repeater {
model: root.backend.availableKeychain model: Backend.availableKeychain
RadioButton { RadioButton {
colorScheme: root.colorScheme colorScheme: root.colorScheme
@ -77,7 +77,7 @@ SettingsView {
text: qsTr("Save and restart") text: qsTr("Save and restart")
enabled: root._valuesChanged enabled: root._valuesChanged
onClicked: { onClicked: {
root.backend.changeKeychain(keychainSelection.checkedButton.text) Backend.changeKeychain(keychainSelection.checkedButton.text)
} }
} }
@ -89,9 +89,9 @@ SettingsView {
} }
Connections { Connections {
target: root.backend target: Backend
onChangeKeychainFinished: { function onChangeKeychainFinished() {
submitButton.loading = false submitButton.loading = false
root.back() root.back()
} }
@ -105,7 +105,7 @@ SettingsView {
function setDefaultValues(){ function setDefaultValues(){
for (var bi in keychainSelection.buttons){ for (var bi in keychainSelection.buttons){
var button = keychainSelection.buttons[bi] var button = keychainSelection.buttons[bi]
if (button.text == root.backend.currentKeychain) { if (button.text == Backend.currentKeychain) {
button.checked = true button.checked = true
break; break;
} }

View File

@ -15,13 +15,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQuick.Controls.impl 2.13 import QtQuick.Controls.impl
import QtQuick.Dialogs 1.1 import QtQuick.Dialogs
import Proton 4.0 import Proton
SettingsView { SettingsView {
id: root id: root
@ -64,7 +64,7 @@ SettingsView {
colorScheme: root.colorScheme colorScheme: root.colorScheme
text: qsTr("Current cache location") text: qsTr("Current cache location")
actionText: qsTr("Change location") actionText: qsTr("Change location")
description: root.backend.goos === "windows" ? description: Backend.goos === "windows" ?
root._diskCachePath.toString().replace("file:///", "").replace(new RegExp("/", 'g'), "\\") + "\\" : root._diskCachePath.toString().replace("file:///", "").replace(new RegExp("/", 'g'), "\\") + "\\" :
root._diskCachePath.toString().replace("file://", "") + "/" root._diskCachePath.toString().replace("file://", "") + "/"
descriptionWrap: Text.WrapAnywhere descriptionWrap: Text.WrapAnywhere
@ -76,13 +76,12 @@ SettingsView {
Layout.fillWidth: true Layout.fillWidth: true
FileDialog { FolderDialog {
id: pathDialog id: pathDialog
title: qsTr("Select cache location") title: qsTr("Select cache location")
folder: root._diskCachePath currentFolder: root._diskCachePath
onAccepted: root._diskCachePath = pathDialog.fileUrl onAccepted: root._diskCachePath = pathDialog.fileUrl
selectFolder: true }
}
} }
RowLayout { RowLayout {
@ -93,8 +92,8 @@ SettingsView {
colorScheme: root.colorScheme colorScheme: root.colorScheme
text: qsTr("Save and restart") text: qsTr("Save and restart")
enabled: ( enabled: (
root.backend.diskCachePath != root._diskCachePath || Backend.diskCachePath != root._diskCachePath ||
root.backend.isDiskCacheEnabled != root._diskCacheEnabled Backend.isDiskCacheEnabled != root._diskCacheEnabled
) )
onClicked: { onClicked: {
root.submit() root.submit()
@ -109,9 +108,9 @@ SettingsView {
} }
Connections { Connections {
target: root.backend target: Backend
onChangeLocalCacheFinished: { function onChangeLocalCacheFinished() {
submitButton.loading = false submitButton.loading = false
root.setDefaultValues() root.setDefaultValues()
} }
@ -123,24 +122,24 @@ SettingsView {
} }
function submit(){ function submit(){
if (!root._diskCacheEnabled && root.backend.isDiskCacheEnabled) { if (!root._diskCacheEnabled && Backend.isDiskCacheEnabled) {
root.notifications.askDisableLocalCache() root.notifications.askDisableLocalCache()
return return
} }
if (root._diskCacheEnabled && !root.backend.isDiskCacheEnabled) { if (root._diskCacheEnabled && !Backend.isDiskCacheEnabled) {
root.notifications.askEnableLocalCache(root._diskCachePath) root.notifications.askEnableLocalCache(root._diskCachePath)
return return
} }
// Not asking, only changing path // Not asking, only changing path
submitButton.loading = true submitButton.loading = true
root.backend.changeLocalCache(root.backend.isDiskCacheEnabled, root._diskCachePath) Backend.changeLocalCache(Backend.isDiskCacheEnabled, root._diskCachePath)
} }
function setDefaultValues(){ function setDefaultValues(){
root._diskCacheEnabled = root.backend.isDiskCacheEnabled root._diskCacheEnabled = Backend.isDiskCacheEnabled
root._diskCachePath = root.backend.diskCachePath root._diskCachePath = Backend.diskCachePath
} }
onVisibleChanged: { onVisibleChanged: {

View File

@ -15,15 +15,14 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
import CppBackend 1.0
import "tests" import "tests"
@ -40,8 +39,6 @@ ApplicationWindow {
colorScheme: ProtonStyle.currentStyle colorScheme: ProtonStyle.currentStyle
property var backend
property var notifications property var notifications
// This is needed because on MacOS if first window shown is not transparent - // This is needed because on MacOS if first window shown is not transparent -
@ -52,11 +49,11 @@ ApplicationWindow {
// show Setup Guide on every new user // show Setup Guide on every new user
Connections { Connections {
target: root.backend.users target: Backend.users
onRowsInserted: { function onRowsInserted(parent, first, last) {
// considerring that users are added one-by-one // considerring that users are added one-by-one
var user = root.backend.users.get(first) var user = Backend.users.get(first)
if (!user.loggedIn) { if (!user.loggedIn) {
return return
@ -69,9 +66,9 @@ ApplicationWindow {
root.showSetup(user,user.addresses[0]) root.showSetup(user,user.addresses[0])
} }
onRowsAboutToBeRemoved: { function onRowsAboutToBeRemoved(parent, first, last) {
for (var i = first; i <= last; i++ ) { for (var i = first; i <= last; i++ ) {
var user = root.backend.users.get(i) var user = Backend.users.get(i)
if (setupGuide.user === user) { if (setupGuide.user === user) {
setupGuide.user = null setupGuide.user = null
@ -83,13 +80,13 @@ ApplicationWindow {
} }
Connections { Connections {
target: root.backend target: Backend
onShowMainWindow: { function onShowMainWindow() {
root.showAndRise() root.showAndRise()
} }
onLoginFinished: { function onLoginFinished(index) {
console.debug("Login finished", index) console.debug("Login finished", index)
} }
} }
@ -102,11 +99,11 @@ ApplicationWindow {
property bool _showSetup: false property bool _showSetup: false
currentIndex: { currentIndex: {
// show welcome when there are no users or only one non-logged-in user is present // show welcome when there are no users or only one non-logged-in user is present
if (backend.users.count === 0) { if (Backend.users.count === 0) {
return 1 return 1
} }
var u = backend.users.get(0) var u = Backend.users.get(0)
if (!u) { if (!u) {
console.trace() console.trace()
@ -114,7 +111,7 @@ ApplicationWindow {
return 1 return 1
} }
if (backend.users.count === 1 && u.loggedIn === false) { if (Backend.users.count === 1 && u.loggedIn === false) {
return 1 return 1
} }
@ -128,7 +125,6 @@ ApplicationWindow {
ContentWrapper { // 0 ContentWrapper { // 0
id: contentWrapper id: contentWrapper
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
notifications: root.notifications notifications: root.notifications
Layout.fillHeight: true Layout.fillHeight: true
@ -141,7 +137,6 @@ ApplicationWindow {
WelcomeGuide { // 1 WelcomeGuide { // 1
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
@ -150,7 +145,6 @@ ApplicationWindow {
SetupGuide { // 2 SetupGuide { // 2
id: setupGuide id: setupGuide
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
@ -160,8 +154,8 @@ ApplicationWindow {
} }
onFinished: { onFinished: {
// TODO: Do not close window. Trigger backend to check that // TODO: Do not close window. Trigger Backend to check that
// there is a successfully connected client. Then backend // there is a successfully connected client. Then Backend
// should send another signal to close the setup guide. // should send another signal to close the setup guide.
root.showSetup(null,"") root.showSetup(null,"")
} }
@ -173,13 +167,11 @@ ApplicationWindow {
colorScheme: root.colorScheme colorScheme: root.colorScheme
notifications: root.notifications notifications: root.notifications
mainWindow: root mainWindow: root
backend: root.backend
} }
SplashScreen { SplashScreen {
id: splashScreen id: splashScreen
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
} }
function showLocalCacheSettings() { contentWrapper.showLocalCacheSettings() } function showLocalCacheSettings() { contentWrapper.showLocalCacheSettings() }

View File

@ -15,13 +15,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.12 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
Dialog { Dialog {
id: root id: root
@ -56,12 +56,12 @@ Dialog {
switch (root.notification.type) { switch (root.notification.type) {
case Notification.NotificationType.Info: case Notification.NotificationType.Info:
return "./icons/ic-info.svg" return "/qml/icons/ic-info.svg"
case Notification.NotificationType.Success: case Notification.NotificationType.Success:
return "./icons/ic-success.svg" return "/qml/icons/ic-success.svg"
case Notification.NotificationType.Warning: case Notification.NotificationType.Warning:
case Notification.NotificationType.Danger: case Notification.NotificationType.Danger:
return "./icons/ic-alert.svg" return "/qml/icons/ic-alert.svg"
} }
} }
} }
@ -84,7 +84,7 @@ Dialog {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
type: Label.LabelType.Body type: Label.LabelType.Body
onLinkActivated: Qt.openUrlExternally(link) onLinkActivated: function(link) { Qt.openUrlExternally(link) }
} }
Item { Item {

View File

@ -15,17 +15,16 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.12 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
Item { Item {
id: root id: root
property var backend
property ColorScheme colorScheme property ColorScheme colorScheme
property var notifications property var notifications
@ -55,8 +54,8 @@ Item {
id:autoUpdate id:autoUpdate
colorScheme: root.colorScheme colorScheme: root.colorScheme
text: qsTr("Update automatically in the future") text: qsTr("Update automatically in the future")
checked: root.backend.isAutomaticUpdateOn checked: Backend.isAutomaticUpdateOn
onClicked: root.backend.toggleAutomaticUpdate(autoUpdate.checked) onClicked: Backend.toggleAutomaticUpdate(autoUpdate.checked)
} }
} }

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick.Controls 2.12 import QtQuick.Controls
QtObject { QtObject {
id: root id: root

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQml.Models 2.12 import QtQml.Models
// contains notifications that satisfy black- and whitelist and are sorted in time-occurred order // contains notifications that satisfy black- and whitelist and are sorted in time-occurred order
ListModel { ListModel {

View File

@ -15,16 +15,14 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import Qt.labs.platform 1.1 import Qt.labs.platform
import QtQuick.Controls 2.12 import QtQuick.Controls
import ".." import ".."
QtObject { QtObject {
id: root id: root
property var backend
property MainWindow frontendMain property MainWindow frontendMain
property StatusWindow frontendStatus property StatusWindow frontendStatus
property SystemTrayIcon frontendTray property SystemTrayIcon frontendTray
@ -89,12 +87,12 @@ QtObject {
group: Notifications.Group.Connection group: Notifications.Group.Connection
Connections { Connections {
target: root.backend target: Backend
onInternetOff: { function onInternetOff() {
root.noInternet.active = true root.noInternet.active = true
} }
onInternetOn: { function onInternetOn() {
root.noInternet.active = false root.noInternet.active = false
} }
} }
@ -106,7 +104,7 @@ QtObject {
description: { description: {
var descr = qsTr("A new version of Proton Mail Bridge is available.") var descr = qsTr("A new version of Proton Mail Bridge is available.")
var text = qsTr("See what's changed.") var text = qsTr("See what's changed.")
var link = root.backend.releaseNotesLink var link = Backend.releaseNotesLink
return `${descr} <a href="${link}">${text}</a>` return `${descr} <a href="${link}">${text}</a>`
} }
brief: qsTr("Update available.") brief: qsTr("Update available.")
@ -115,8 +113,8 @@ QtObject {
group: Notifications.Group.Update | Notifications.Group.Dialogs group: Notifications.Group.Update | Notifications.Group.Dialogs
Connections { Connections {
target: root.backend target: Backend
onUpdateManualReady: { function onUpdateManualReady(version) {
root.updateManualReady.data = { version: version } root.updateManualReady.data = { version: version }
root.updateManualReady.active = true root.updateManualReady.active = true
} }
@ -127,7 +125,7 @@ QtObject {
text: qsTr("Install update") text: qsTr("Install update")
onTriggered: { onTriggered: {
root.backend.installUpdate() Backend.installUpdate()
root.updateManualReady.active = false root.updateManualReady.active = false
} }
}, },
@ -135,7 +133,7 @@ QtObject {
text: qsTr("Update manually") text: qsTr("Update manually")
onTriggered: { onTriggered: {
Qt.openUrlExternally(root.backend.landingPageLink) Qt.openUrlExternally(Backend.landingPageLink)
root.updateManualReady.active = false root.updateManualReady.active = false
} }
}, },
@ -157,8 +155,8 @@ QtObject {
group: Notifications.Group.Update group: Notifications.Group.Update
Connections { Connections {
target: root.backend target: Backend
onUpdateManualRestartNeeded: { function onUpdateManualRestartNeeded() {
root.updateManualRestartNeeded.active = true root.updateManualRestartNeeded.active = true
} }
} }
@ -167,7 +165,7 @@ QtObject {
text: qsTr("Restart Bridge") text: qsTr("Restart Bridge")
onTriggered: { onTriggered: {
root.backend.restart() Backend.restart()
root.updateManualRestartNeeded.active = false root.updateManualRestartNeeded.active = false
} }
} }
@ -182,8 +180,8 @@ QtObject {
group: Notifications.Group.Update group: Notifications.Group.Update
Connections { Connections {
target: root.backend target: Backend
onUpdateManualError: { function onUpdateManualError() {
root.updateManualError.active = true root.updateManualError.active = true
} }
} }
@ -193,7 +191,7 @@ QtObject {
text: qsTr("Update manually") text: qsTr("Update manually")
onTriggered: { onTriggered: {
Qt.openUrlExternally(root.backend.landingPageLink) Qt.openUrlExternally(Backend.landingPageLink)
root.updateManualError.active = false root.updateManualError.active = false
root.backend.quit() root.backend.quit()
} }
@ -217,9 +215,9 @@ QtObject {
group: Notifications.Group.Update | Notifications.Group.ForceUpdate | Notifications.Group.Dialogs group: Notifications.Group.Update | Notifications.Group.ForceUpdate | Notifications.Group.Dialogs
Connections { Connections {
target: root.backend target: Backend
onUpdateForce: { function onUpdateForce(version) {
root.updateForce.data = { version: version } root.updateForce.data = { version: version }
root.updateForce.active = true root.updateForce.active = true
} }
@ -230,7 +228,7 @@ QtObject {
text: qsTr("Install update") text: qsTr("Install update")
onTriggered: { onTriggered: {
root.backend.installUpdate() Backend.installUpdate()
root.updateForce.active = false root.updateForce.active = false
} }
}, },
@ -238,7 +236,7 @@ QtObject {
text: qsTr("Update manually") text: qsTr("Update manually")
onTriggered: { onTriggered: {
Qt.openUrlExternally(root.backend.landingPageLink) Qt.openUrlExternally(Backend.landingPageLink)
root.updateForce.active = false root.updateForce.active = false
} }
}, },
@ -246,7 +244,7 @@ QtObject {
text: qsTr("Quit Bridge") text: qsTr("Quit Bridge")
onTriggered: { onTriggered: {
root.backend.quit() Backend.quit()
root.updateForce.active = false root.updateForce.active = false
} }
} }
@ -262,9 +260,9 @@ QtObject {
group: Notifications.Group.Update | Notifications.Group.Dialogs group: Notifications.Group.Update | Notifications.Group.Dialogs
Connections { Connections {
target: root.backend target: Backend
onUpdateForceError: { function onUpdateForceError() {
root.updateForceError.active = true root.updateForceError.active = true
} }
} }
@ -274,7 +272,7 @@ QtObject {
text: qsTr("Update manually") text: qsTr("Update manually")
onTriggered: { onTriggered: {
Qt.openUrlExternally(root.backend.landingPageLink) Qt.openUrlExternally(Backend.landingPageLink)
root.updateForceError.active = false root.updateForceError.active = false
} }
}, },
@ -282,7 +280,7 @@ QtObject {
text: qsTr("Quit Bridge") text: qsTr("Quit Bridge")
onTriggered: { onTriggered: {
root.backend.quit() Backend.quit()
root.updateForceError.active = false root.updateForceError.active = false
} }
} }
@ -297,8 +295,8 @@ QtObject {
group: Notifications.Group.Update group: Notifications.Group.Update
Connections { Connections {
target: root.backend target: Backend
onUpdateSilentRestartNeeded: { function onUpdateSilentRestartNeeded() {
root.updateSilentRestartNeeded.active = true root.updateSilentRestartNeeded.active = true
} }
} }
@ -307,7 +305,7 @@ QtObject {
text: qsTr("Restart Bridge") text: qsTr("Restart Bridge")
onTriggered: { onTriggered: {
root.backend.restart() Backend.restart()
root.updateSilentRestartNeeded.active = false root.updateSilentRestartNeeded.active = false
} }
} }
@ -321,8 +319,8 @@ QtObject {
group: Notifications.Group.Update group: Notifications.Group.Update
Connections { Connections {
target: root.backend target: Backend
onUpdateSilentError: { function onUpdateSilentError() {
root.updateSilentError.active = true root.updateSilentError.active = true
} }
} }
@ -331,7 +329,7 @@ QtObject {
text: qsTr("Update manually") text: qsTr("Update manually")
onTriggered: { onTriggered: {
Qt.openUrlExternally(root.backend.landingPageLink) Qt.openUrlExternally(Backend.landingPageLink)
root.updateSilentError.active = false root.updateSilentError.active = false
} }
} }
@ -345,8 +343,8 @@ QtObject {
group: Notifications.Group.Update group: Notifications.Group.Update
Connections { Connections {
target: root.backend target: Backend
onUpdateIsLatestVersion: { function onUpdateIsLatestVersion() {
root.updateIsLatestVersion.active = true root.updateIsLatestVersion.active = true
} }
} }
@ -370,7 +368,7 @@ QtObject {
Connections { Connections {
target: root target: root
onAskEnableBeta: { function onAskEnableBeta() {
root.enableBeta.active = true root.enableBeta.active = true
} }
} }
@ -379,7 +377,7 @@ QtObject {
Action { Action {
text: qsTr("Enable") text: qsTr("Enable")
onTriggered: { onTriggered: {
root.backend.toggleBeta(true) Backend.toggleBeta(true)
root.enableBeta.active = false root.enableBeta.active = false
} }
}, },
@ -402,8 +400,8 @@ QtObject {
group: Notifications.Group.Configuration group: Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onLoginConnectionError: { function onLoginConnectionError(errorMsg) {
root.loginConnectionError.active = true root.loginConnectionError.active = true
} }
} }
@ -426,8 +424,8 @@ QtObject {
group: Notifications.Group.Configuration group: Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onLoginFreeUserError: { function onLoginFreeUserError() {
root.onlyPaidUsers.active = true root.onlyPaidUsers.active = true
} }
} }
@ -450,8 +448,8 @@ QtObject {
group: Notifications.Group.Configuration group: Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onLoginAlreadyLoggedIn: { function onLoginAlreadyLoggedIn(index) {
root.alreadyLoggedIn.active = true root.alreadyLoggedIn.active = true
} }
} }
@ -475,8 +473,8 @@ QtObject {
group: Notifications.Group.Configuration group: Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onBugReportSendSuccess: { function onBugReportSendSuccess() {
root.bugReportSendSuccess.active = true root.bugReportSendSuccess.active = true
} }
} }
@ -499,8 +497,8 @@ QtObject {
group: Notifications.Group.Configuration group: Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onBugReportSendError: { function onBugReportSendError() {
root.bugReportSendError.active = true root.bugReportSendError.active = true
} }
} }
@ -523,8 +521,8 @@ QtObject {
group: Notifications.Group.Configuration | Notifications.Group.Dialogs group: Notifications.Group.Configuration | Notifications.Group.Dialogs
Connections { Connections {
target: root.backend target: Backend
onCacheUnavailable: { function onCacheUnavailable() {
root.cacheUnavailable.active = true root.cacheUnavailable.active = true
} }
} }
@ -533,7 +531,7 @@ QtObject {
Action { Action {
text: qsTr("Quit Bridge") text: qsTr("Quit Bridge")
onTriggered: { onTriggered: {
root.backend.quit() Backend.quit()
root.cacheUnavailable.active = false root.cacheUnavailable.active = false
} }
}, },
@ -556,8 +554,8 @@ QtObject {
group: Notifications.Group.Configuration | Notifications.Group.Dialogs group: Notifications.Group.Configuration | Notifications.Group.Dialogs
Connections { Connections {
target: root.backend target: Backend
onCacheCantMove: { function onCacheCantMove() {
root.cacheCantMove.active = true root.cacheCantMove.active = true
} }
} }
@ -587,8 +585,8 @@ QtObject {
group: Notifications.Group.Configuration group: Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onCacheLocationChangeSuccess: { function onCacheLocationChangeSuccess() {
console.log("notify location changed succesfully") console.log("notify location changed succesfully")
root.cacheLocationChangeSuccess.active = true root.cacheLocationChangeSuccess.active = true
} }
@ -630,8 +628,8 @@ QtObject {
group: Notifications.Group.Configuration | Notifications.Group.Dialogs group: Notifications.Group.Configuration | Notifications.Group.Dialogs
Connections { Connections {
target: root.backend target: Backend
onDiskFull: { function onDiskFull() {
root.diskFull.active = true root.diskFull.active = true
} }
} }
@ -640,7 +638,7 @@ QtObject {
Action { Action {
text: qsTr("Quit Bridge") text: qsTr("Quit Bridge")
onTriggered: { onTriggered: {
root.backend.quit() Backend.quit()
root.diskFull.active = false root.diskFull.active = false
} }
}, },
@ -658,7 +656,7 @@ QtObject {
title: qsTr("Enable split mode?") title: qsTr("Enable split mode?")
brief: title brief: title
description: qsTr("Changing between split and combined address mode will require you to delete your account(s) from your email client and begin the setup process from scratch.") description: qsTr("Changing between split and combined address mode will require you to delete your account(s) from your email client and begin the setup process from scratch.")
icon: "./icons/ic-question-circle.svg" icon: "/qml/icons/ic-question-circle.svg"
type: Notification.NotificationType.Warning type: Notification.NotificationType.Warning
group: Notifications.Group.Configuration | Notifications.Group.Dialogs group: Notifications.Group.Configuration | Notifications.Group.Dialogs
@ -666,7 +664,7 @@ QtObject {
Connections { Connections {
target: root target: root
onAskEnableSplitMode: { function onAskEnableSplitMode(user) {
root.enableSplitMode.user = user root.enableSplitMode.user = user
root.enableSplitMode.active = true root.enableSplitMode.active = true
} }
@ -674,7 +672,7 @@ QtObject {
Connections { Connections {
target: (root && root.enableSplitMode && root.enableSplitMode.user ) ? root.enableSplitMode.user : null target: (root && root.enableSplitMode && root.enableSplitMode.user ) ? root.enableSplitMode.user : null
onToggleSplitModeFinished: { function onToggleSplitModeFinished() {
root.enableSplitMode.active = false root.enableSplitMode.active = false
enableSplitMode_enable.loading = false enableSplitMode_enable.loading = false
@ -706,20 +704,20 @@ QtObject {
title: qsTr("Disable local cache?") title: qsTr("Disable local cache?")
brief: title brief: title
description: qsTr("This action will clear your local cache, including locally stored messages. Bridge will restart.") description: qsTr("This action will clear your local cache, including locally stored messages. Bridge will restart.")
icon: "./icons/ic-question-circle.svg" icon: "/qml/icons/ic-question-circle.svg"
type: Notification.NotificationType.Warning type: Notification.NotificationType.Warning
group: Notifications.Group.Configuration | Notifications.Group.Dialogs group: Notifications.Group.Configuration | Notifications.Group.Dialogs
Connections { Connections {
target: root target: root
onAskDisableLocalCache: { function onAskDisableLocalCache() {
root.disableLocalCache.active = true root.disableLocalCache.active = true
} }
} }
Connections { Connections {
target: root.backend target: Backend
onChangeLocalCacheFinished: { function onChangeLocalCacheFinished() {
root.disableLocalCache.active = false root.disableLocalCache.active = false
disableLocalCache_disable.loading = false disableLocalCache_disable.loading = false
@ -741,7 +739,7 @@ QtObject {
onTriggered: { onTriggered: {
disableLocalCache_disable.loading = true disableLocalCache_disable.loading = true
disableLocalCache_cancel.enabled = false disableLocalCache_cancel.enabled = false
root.backend.changeLocalCache(false, root.backend.diskCachePath) Backend.changeLocalCache(false, Backend.diskCachePath)
} }
} }
] ]
@ -751,7 +749,7 @@ QtObject {
title: qsTr("Enable local cache") title: qsTr("Enable local cache")
brief: title brief: title
description: qsTr("Bridge will restart.") description: qsTr("Bridge will restart.")
icon: "./icons/ic-question-circle.svg" icon: "/qml/icons/ic-question-circle.svg"
type: Notification.NotificationType.Warning type: Notification.NotificationType.Warning
group: Notifications.Group.Configuration | Notifications.Group.Dialogs group: Notifications.Group.Configuration | Notifications.Group.Dialogs
@ -759,15 +757,15 @@ QtObject {
Connections { Connections {
target: root target: root
onAskEnableLocalCache: { function onAskEnableLocalCache(path) {
root.enableLocalCache.active = true root.enableLocalCache.active = true
root.enableLocalCache.path = path root.enableLocalCache.path = path
} }
} }
Connections { Connections {
target: root.backend target: Backend
onChangeLocalCacheFinished: { function onChangeLocalCacheFinished() {
root.enableLocalCache.active = false root.enableLocalCache.active = false
enableLocalCache_enable.loading = false enableLocalCache_enable.loading = false
@ -782,7 +780,7 @@ QtObject {
onTriggered: { onTriggered: {
enableLocalCache_enable.loading = true enableLocalCache_enable.loading = true
enableLocalCache_cancel.enabled = false enableLocalCache_cancel.enabled = false
root.backend.changeLocalCache(true, root.enableLocalCache.path) Backend.changeLocalCache(true, root.enableLocalCache.path)
} }
}, },
Action { Action {
@ -807,14 +805,14 @@ QtObject {
Connections { Connections {
target: root target: root
onAskResetBridge: { function onAskResetBridge() {
root.resetBridge.active = true root.resetBridge.active = true
} }
} }
Connections { Connections {
target: root.backend target: Backend
onResetFinished: { function onResetFinished() {
root.resetBridge.active = false root.resetBridge.active = false
resetBridge_reset.loading = false resetBridge_reset.loading = false
@ -836,7 +834,7 @@ QtObject {
onTriggered: { onTriggered: {
resetBridge_reset.loading = true resetBridge_reset.loading = true
resetBridge_cancel.enabled = false resetBridge_cancel.enabled = false
root.backend.triggerReset() Backend.triggerReset()
} }
} }
] ]
@ -895,7 +893,7 @@ QtObject {
Connections { Connections {
target: root target: root
onAskDeleteAccount: { function onAskDeleteAccount(user) {
root.deleteAccount.user = user root.deleteAccount.user = user
root.deleteAccount.active = true root.deleteAccount.active = true
} }
@ -929,9 +927,9 @@ QtObject {
group: Notifications.Group.Dialogs | Notifications.Group.Configuration group: Notifications.Group.Dialogs | Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onNotifyHasNoKeychain: { function onNotifyHasNoKeychain() {
root.noKeychain.active = true root.noKeychain.active = true
} }
} }
@ -941,14 +939,14 @@ QtObject {
text: qsTr("Quit Bridge") text: qsTr("Quit Bridge")
onTriggered: { onTriggered: {
root.backend.quit() Backend.quit()
} }
}, },
Action { Action {
text: qsTr("Restart Bridge") text: qsTr("Restart Bridge")
onTriggered: { onTriggered: {
root.backend.restart() Backend.restart()
} }
} }
] ]
@ -966,9 +964,9 @@ QtObject {
Connections { Connections {
target: root.backend target: Backend
onNotifyRebuildKeychain: { function onNotifyRebuildKeychain() {
console.log("notifications") console.log("notifications")
root.rebuildKeychain.active = true root.rebuildKeychain.active = true
} }
@ -980,7 +978,7 @@ QtObject {
onTriggered: { onTriggered: {
Qt.openUrlExternally(root.rebuildKeychain.supportLink) Qt.openUrlExternally(root.rebuildKeychain.supportLink)
root.backend.quit() Backend.quit()
} }
} }
] ]
@ -995,14 +993,14 @@ QtObject {
group: Notifications.Group.Configuration group: Notifications.Group.Configuration
Connections { Connections {
target: root.backend target: Backend
onAddressChanged: { function onAddressChanged(address) {
root.addressChanged.description = qsTr("The address list for your account %1 has changed. You might need to reconfigure your email client.").arg(address) root.addressChanged.description = qsTr("The address list for your account %1 has changed. You might need to reconfigure your email client.").arg(address)
root.addressChanged.active = true root.addressChanged.active = true
} }
onAddressChangedLogout: { function onAddressChangedLogout(address) {
root.addressChanged.description = qsTr("The address list for your account %1 has changed. You have to reconfigure your email client.").arg(address) root.addressChanged.description = qsTr("The address list for your account %1 has changed. You have to reconfigure your email client.").arg(address)
root.addressChanged.active = true root.addressChanged.active = true
} }

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQuick.Controls.impl 2.13 import QtQuick.Controls.impl
import Proton 4.0 import Proton
SettingsView { SettingsView {
id: root id: root
@ -28,8 +28,8 @@ SettingsView {
fillHeight: false fillHeight: false
property bool _valuesChanged: ( property bool _valuesChanged: (
imapField.text*1 !== root.backend.portIMAP || imapField.text*1 !== Backend.portIMAP ||
smtpField.text*1 !== root.backend.portSMTP smtpField.text*1 !== Backend.portSMTP
) )
Label { Label {
@ -107,7 +107,7 @@ SettingsView {
return return
} }
root.backend.changePorts(imapField.text, smtpField.text) Backend.changePorts(imapField.text, smtpField.text)
} }
} }
@ -119,9 +119,11 @@ SettingsView {
} }
Connections { Connections {
target: root.backend target: Backend
onChangePortFinished: submitButton.loading = false function onChangePortFinished() {
submitButton.loading = false
}
} }
} }
@ -144,9 +146,9 @@ SettingsView {
function isPortFree(field) { function isPortFree(field) {
var num = field.text*1 var num = field.text*1
if (num === root.backend.portIMAP) return true if (num === Backend.portIMAP) return true
if (num === root.backend.portSMTP) return true if (num === Backend.portSMTP) return true
if (!root.backend.isPortFree(num)) { if (!Backend.isPortFree(num)) {
field.error = true field.error = true
field.errorString = qsTr("Port occupied") field.errorString = qsTr("Port occupied")
return false return false
@ -156,8 +158,8 @@ SettingsView {
} }
function setDefaultValues(){ function setDefaultValues(){
imapField.text = backend.portIMAP imapField.text = Backend.portIMAP
smtpField.text = backend.portSMTP smtpField.text = Backend.portSMTP
} }
Component.onCompleted: root.setDefaultValues() Component.onCompleted: root.setDefaultValues()

View File

@ -15,8 +15,8 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
T.Action { T.Action {
property bool loading property bool loading

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.12 import QtQuick
import QtQuick.Window 2.12 import QtQuick.Window
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
T.ApplicationWindow { T.ApplicationWindow {
id: root id: root
@ -46,7 +46,7 @@ T.ApplicationWindow {
return data(index(row, 0), Qt.DisplayRole) return data(index(row, 0), Qt.DisplayRole)
} }
onRowsInserted: { onRowsInserted: function(parent, first, last) {
for (var i = first; i <= last; i++) { for (var i = first; i <= last; i++) {
var obj = popups.get(i) var obj = popups.get(i)
obj.onShouldShowChanged.connect( root.processPopups ) obj.onShouldShowChanged.connect( root.processPopups )
@ -55,7 +55,7 @@ T.ApplicationWindow {
processPopups() processPopups()
} }
onRowsAboutToBeRemoved: { onRowsAboutToBeRemoved: function (parent, first, last) {
for (var i = first; i <= last; i++ ) { for (var i = first; i <= last; i++ ) {
var obj = popups.get(i) var obj = popups.get(i)
obj.onShouldShowChanged.disconnect( root.processPopups ) obj.onShouldShowChanged.disconnect( root.processPopups )
@ -112,7 +112,7 @@ T.ApplicationWindow {
Connections { Connections {
target: root.popupVisible target: root.popupVisible
onVisibleChanged: { function onVisibleChanged() {
if (root.popupVisible.visible) { if (root.popupVisible.visible) {
return return
} }
@ -124,11 +124,11 @@ T.ApplicationWindow {
color: root.colorScheme.background_norm color: root.colorScheme.background_norm
overlay.modal: Rectangle { Overlay.modal: Rectangle {
color: root.colorScheme.backdrop_norm color: root.colorScheme.backdrop_norm
} }
overlay.modeless: Rectangle { Overlay.modeless: Rectangle {
color: "transparent" color: "transparent"
} }
} }

View File

@ -15,12 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import "." as Proton import "." as Proton
T.Button { T.Button {
@ -129,7 +128,7 @@ T.Button {
sourceSize.height: control.icon.height sourceSize.height: control.icon.height
color: control.icon.color color: control.icon.color
source: control.loading ? "../icons/Loader_16.svg" : control.icon.source source: control.loading ? "/qml/icons/Loader_16.svg" : control.icon.source
visible: control.loading || control.icon.source visible: control.loading || control.icon.source
RotationAnimation { RotationAnimation {
@ -147,7 +146,7 @@ T.Button {
background: Rectangle { background: Rectangle {
implicitWidth: 36 implicitWidth: 36
implicitHeight: 36 implicitHeight: 36
radius: Style.button_radius radius: ProtonStyle.button_radius
visible: true visible: true
color: { color: {
if (!isIcon) { if (!isIcon) {

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
T.CheckBox { T.CheckBox {
property ColorScheme colorScheme property ColorScheme colorScheme
@ -39,7 +39,7 @@ T.CheckBox {
indicator: Rectangle { indicator: Rectangle {
implicitWidth: 20 implicitWidth: 20
implicitHeight: 20 implicitHeight: 20
radius: Style.checkbox_radius radius: ProtonStyle.checkbox_radius
x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2 x: text ? (control.mirrored ? control.width - width - control.rightPadding : control.leftPadding) : control.leftPadding + (control.availableWidth - width) / 2
y: control.topPadding + (control.availableHeight - height) / 2 y: control.topPadding + (control.availableHeight - height) / 2
@ -90,7 +90,7 @@ T.CheckBox {
sourceSize.width: parent.width - 4 sourceSize.width: parent.width - 4
sourceSize.height: parent.height - 4 sourceSize.height: parent.height - 4
color: "#FFFFFF" color: "#FFFFFF"
source: "../icons/ic-check.svg" source: "/qml/icons/ic-check.svg"
visible: control.checkState === Qt.Checked visible: control.checkState === Qt.Checked
} }
@ -124,11 +124,11 @@ T.CheckBox {
return control.colorScheme.text_norm return control.colorScheme.text_norm
} }
font.family: Style.font_family font.family: ProtonStyle.font_family
font.weight: Style.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: Style.body_font_size font.pixelSize: ProtonStyle.body_font_size
lineHeight: Style.body_line_height lineHeight: ProtonStyle.body_line_height
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
font.letterSpacing: Style.body_letter_spacing font.letterSpacing: ProtonStyle.body_letter_spacing
} }
} }

View File

@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.13 import QtQml
QtObject { QtObject {
// should be a pointer to ColorScheme object // should be a pointer to ColorScheme object

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Window 2.12 import QtQuick.Window
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
T.ComboBox { T.ComboBox {
id: root id: root
@ -40,10 +40,10 @@ T.ComboBox {
spacing: 8 spacing: 8
font.family: Style.font_family font.family: ProtonStyle.font_family
font.weight: Style.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: Style.body_font_size font.pixelSize: ProtonStyle.body_font_size
font.letterSpacing: Style.body_letter_spacing font.letterSpacing: ProtonStyle.body_letter_spacing
contentItem: T.TextField { contentItem: T.TextField {
padding: 5 padding: 5
@ -64,7 +64,7 @@ T.ComboBox {
placeholderTextColor: root.enabled ? root.colorScheme.text_hint : root.colorScheme.text_disabled placeholderTextColor: root.enabled ? root.colorScheme.text_hint : root.colorScheme.text_disabled
background: Rectangle { background: Rectangle {
radius: Style.context_item_radius radius: ProtonStyle.context_item_radius
visible: root.enabled && root.editable && !root.flat visible: root.enabled && root.editable && !root.flat
border.color: { border.color: {
if (root.activeFocus) { if (root.activeFocus) {
@ -85,7 +85,7 @@ T.ComboBox {
background: Rectangle { background: Rectangle {
implicitWidth: 140 implicitWidth: 140
implicitHeight: 36 implicitHeight: 36
radius: Style.context_item_radius radius: ProtonStyle.context_item_radius
color: { color: {
if (root.down) { if (root.down) {
return root.colorScheme.interaction_default_active return root.colorScheme.interaction_default_active
@ -110,7 +110,7 @@ T.ComboBox {
x: root.mirrored ? 12 : root.width - width - 12 x: root.mirrored ? 12 : root.width - width - 12
y: root.topPadding + (root.availableHeight - height) / 2 y: root.topPadding + (root.availableHeight - height) / 2
color: root.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled color: root.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
source: popup.visible ? "../icons/ic-chevron-up.svg" : "../icons/ic-chevron-down.svg" source: popup.visible ? "/qml/icons/ic-chevron-up.svg" : "/qml/icons/ic-chevron-down.svg"
sourceSize.width: 16 sourceSize.width: 16
sourceSize.height: 16 sourceSize.height: 16
@ -142,7 +142,7 @@ T.ComboBox {
palette.highlightedText: selected ? root.colorScheme.text_invert : root.colorScheme.text_norm palette.highlightedText: selected ? root.colorScheme.text_invert : root.colorScheme.text_norm
background: PaddedRectangle { background: PaddedRectangle {
radius: Style.context_item_radius radius: ProtonStyle.context_item_radius
color: { color: {
if (parent.down) { if (parent.down) {
return root.colorScheme.interaction_default_active return root.colorScheme.interaction_default_active
@ -187,7 +187,7 @@ T.ComboBox {
background: Rectangle { background: Rectangle {
color: root.colorScheme.background_norm color: root.colorScheme.background_norm
radius: Style.dialog_radius radius: ProtonStyle.dialog_radius
border.color: root.colorScheme.border_weak border.color: root.colorScheme.border_weak
border.width: 1 border.width: 1
} }

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.12 import QtQuick
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
T.Dialog { T.Dialog {
id: root id: root
@ -65,7 +65,7 @@ T.Dialog {
background: Rectangle { background: Rectangle {
color: root.colorScheme.background_norm color: root.colorScheme.background_norm
radius: Style.dialog_radius radius: ProtonStyle.dialog_radius
} }
// TODO: Add DropShadow here // TODO: Add DropShadow here

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import "." as Proton import "." as Proton
@ -53,67 +53,67 @@ T.Label {
linkColor: root.colorScheme.interaction_norm linkColor: root.colorScheme.interaction_norm
palette.link: linkColor palette.link: linkColor
font.family: Style.font_family font.family: ProtonStyle.font_family
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
font.weight: { font.weight: {
switch (root.type) { switch (root.type) {
case Proton.Label.LabelType.Heading: case Proton.Label.LabelType.Heading:
return Style.fontWeight_700 return ProtonStyle.fontWeight_700
case Proton.Label.LabelType.Title: case Proton.Label.LabelType.Title:
return Style.fontWeight_700 return ProtonStyle.fontWeight_700
case Proton.Label.LabelType.Lead: case Proton.Label.LabelType.Lead:
return Style.fontWeight_400 return ProtonStyle.fontWeight_400
case Proton.Label.LabelType.Body: case Proton.Label.LabelType.Body:
return Style.fontWeight_400 return ProtonStyle.fontWeight_400
case Proton.Label.LabelType.Body_semibold: case Proton.Label.LabelType.Body_semibold:
return Style.fontWeight_600 return ProtonStyle.fontWeight_600
case Proton.Label.LabelType.Body_bold: case Proton.Label.LabelType.Body_bold:
return Style.fontWeight_700 return ProtonStyle.fontWeight_700
case Proton.Label.LabelType.Caption: case Proton.Label.LabelType.Caption:
return Style.fontWeight_400 return ProtonStyle.fontWeight_400
case Proton.Label.LabelType.Caption_semibold: case Proton.Label.LabelType.Caption_semibold:
return Style.fontWeight_600 return ProtonStyle.fontWeight_600
case Proton.Label.LabelType.Caption_bold: case Proton.Label.LabelType.Caption_bold:
return Style.fontWeight_700 return ProtonStyle.fontWeight_700
} }
} }
font.pixelSize: { font.pixelSize: {
switch (root.type) { switch (root.type) {
case Proton.Label.LabelType.Heading: case Proton.Label.LabelType.Heading:
return Style.heading_font_size return ProtonStyle.heading_font_size
case Proton.Label.LabelType.Title: case Proton.Label.LabelType.Title:
return Style.title_font_size return ProtonStyle.title_font_size
case Proton.Label.LabelType.Lead: case Proton.Label.LabelType.Lead:
return Style.lead_font_size return ProtonStyle.lead_font_size
case Proton.Label.LabelType.Body: case Proton.Label.LabelType.Body:
case Proton.Label.LabelType.Body_semibold: case Proton.Label.LabelType.Body_semibold:
case Proton.Label.LabelType.Body_bold: case Proton.Label.LabelType.Body_bold:
return Style.body_font_size return ProtonStyle.body_font_size
case Proton.Label.LabelType.Caption: case Proton.Label.LabelType.Caption:
case Proton.Label.LabelType.Caption_semibold: case Proton.Label.LabelType.Caption_semibold:
case Proton.Label.LabelType.Caption_bold: case Proton.Label.LabelType.Caption_bold:
return Style.caption_font_size return ProtonStyle.caption_font_size
} }
} }
lineHeight: { lineHeight: {
switch (root.type) { switch (root.type) {
case Proton.Label.LabelType.Heading: case Proton.Label.LabelType.Heading:
return Style.heading_line_height return ProtonStyle.heading_line_height
case Proton.Label.LabelType.Title: case Proton.Label.LabelType.Title:
return Style.title_line_height return ProtonStyle.title_line_height
case Proton.Label.LabelType.Lead: case Proton.Label.LabelType.Lead:
return Style.lead_line_height return ProtonStyle.lead_line_height
case Proton.Label.LabelType.Body: case Proton.Label.LabelType.Body:
case Proton.Label.LabelType.Body_semibold: case Proton.Label.LabelType.Body_semibold:
case Proton.Label.LabelType.Body_bold: case Proton.Label.LabelType.Body_bold:
return Style.body_line_height return ProtonStyle.body_line_height
case Proton.Label.LabelType.Caption: case Proton.Label.LabelType.Caption:
case Proton.Label.LabelType.Caption_semibold: case Proton.Label.LabelType.Caption_semibold:
case Proton.Label.LabelType.Caption_bold: case Proton.Label.LabelType.Caption_bold:
return Style.caption_line_height return ProtonStyle.caption_line_height
} }
} }
@ -126,11 +126,11 @@ T.Label {
case Proton.Label.LabelType.Body: case Proton.Label.LabelType.Body:
case Proton.Label.LabelType.Body_semibold: case Proton.Label.LabelType.Body_semibold:
case Proton.Label.LabelType.Body_bold: case Proton.Label.LabelType.Body_bold:
return Style.body_letter_spacing return ProtonStyle.body_letter_spacing
case Proton.Label.LabelType.Caption: case Proton.Label.LabelType.Caption:
case Proton.Label.LabelType.Caption_semibold: case Proton.Label.LabelType.Caption_semibold:
case Proton.Label.LabelType.Caption_bold: case Proton.Label.LabelType.Caption_bold:
return Style.caption_letter_spacing return ProtonStyle.caption_letter_spacing
} }
} }

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import QtQuick.Window 2.12 import QtQuick.Window
import "." import "."
T.Menu { T.Menu {
@ -67,6 +67,6 @@ T.Menu {
color: colorScheme.background_norm color: colorScheme.background_norm
border.width: 1 border.width: 1
border.color: colorScheme.border_weak border.color: colorScheme.border_weak
radius: Style.account_row_radius radius: ProtonStyle.account_row_radius
} }
} }

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import "." import "."
T.MenuItem { T.MenuItem {
@ -39,10 +39,10 @@ T.MenuItem {
icon.height: 24 icon.height: 24
icon.color: control.enabled ? control.colorScheme.text_norm : control.colorScheme.text_disabled icon.color: control.enabled ? control.colorScheme.text_norm : control.colorScheme.text_disabled
font.family: Style.font_family font.family: ProtonStyle.font_family
font.weight: Style.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: Style.body_font_size font.pixelSize: ProtonStyle.body_font_size
font.letterSpacing: Style.body_letter_spacing font.letterSpacing: ProtonStyle.body_letter_spacing
contentItem: IconLabel { contentItem: IconLabel {
id: iconLabel id: iconLabel
@ -66,7 +66,7 @@ T.MenuItem {
background: Rectangle { background: Rectangle {
implicitWidth: 164 implicitWidth: 164
implicitHeight: 36 implicitHeight: 36
radius: Style.button_radius radius: ProtonStyle.button_radius
color: control.down ? control.colorScheme.interaction_default_active : control.highlighted ? control.colorScheme.interaction_default_hover : control.colorScheme.interaction_default color: control.down ? control.colorScheme.interaction_default_active : control.highlighted ? control.colorScheme.interaction_default_hover : control.colorScheme.interaction_default
} }
} }

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
T.Popup { T.Popup {
id: root id: root

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
T.RadioButton { T.RadioButton {
property ColorScheme colorScheme property ColorScheme colorScheme
@ -105,11 +105,11 @@ T.RadioButton {
return control.colorScheme.text_norm return control.colorScheme.text_norm
} }
font.family: Style.font_family font.family: ProtonStyle.font_family
font.weight: Style.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: Style.body_font_size font.pixelSize: ProtonStyle.body_font_size
lineHeight: Style.body_line_height lineHeight: ProtonStyle.body_line_height
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
font.letterSpacing: Style.body_letter_spacing font.letterSpacing: ProtonStyle.body_letter_spacing
} }
} }

View File

@ -16,8 +16,8 @@
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
pragma Singleton pragma Singleton
import QtQml 2.13 import QtQml
import QtQuick 2.12 import QtQuick
import "./" import "./"
@ -105,8 +105,8 @@ QtObject {
backdrop_norm: Qt.rgba(12./255., 12./255., 20./255., 0.32) backdrop_norm: Qt.rgba(12./255., 12./255., 20./255., 0.32)
// Images // Images
welcome_img: "icons/img-welcome.png" welcome_img: "/qml/icons/img-welcome.png"
logo_img: "icons/product_logos.svg" logo_img: "/qml/icons/product_logos.svg"
} }
property ColorScheme lightProminentStyle: ColorScheme { property ColorScheme lightProminentStyle: ColorScheme {
@ -180,8 +180,8 @@ QtObject {
backdrop_norm: Qt.rgba(0,0,0, 0.32) backdrop_norm: Qt.rgba(0,0,0, 0.32)
// Images // Images
welcome_img: "icons/img-welcome-dark.png" welcome_img: "/qml/icons/img-welcome-dark.png"
logo_img: "icons/product_logos_dark.svg" logo_img: "/qml/icons/product_logos_dark.svg"
} }
property ColorScheme darkStyle: ColorScheme { property ColorScheme darkStyle: ColorScheme {
@ -255,8 +255,8 @@ QtObject {
backdrop_norm: Qt.rgba(0,0,0,0.32) backdrop_norm: Qt.rgba(0,0,0,0.32)
// Images // Images
welcome_img: "icons/img-welcome-dark.png" welcome_img: "/qml/icons/img-welcome-dark.png"
logo_img: "icons/product_logos_dark.svg" logo_img: "/qml/icons/product_logos_dark.svg"
} }
property ColorScheme darkProminentStyle: ColorScheme { property ColorScheme darkProminentStyle: ColorScheme {
@ -330,8 +330,8 @@ QtObject {
backdrop_norm: Qt.rgba(0,0,0,0.32) backdrop_norm: Qt.rgba(0,0,0,0.32)
// Images // Images
welcome_img: "icons/img-welcome-dark.png" welcome_img: "/qml/icons/img-welcome-dark.png"
logo_img: "icons/product_logos_dark.svg" logo_img: "/qml/icons/product_logos_dark.svg"
} }
property ColorScheme currentStyle: lightStyle property ColorScheme currentStyle: lightStyle
@ -341,7 +341,7 @@ QtObject {
case "windows": case "windows":
return "Segoe UI" return "Segoe UI"
case "osx": case "osx":
return "SF Pro Display" return ".AppleSystemUIFont" // should be SF Pro for the foreseeable future. Using "SF Pro Display" direcly here is not allowed by the font's license.
case "linux": case "linux":
return "Ubuntu" return "Ubuntu"
default: default:

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.12 import QtQuick
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
T.Switch { T.Switch {
property ColorScheme colorScheme property ColorScheme colorScheme
@ -96,7 +96,7 @@ T.Switch {
sourceSize.width: 16 sourceSize.width: 16
sourceSize.height: 16 sourceSize.height: 16
color: "#FFFFFF" color: "#FFFFFF"
source: "../icons/ic-check.svg" source: "/qml/icons/ic-check.svg"
visible: control.checked visible: control.checked
} }
@ -116,7 +116,7 @@ T.Switch {
sourceSize.width: 18 sourceSize.width: 18
sourceSize.height: 18 sourceSize.height: 18
color: control.colorScheme.interaction_norm_hover color: control.colorScheme.interaction_norm_hover
source: "../icons/Loader_16.svg" source: "/qml/icons/Loader_16.svg"
visible: control.loading visible: control.loading
RotationAnimation { RotationAnimation {
@ -140,11 +140,11 @@ T.Switch {
color: control.enabled || control.loading ? control.colorScheme.text_norm : control.colorScheme.text_disabled color: control.enabled || control.loading ? control.colorScheme.text_norm : control.colorScheme.text_disabled
font.family: Style.font_family font.family: ProtonStyle.font_family
font.weight: Style.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: Style.body_font_size font.pixelSize: ProtonStyle.body_font_size
lineHeight: Style.body_line_height lineHeight: ProtonStyle.body_line_height
lineHeightMode: Text.FixedHeight lineHeightMode: Text.FixedHeight
font.letterSpacing: Style.body_letter_spacing font.letterSpacing: ProtonStyle.body_letter_spacing
} }
} }

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import "." as Proton import "." as Proton
@ -198,10 +198,10 @@ FocusScope {
leftPadding: 12 leftPadding: 12
rightPadding: 12 rightPadding: 12
font.family: Style.font_family font.family: ProtonStyle.font_family
font.weight: Style.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: Style.body_font_size font.pixelSize: ProtonStyle.body_font_size
font.letterSpacing: Style.body_letter_spacing font.letterSpacing: ProtonStyle.body_letter_spacing
color: control.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled color: control.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
placeholderTextColor: control.enabled ? root.colorScheme.text_hint : root.colorScheme.text_disabled placeholderTextColor: control.enabled ? root.colorScheme.text_hint : root.colorScheme.text_disabled
@ -233,7 +233,7 @@ FocusScope {
Connections { Connections {
target: control target: control
onCursorPositionChanged: { function onCursorPositionChanged() {
// keep a moving cursor visible // keep a moving cursor visible
cursor.opacity = 1 cursor.opacity = 1
timer.restart() timer.restart()
@ -270,7 +270,7 @@ FocusScope {
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
radius: Style.input_radius radius: ProtonStyle.input_radius
visible: true visible: true
color: root.colorScheme.background_norm color: root.colorScheme.background_norm
border.color: { border.color: {
@ -308,7 +308,7 @@ FocusScope {
Layout.rightMargin: 4 Layout.rightMargin: 4
visible: root.error && (assistiveText.text.length > 0) visible: root.error && (assistiveText.text.length > 0)
source: "../icons/ic-exclamation-circle-filled.svg" source: "/qml/icons/ic-exclamation-circle-filled.svg"
color: root.colorScheme.signal_danger color: root.colorScheme.signal_danger
height: assistiveText.height height: assistiveText.height
sourceSize.height: assistiveText.height sourceSize.height: assistiveText.height

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import QtQuick.Templates 2.12 as T import QtQuick.Templates as T
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import "." as Proton import "." as Proton
@ -160,7 +160,7 @@ FocusScope {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
radius: Style.input_radius radius: ProtonStyle.input_radius
visible: true visible: true
color: root.colorScheme.background_norm color: root.colorScheme.background_norm
border.color: { border.color: {
@ -208,10 +208,10 @@ FocusScope {
leftPadding: 12 leftPadding: 12
rightPadding: 12 rightPadding: 12
font.family: Style.font_family font.family: ProtonStyle.font_family
font.weight: Style.fontWeight_400 font.weight: ProtonStyle.fontWeight_400
font.pixelSize: Style.body_font_size font.pixelSize: ProtonStyle.body_font_size
font.letterSpacing: Style.body_letter_spacing font.letterSpacing: ProtonStyle.body_letter_spacing
color: control.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled color: control.enabled ? root.colorScheme.text_norm : root.colorScheme.text_disabled
placeholderTextColor: control.enabled ? root.colorScheme.text_hint : root.colorScheme.text_disabled placeholderTextColor: control.enabled ? root.colorScheme.text_hint : root.colorScheme.text_disabled
@ -243,7 +243,7 @@ FocusScope {
Connections { Connections {
target: control target: control
onCursorPositionChanged: { function onCursorPositionChanged() {
// keep a moving cursor visible // keep a moving cursor visible
cursor.opacity = 1 cursor.opacity = 1
timer.restart() timer.restart()

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQuick.Controls.impl 2.13 import QtQuick.Controls.impl
Item { Item {
id: root id: root
@ -72,7 +72,7 @@ Item {
ColorImage { ColorImage {
anchors.centerIn: parent anchors.centerIn: parent
source: "../icons/ic-check.svg" source: "/qml/icons/ic-check.svg"
color: root.colorScheme.background_norm color: root.colorScheme.background_norm
height: root.colorScheme.body_font_size height: root.colorScheme.body_font_size
sourceSize.height: root.colorScheme.body_font_size sourceSize.height: root.colorScheme.body_font_size
@ -83,7 +83,7 @@ Item {
ColorImage { ColorImage {
id: loader id: loader
anchors.centerIn: parent anchors.centerIn: parent
source: "../icons/Loader_16.svg" source: "/qml/icons/Loader_16.svg"
color: root.colorScheme.text_norm color: root.colorScheme.text_norm
height: root.colorScheme.body_font_size height: root.colorScheme.body_font_size
sourceSize.height: root.colorScheme.body_font_size sourceSize.height: root.colorScheme.body_font_size

View File

@ -21,6 +21,7 @@ depends QtQuick.Controls 2.12
singleton ProtonStyle 4.0 Style.qml singleton ProtonStyle 4.0 Style.qml
ColorScheme 4.0 ColorScheme.qml ColorScheme 4.0 ColorScheme.qml
Action 4.0 Action.qml
ApplicationWindow 4.0 ApplicationWindow.qml ApplicationWindow 4.0 ApplicationWindow.qml
Button 4.0 Button.qml Button 4.0 Button.qml
CheckBox 4.0 CheckBox.qml CheckBox 4.0 CheckBox.qml

View File

@ -15,12 +15,12 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQuick.Controls.impl 2.13 import QtQuick.Controls.impl
import Proton 4.0 import Proton
SettingsView { SettingsView {
id: root id: root
@ -87,7 +87,7 @@ SettingsView {
root.submit() root.submit()
} }
enabled: sslButton.checked !== root.backend.useSSLforSMTP enabled: sslButton.checked !== Backend.useSSLforSMTP
} }
Button { Button {
@ -98,20 +98,22 @@ SettingsView {
} }
Connections { Connections {
target: root.backend target: Backend
onToggleUseSSLFinished: submitButton.loading = false function onToggleUseSSLFinished() {
submitButton.loading = false
}
} }
} }
function submit(){ function submit(){
submitButton.loading = true submitButton.loading = true
root.backend.toggleUseSSLforSMTP(sslButton.checked) Backend.toggleUseSSLforSMTP(sslButton.checked)
} }
function setDefaultValues(){ function setDefaultValues(){
sslButton.checked = root.backend.useSSLforSMTP sslButton.checked = Backend.useSSLforSMTP
starttlsButton.checked = !root.backend.useSSLforSMTP starttlsButton.checked = !Backend.useSSLforSMTP
} }
onVisibleChanged: { onVisibleChanged: {

View File

@ -15,11 +15,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
Item { Item {
id: root id: root

View File

@ -15,18 +15,17 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import QtQuick.Controls.impl 2.13 import QtQuick.Controls.impl
import Proton 4.0 import Proton
Item { Item {
id: root id: root
property var colorScheme property var colorScheme
property var backend
default property alias items: content.children default property alias items: content.children
signal back() signal back()
@ -92,7 +91,7 @@ Item {
} }
colorScheme: root.colorScheme colorScheme: root.colorScheme
onClicked: root.back() onClicked: root.back()
icon.source: "icons/ic-arrow-left.svg" icon.source: "/qml/icons/ic-arrow-left.svg"
secondary: true secondary: true
horizontalPadding: 8 horizontalPadding: 8
} }

View File

@ -16,18 +16,17 @@
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import Proton 4.0 import Proton
Item { Item {
id:root id:root
property ColorScheme colorScheme property ColorScheme colorScheme
property var backend
property var user property var user
property string address property string address
@ -41,29 +40,29 @@ Item {
ListModel { ListModel {
id: clients id: clients
property string name : "Apple Mail" property string name : "Apple Mail"
property string iconSource : "./icons/ic-apple-mail.svg" property string iconSource : "/qml/icons/ic-apple-mail.svg"
property bool haveAutoSetup: true property bool haveAutoSetup: true
property string link: "https://protonmail.com/bridge/applemail" property string link: "https://protonmail.com/bridge/applemail"
Component.onCompleted : { Component.onCompleted : {
if (root.backend.goos == "darwin") { if (Backend.goos == "darwin") {
append({ append({
"name" : "Apple Mail", "name" : "Apple Mail",
"iconSource" : "./icons/ic-apple-mail.svg", "iconSource" : "/qml/icons/ic-apple-mail.svg",
"haveAutoSetup" : true, "haveAutoSetup" : true,
"link" : "https://protonmail.com/bridge/applemail" "link" : "https://protonmail.com/bridge/applemail"
}) })
append({ append({
"name" : "Microsoft Outlook", "name" : "Microsoft Outlook",
"iconSource" : "./icons/ic-microsoft-outlook.svg", "iconSource" : "/qml/icons/ic-microsoft-outlook.svg",
"haveAutoSetup" : false, "haveAutoSetup" : false,
"link" : "https://protonmail.com/bridge/outlook2019-mac" "link" : "https://protonmail.com/bridge/outlook2019-mac"
}) })
} }
if (root.backend.goos == "windows") { if (Backend.goos == "windows") {
append({ append({
"name" : "Microsoft Outlook", "name" : "Microsoft Outlook",
"iconSource" : "./icons/ic-microsoft-outlook.svg", "iconSource" : "/qml/icons/ic-microsoft-outlook.svg",
"haveAutoSetup" : false, "haveAutoSetup" : false,
"link" : "https://protonmail.com/bridge/outlook2019" "link" : "https://protonmail.com/bridge/outlook2019"
}) })
@ -71,14 +70,14 @@ Item {
append({ append({
"name" : "Mozilla Thunderbird", "name" : "Mozilla Thunderbird",
"iconSource" : "./icons/ic-mozilla-thunderbird.svg", "iconSource" : "/qml/icons/ic-mozilla-thunderbird.svg",
"haveAutoSetup" : false, "haveAutoSetup" : false,
"link" : "https://protonmail.com/bridge/thunderbird" "link" : "https://protonmail.com/bridge/thunderbird"
}) })
append({ append({
"name" : "Other", "name" : "Other",
"iconSource" : "./icons/ic-other-mail-clients.svg", "iconSource" : "/qml/icons/ic-other-mail-clients.svg",
"haveAutoSetup" : false, "haveAutoSetup" : false,
"link" : "https://protonmail.com/bridge/clients" "link" : "https://protonmail.com/bridge/clients"
}) })

View File

@ -15,13 +15,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import Proton 4.0 import Proton
Item { Item {
id: root id: root
@ -37,14 +37,12 @@ Item {
function abort() { function abort() {
root.reset() root.reset()
root.backend.loginAbort(usernameTextField.text) Backend.loginAbort(usernameTextField.text)
} }
implicitHeight: children[0].implicitHeight implicitHeight: children[0].implicitHeight
implicitWidth: children[0].implicitWidth implicitWidth: children[0].implicitWidth
property var backend
property alias username: usernameTextField.text property alias username: usernameTextField.text
state: "Page 1" state: "Page 1"
@ -65,9 +63,9 @@ Item {
} }
Connections { Connections {
target: root.backend target: Backend
onLoginUsernamePasswordError: { function onLoginUsernamePasswordError(errorMsg) {
console.assert(stackLayout.currentIndex == 0, "Unexpected loginUsernamePasswordError") console.assert(stackLayout.currentIndex == 0, "Unexpected loginUsernamePasswordError")
console.assert(signInButton.loading == true, "Unexpected loginUsernamePasswordError") console.assert(signInButton.loading == true, "Unexpected loginUsernamePasswordError")
@ -76,23 +74,24 @@ Item {
else errorLabel.text = qsTr("Incorrect login credentials") else errorLabel.text = qsTr("Incorrect login credentials")
} }
onLoginFreeUserError: { function onLoginFreeUserError() {
console.assert(stackLayout.currentIndex == 0, "Unexpected loginFreeUserError") console.assert(stackLayout.currentIndex == 0, "Unexpected loginFreeUserError")
stackLayout.loginFailed() stackLayout.loginFailed()
} }
onLoginConnectionError: { function onLoginConnectionError(errorMsg) {
if (stackLayout.currentIndex == 0 ) { if (stackLayout.currentIndex == 0 ) {
stackLayout.loginFailed() stackLayout.loginFailed()
} }
} }
onLogin2FARequested: { function onLogin2FARequested(username) {
console.assert(stackLayout.currentIndex == 0, "Unexpected login2FARequested") console.assert(stackLayout.currentIndex == 0, "Unexpected login2FARequested")
twoFactorUsernameLabel.text = username twoFactorUsernameLabel.text = username
stackLayout.currentIndex = 1 stackLayout.currentIndex = 1
} }
onLogin2FAError: {
function onLogin2FAError(errorMsg) {
console.assert(stackLayout.currentIndex == 1, "Unexpected login2FAError") console.assert(stackLayout.currentIndex == 1, "Unexpected login2FAError")
twoFAButton.loading = false twoFAButton.loading = false
@ -101,17 +100,18 @@ Item {
twoFactorPasswordTextField.error = true twoFactorPasswordTextField.error = true
twoFactorPasswordTextField.errorString = qsTr("Your code is incorrect") twoFactorPasswordTextField.errorString = qsTr("Your code is incorrect")
} }
onLogin2FAErrorAbort: {
function onLogin2FAErrorAbort(errorMsg) {
console.assert(stackLayout.currentIndex == 1, "Unexpected login2FAErrorAbort") console.assert(stackLayout.currentIndex == 1, "Unexpected login2FAErrorAbort")
root.reset() root.reset()
errorLabel.text = qsTr("Incorrect login credentials. Please try again.") errorLabel.text = qsTr("Incorrect login credentials. Please try again.")
} }
onLogin2PasswordRequested: { function onLogin2PasswordRequested() {
console.assert(stackLayout.currentIndex == 0 || stackLayout.currentIndex == 1, "Unexpected login2PasswordRequested") console.assert(stackLayout.currentIndex == 0 || stackLayout.currentIndex == 1, "Unexpected login2PasswordRequested")
stackLayout.currentIndex = 2 stackLayout.currentIndex = 2
} }
onLogin2PasswordError: { function onLogin2PasswordError(errorMsg) {
console.assert(stackLayout.currentIndex == 2, "Unexpected login2PasswordError") console.assert(stackLayout.currentIndex == 2, "Unexpected login2PasswordError")
secondPasswordButton.loading = false secondPasswordButton.loading = false
@ -120,13 +120,13 @@ Item {
secondPasswordTextField.error = true secondPasswordTextField.error = true
secondPasswordTextField.errorString = qsTr("Your mailbox password is incorrect") secondPasswordTextField.errorString = qsTr("Your mailbox password is incorrect")
} }
onLogin2PasswordErrorAbort: { function onLogin2PasswordErrorAbort(errorMsg) {
console.assert(stackLayout.currentIndex == 2, "Unexpected login2PasswordErrorAbort") console.assert(stackLayout.currentIndex == 2, "Unexpected login2PasswordErrorAbort")
root.reset() root.reset()
errorLabel.text = qsTr("Incorrect login credentials. Please try again.") errorLabel.text = qsTr("Incorrect login credentials. Please try again.")
} }
onLoginFinished: { function onLoginFinished(index) {
stackLayout.currentIndex = 0 stackLayout.currentIndex = 0
root.reset() root.reset()
} }
@ -179,7 +179,7 @@ Item {
ColorImage { ColorImage {
color: root.colorScheme.signal_danger color: root.colorScheme.signal_danger
source: "./icons/ic-exclamation-circle-filled.svg" source: "/qml/icons/ic-exclamation-circle-filled.svg"
height: errorLabel.height height: errorLabel.height
sourceSize.height: errorLabel.height sourceSize.height: errorLabel.height
} }
@ -274,7 +274,7 @@ Item {
enabled = false enabled = false
loading = true loading = true
root.backend.login(usernameTextField.text, Qt.btoa(passwordTextField.text)) Backend.login(usernameTextField.text, Qt.btoa(passwordTextField.text))
} }
} }
@ -361,7 +361,7 @@ Item {
enabled = false enabled = false
loading = true loading = true
root.backend.login2FA(usernameTextField.text, Qt.btoa(twoFactorPasswordTextField.text)) Backend.login2FA(usernameTextField.text, Qt.btoa(twoFactorPasswordTextField.text))
} }
} }
} }
@ -425,7 +425,7 @@ Item {
enabled = false enabled = false
loading = true loading = true
root.backend.login2Password(usernameTextField.text, Qt.btoa(secondPasswordTextField.text)) Backend.login2Password(usernameTextField.text, Qt.btoa(secondPasswordTextField.text))
} }
} }
} }

View File

@ -15,20 +15,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import Proton 4.0 import Proton
Dialog { Dialog {
id: root id: root
property var backend shouldShow: Backend.showSplashScreen
shouldShow: root.backend.showSplashScreen
modal: true modal: true
topPadding : 0 topPadding : 0
@ -89,7 +87,7 @@ Dialog {
Layout.rightMargin: 24 Layout.rightMargin: 24
colorScheme: root.colorScheme colorScheme: root.colorScheme
text: "Got it" text: "Got it"
onClicked: root.backend.showSplashScreen = false onClicked: Backend.showSplashScreen = false
} }
Image { Image {
@ -101,7 +99,7 @@ Dialog {
Layout.preferredWidth: 164 Layout.preferredWidth: 164
Layout.preferredHeight: 32 Layout.preferredHeight: 32
source: "./icons/img-proton-logos.svg" source: "/qml/icons/img-proton-logos.svg"
} }
} }
} }

View File

@ -16,18 +16,17 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import QtQuick.Controls.impl 2.12 import QtQuick.Controls.impl
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
Item { Item {
id: root id: root
property var backend
property var notifications property var notifications
property ColorScheme colorScheme property ColorScheme colorScheme
@ -48,7 +47,7 @@ Item {
onTopmostChanged: { onTopmostChanged: {
if (!topmost) { if (!topmost) {
image.source = "./icons/ic-connected.svg" image.source = "/qml/icons/ic-connected.svg"
image.color = root.colorScheme.signal_success image.color = root.colorScheme.signal_success
label.text = qsTr("Connected") label.text = qsTr("Connected")
label.color = root.colorScheme.signal_success label.color = root.colorScheme.signal_success
@ -89,7 +88,7 @@ Item {
height: 16 height: 16
sourceSize.width: width sourceSize.width: width
sourceSize.height: height sourceSize.height: height
source: "./icons/ic-connected.svg" source: "/qml/icons/ic-connected.svg"
color: root.colorScheme.signal_success color: root.colorScheme.signal_success
} }

View File

@ -15,14 +15,14 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.13 import QtQuick.Controls
import Proton 4.0 import Proton
import Notifications 1.0 import Notifications
Window { Window {
id: root id: root
@ -35,7 +35,6 @@ Window {
property ColorScheme colorScheme: ProtonStyle.currentStyle property ColorScheme colorScheme: ProtonStyle.currentStyle
property var backend
property var notifications property var notifications
signal showMainWindow() signal showMainWindow()
@ -114,7 +113,6 @@ Window {
Layout.bottomMargin: 12 Layout.bottomMargin: 12
colorScheme: root.colorScheme colorScheme: root.colorScheme
backend: root.backend
notifications: root.notifications notifications: root.notifications
notificationWhitelist: Notifications.Group.Connection | Notifications.Group.Update | Notifications.Group.Configuration notificationWhitelist: Notifications.Group.Connection | Notifications.Group.Update | Notifications.Group.Configuration
@ -164,7 +162,7 @@ Window {
ListView { ListView {
id: accountListView id: accountListView
model: root.backend.users model: Backend.users
anchors.fill: parent anchors.fill: parent
anchors.topMargin: 8 anchors.topMargin: 8
@ -185,7 +183,7 @@ Window {
implicitHeight: children[0].implicitHeight implicitHeight: children[0].implicitHeight
implicitWidth: children[0].implicitWidth implicitWidth: children[0].implicitWidth
property var user: root.backend.users.get(index) property var user: Backend.users.get(index)
RowLayout { RowLayout {
spacing: 0 spacing: 0
@ -262,7 +260,7 @@ Window {
Button { Button {
colorScheme: root.colorScheme colorScheme: root.colorScheme
secondary: true secondary: true
icon.source: "./icons/ic-three-dots-vertical.svg" icon.source: "/qml/icons/ic-three-dots-vertical.svg"
borderless: true borderless: true
checkable: true checkable: true

View File

@ -15,20 +15,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQml 2.12 import QtQml
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import Proton 4.0 import Proton
Item { Item {
id: root id: root
property ColorScheme colorScheme property ColorScheme colorScheme
property var backend
implicitHeight: children[0].implicitHeight implicitHeight: children[0].implicitHeight
implicitWidth: children[0].implicitWidth implicitWidth: children[0].implicitWidth
@ -224,8 +222,7 @@ Item {
Layout.preferredWidth: 320 Layout.preferredWidth: 320
Layout.fillWidth: true Layout.fillWidth: true
username: root.backend.users.count === 1 && root.backend.users.get(0) && root.backend.users.get(0).loggedIn === false ? root.backend.users.get(0).username : "" username: Backend.users.count === 1 && Backend.users.get(0) && Backend.users.get(0).loggedIn === false ? Backend.users.get(0).username : ""
backend: root.backend
} }
// Right margin // Right margin

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"
@ -32,7 +32,7 @@ RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
iconLoading: "../icons/Loader_16.svg" iconLoading: "/qml/icons/Loader_16.svg"
} }
// Secondary buttons // Secondary buttons
@ -42,7 +42,7 @@ RowLayout {
Layout.fillHeight: true Layout.fillHeight: true
secondary: true secondary: true
iconLoading: "../icons/Loader_16.svg" iconLoading: "/qml/icons/Loader_16.svg"
} }
// Secondary icons // Secondary icons
@ -53,11 +53,11 @@ RowLayout {
secondary: true secondary: true
textNormal: "" textNormal: ""
iconNormal: "../icons/ic-cross-close.svg" iconNormal: "/qml/icons/ic-cross-close.svg"
textDisabled: "" textDisabled: ""
iconDisabled: "../icons/ic-cross-close.svg" iconDisabled: "/qml/icons/ic-cross-close.svg"
textLoading: "" textLoading: ""
iconLoading: "../icons/Loader_16.svg" iconLoading: "/qml/icons/Loader_16.svg"
} }
// Icons // Icons
@ -67,10 +67,10 @@ RowLayout {
Layout.fillHeight: true Layout.fillHeight: true
textNormal: "" textNormal: ""
iconNormal: "../icons/ic-cross-close.svg" iconNormal: "/qml/icons/ic-cross-close.svg"
textDisabled: "" textDisabled: ""
iconDisabled: "../icons/ic-cross-close.svg" iconDisabled: "/qml/icons/ic-cross-close.svg"
textLoading: "" textLoading: ""
iconLoading: "../icons/Loader_16.svg" iconLoading: "/qml/icons/Loader_16.svg"
} }
} }

View File

@ -15,9 +15,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick 2.12 import QtQuick
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"

View File

@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick.Window 2.13 import QtQuick.Window
import "../Proton" import "../Proton"

View File

@ -15,9 +15,9 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"

View File

@ -15,10 +15,10 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. // along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
import QtQuick 2.13 import QtQuick
import QtQuick.Window 2.13 import QtQuick.Window
import QtQuick.Layouts 1.12 import QtQuick.Layouts
import QtQuick.Controls 2.12 import QtQuick.Controls
import "../Proton" import "../Proton"