Merge branch 'master' of github.com:Ultimaker/Cura

This commit is contained in:
Jaime van Kessel 2020-06-17 16:03:39 +02:00
commit d8ac7fdf2a
No known key found for this signature in database
GPG key ID: 3710727397403C91
14 changed files with 203 additions and 107 deletions

View file

@ -103,6 +103,11 @@ class Account(QObject):
self._authorization_service.accessTokenChanged.connect(self._onAccessTokenChanged)
self._authorization_service.loadAuthDataFromPreferences()
@pyqtProperty(int, notify=syncStateChanged)
def syncState(self):
return self._sync_state
def setSyncState(self, service_name: str, state: int) -> None:
""" Can be used to register sync services and update account sync states

View file

@ -262,6 +262,10 @@ class CuraApplication(QtApplication):
def ultimakerCloudAccountRootUrl(self) -> str:
return UltimakerCloudConstants.CuraCloudAccountAPIRoot
@pyqtProperty(str, constant=True)
def ultimakerDigitalFactoryUrl(self) -> str:
return UltimakerCloudConstants.CuraDigitalFactoryURL
def addCommandLineOptions(self):
"""Adds command line options to the command line parser.

View file

@ -7,6 +7,7 @@
DEFAULT_CLOUD_API_ROOT = "https://api.ultimaker.com" # type: str
DEFAULT_CLOUD_API_VERSION = "1" # type: str
DEFAULT_CLOUD_ACCOUNT_API_ROOT = "https://account.ultimaker.com" # type: str
DEFAULT_DIGITAL_FACTORY_URL = "https://digitalfactory.ultimaker.com" # type: str
# Container Metadata keys
META_UM_LINKED_TO_ACCOUNT = "um_linked_to_account"
@ -32,3 +33,10 @@ try:
CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT
except ImportError:
CuraCloudAccountAPIRoot = DEFAULT_CLOUD_ACCOUNT_API_ROOT
try:
from cura.CuraVersion import CuraDigitalFactoryURL # type: ignore
if CuraDigitalFactoryURL == "":
CuraDigitalFactoryURL = DEFAULT_DIGITAL_FACTORY_URL
except ImportError:
CuraDigitalFactoryURL = DEFAULT_DIGITAL_FACTORY_URL

View file

@ -5702,7 +5702,7 @@
"minimum_value": "0",
"maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)",
"minimum_value_warning": "max(extruderValues('prime_tower_line_width')) * 2",
"maximum_value_warning": "20",
"maximum_value_warning": "42",
"settable_per_mesh": false,
"settable_per_extruder": false
},

View file

@ -1,4 +1,4 @@
// Copyright (c) 2018 Ultimaker B.V.
// Copyright (c) 2020 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@ -7,19 +7,16 @@ import QtQuick.Controls 2.3
import UM 1.4 as UM
import Cura 1.1 as Cura
Column
Item
{
property var profile: null
property var loggedIn: false
property var profileImage: ""
padding: UM.Theme.getSize("wide_margin").height
spacing: UM.Theme.getSize("wide_margin").height
property var profile: Cura.API.account.userProfile
property bool loggedIn: Cura.API.account.isLoggedIn
property var profileImage: Cura.API.account.profileImageUrl
Loader
{
id: accountOperations
anchors.horizontalCenter: parent.horizontalCenter
anchors.centerIn: parent
sourceComponent: loggedIn ? userOperations : generalOperations
}

View file

@ -131,14 +131,9 @@ Item
opacity: opened ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
padding: 0
contentItem: AccountDetails
{
id: panel
profile: Cura.API.account.userProfile
loggedIn: Cura.API.account.isLoggedIn
profileImage: Cura.API.account.profileImageUrl
}
{}
background: UM.PointingRectangle
{

View file

@ -54,6 +54,6 @@ Item
visible: hasAvatar
source: UM.Theme.getIcon("circle_outline")
sourceSize: Qt.size(parent.width, parent.height)
color: UM.Theme.getColor("account_widget_ouline_active")
color: UM.Theme.getColor("account_widget_outline_active")
}
}

View file

@ -10,7 +10,7 @@ import Cura 1.1 as Cura
Column
{
spacing: UM.Theme.getSize("default_margin").width
padding: UM.Theme.getSize("default_margin").width
Image
{
id: machinesImage

View file

@ -4,15 +4,45 @@ import QtQuick.Controls 2.3
import UM 1.4 as UM
import Cura 1.1 as Cura
Row // sync state icon + message
Row // Sync state icon + message
{
property var syncState: Cura.API.account.syncState
id: syncRow
width: childrenRect.width
height: childrenRect.height
anchors.horizontalCenter: parent.horizontalCenter
spacing: UM.Theme.getSize("narrow_margin").height
states: [
State
{
name: "idle"
when: syncState == Cura.AccountSyncState.IDLE
PropertyChanges { target: icon; source: UM.Theme.getIcon("update")}
},
State
{
name: "syncing"
when: syncState == Cura.AccountSyncState.SYNCING
PropertyChanges { target: icon; source: UM.Theme.getIcon("update") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Checking...")}
},
State
{
name: "up_to_date"
when: syncState == Cura.AccountSyncState.SUCCESS
PropertyChanges { target: icon; source: UM.Theme.getIcon("checked") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Account synced")}
},
State
{
name: "error"
when: syncState == Cura.AccountSyncState.ERROR
PropertyChanges { target: icon; source: UM.Theme.getIcon("warning_light") }
PropertyChanges { target: stateLabel; text: catalog.i18nc("@label", "Something went wrong...")}
}
]
UM.RecolorImage
{
id: icon
@ -20,7 +50,7 @@ Row // sync state icon + message
height: width
source: Cura.API.account.manualSyncEnabled ? UM.Theme.getIcon("update") : UM.Theme.getIcon("checked")
color: palette.text
color: UM.Theme.getColor("account_sync_state_icon")
RotationAnimator
{
@ -30,7 +60,7 @@ Row // sync state icon + message
to: 360
duration: 1000
loops: Animation.Infinite
running: true
running: syncState == Cura.AccountSyncState.SYNCING
// reset rotation when stopped
onRunningChanged: {
@ -50,10 +80,13 @@ Row // sync state icon + message
Label
{
id: stateLabel
text: catalog.i18nc("@state", catalog.i18nc("@label", "You are in sync with your account"))
text: catalog.i18nc("@state", catalog.i18nc("@label", "Account synced"))
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
width: contentWidth + UM.Theme.getSize("default_margin").height
height: contentHeight
verticalAlignment: Text.AlignVCenter
visible: !Cura.API.account.manualSyncEnabled
}
@ -64,8 +97,10 @@ Row // sync state icon + message
color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
verticalAlignment: Text.AlignVCenter
height: contentHeight
width: contentWidth + UM.Theme.getSize("default_margin").height
visible: Cura.API.account.manualSyncEnabled
height: visible ? accountSyncButton.intrinsicHeight : 0
MouseArea
{
@ -77,33 +112,4 @@ Row // sync state icon + message
}
}
}
signal syncStateChanged(string newState)
onSyncStateChanged: {
if(newState == Cura.AccountSyncState.IDLE){
icon.source = UM.Theme.getIcon("update")
} else if(newState == Cura.AccountSyncState.SYNCING){
icon.source = UM.Theme.getIcon("update")
stateLabel.text = catalog.i18nc("@label", "Checking...")
} else if (newState == Cura.AccountSyncState.SUCCESS) {
icon.source = UM.Theme.getIcon("checked")
stateLabel.text = catalog.i18nc("@label", "You are in sync with your account")
} else if (newState == Cura.AccountSyncState.ERROR) {
icon.source = UM.Theme.getIcon("warning_light")
stateLabel.text = catalog.i18nc("@label", "Something went wrong...")
} else {
print("Error: unexpected sync state: " + newState)
}
if(newState == Cura.AccountSyncState.SYNCING){
updateAnimator.running = true
} else {
updateAnimator.running = false
}
}
Component.onCompleted: Cura.API.account.syncStateChanged.connect(syncStateChanged)
}
}

View file

@ -9,72 +9,119 @@ import Cura 1.1 as Cura
Column
{
width: Math.max(
Math.max(title.width, accountButton.width) + 2 * UM.Theme.getSize("default_margin").width,
syncRow.width
)
spacing: UM.Theme.getSize("narrow_margin").height
topPadding: UM.Theme.getSize("default_margin").height
bottomPadding: UM.Theme.getSize("default_margin").height
width: childrenRect.width
spacing: UM.Theme.getSize("default_margin").height
SystemPalette
Item
{
id: palette
id: accountInfo
width: childrenRect.width
height: childrenRect.height
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
AvatarImage
{
id: avatar
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("main_window_header").height
height: UM.Theme.getSize("main_window_header").height
source: profile["profile_image_url"] ? profile["profile_image_url"] : ""
outlineColor: UM.Theme.getColor("main_background")
}
Rectangle
{
id: initialCircle
width: avatar.width
height: avatar.height
radius: width
anchors.verticalCenter: parent.verticalCenter
color: UM.Theme.getColor("action_button_disabled")
visible: !avatar.hasAvatar
Label
{
id: initialLabel
anchors.centerIn: parent
text: profile["username"].charAt(0).toUpperCase()
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
}
}
Column
{
anchors.left: avatar.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("narrow_margin").height
width: childrenRect.width
height: childrenRect.height
Label
{
id: username
renderType: Text.NativeRendering
text: profile.username
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
}
SyncState
{
id: syncRow
}
Label
{
id: lastSyncLabel
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a timestamp", "Last update: %1").arg(Cura.API.account.lastSyncDateTime)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
}
}
}
Label
Rectangle
{
id: title
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a username.", "Hi %1").arg(profile.username)
font: UM.Theme.getFont("large_bold")
color: UM.Theme.getColor("text")
width: parent.width
color: UM.Theme.getColor("lining")
height: UM.Theme.getSize("default_lining").height
}
SyncState {
id: syncRow
}
Label
Cura.TertiaryButton
{
id: lastSyncLabel
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering
text: catalog.i18nc("@label The argument is a timestamp", "Last update: %1").arg(Cura.API.account.lastSyncDateTime)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_medium")
}
Cura.SecondaryButton
{
id: accountButton
anchors.horizontalCenter: parent.horizontalCenter
id: cloudButton
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Ultimaker account")
text: catalog.i18nc("@button", "Ultimaker Digital Factory")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerDigitalFactoryUrl)
fixedWidthMode: false
}
Cura.TertiaryButton
{
id: accountButton
width: UM.Theme.getSize("account_button").width
height: UM.Theme.getSize("account_button").height
text: catalog.i18nc("@button", "Ultimaker Account")
onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl)
fixedWidthMode: false
}
Label
Rectangle
{
id: signOutButton
anchors.horizontalCenter: parent.horizontalCenter
text: catalog.i18nc("@button", "Sign out")
color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
MouseArea
{
anchors.fill: parent
onClicked: Cura.API.account.logout()
hoverEnabled: true
onEntered: signOutButton.font.underline = true
onExited: signOutButton.font.underline = false
}
width: parent.width
color: UM.Theme.getColor("lining")
height: UM.Theme.getSize("default_lining").height
}
Cura.TertiaryButton
{
id: signOutButton
onClicked: Cura.API.account.logout()
text: catalog.i18nc("@button", "Sign Out")
}
}

View file

@ -33,6 +33,8 @@ Button
property alias shadowEnabled: shadow.visible
property alias busy: busyIndicator.visible
property bool underlineTextOnHover: false
property alias toolTipContentAlignment: tooltip.contentAlignment
// This property is used to indicate whether the button has a fixed width or the width would depend on the contents
@ -49,6 +51,14 @@ Button
height: UM.Theme.getSize("action_button").height
hoverEnabled: true
onHoveredChanged:
{
if(underlineTextOnHover)
{
buttonText.font.underline = hovered
}
}
contentItem: Row
{
spacing: UM.Theme.getSize("narrow_margin").width

View file

@ -0,0 +1,21 @@
// Copyright (c) 2020 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2
import UM 1.4 as UM
import Cura 1.1 as Cura
Cura.ActionButton
{
shadowEnabled: true
shadowColor: enabled ? UM.Theme.getColor("secondary_button_shadow"): UM.Theme.getColor("action_button_disabled_shadow")
color: "transparent"
textColor: UM.Theme.getColor("secondary_button_text")
outlineColor: "transparent"
disabledColor: UM.Theme.getColor("action_button_disabled")
textDisabledColor: UM.Theme.getColor("action_button_disabled_text")
hoverColor: "transparent"
underlineTextOnHover: true
}

View file

@ -24,6 +24,8 @@
"main_window_header_button_text_inactive": [128, 128, 128, 255],
"account_sync_state_icon": [255, 255, 255, 204],
"machine_selector_bar": [39, 44, 48, 255],
"machine_selector_active": [39, 44, 48, 255],
"machine_selector_printer_icon": [204, 204, 204, 255],

View file

@ -183,6 +183,7 @@
"main_window_header_button_background_hovered": [117, 114, 159, 255],
"account_widget_outline_active": [70, 66, 126, 255],
"account_sync_state_icon": [25, 25, 25, 255],
"machine_selector_bar": [31, 36, 39, 255],
"machine_selector_active": [68, 72, 75, 255],