Merge pull request #5521 from Ultimaker/CURA-6151-Notify-updates-from-marketplace

Notify updates from marketplace
This commit is contained in:
Lipu Fei 2019-04-01 13:19:37 +02:00 committed by GitHub
commit b28e98f288
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 135 additions and 60 deletions

View File

@ -10,7 +10,7 @@ import Cura 1.1 as Cura
Column Column
{ {
property bool installed: toolbox.isInstalled(model.id) property bool installed: toolbox.isInstalled(model.id)
property bool canUpdate: toolbox.canUpdate(model.id) property bool canUpdate: CuraApplication.getPackageManager().packagesWithUpdate.indexOf(model.id) != -1
property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn
property var packageData property var packageData
@ -112,11 +112,9 @@ Column
{ {
target: toolbox target: toolbox
onInstallChanged: installed = toolbox.isInstalled(model.id) onInstallChanged: installed = toolbox.isInstalled(model.id)
onMetadataChanged: canUpdate = toolbox.canUpdate(model.id)
onFilterChanged: onFilterChanged:
{ {
installed = toolbox.isInstalled(model.id) installed = toolbox.isInstalled(model.id)
canUpdate = toolbox.canUpdate(model.id)
} }
} }
} }

View File

@ -1,9 +1,11 @@
// Copyright (c) 2018 Ultimaker B.V. // Copyright (c) 2018 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher. // Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2 import QtQuick 2.10
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import UM 1.1 as UM
import UM 1.4 as UM
import Cura 1.0 as Cura
Item Item
{ {
@ -50,6 +52,7 @@ Item
} }
} }
} }
ToolboxTabButton ToolboxTabButton
{ {
id: installedTabButton id: installedTabButton
@ -62,7 +65,25 @@ Item
rightMargin: UM.Theme.getSize("default_margin").width rightMargin: UM.Theme.getSize("default_margin").width
} }
onClicked: toolbox.viewCategory = "installed" onClicked: toolbox.viewCategory = "installed"
width: UM.Theme.getSize("toolbox_header_tab").width + marketplaceNotificationIcon.width - UM.Theme.getSize("default_margin").width
} }
Cura.NotificationIcon
{
id: marketplaceNotificationIcon
visible: CuraApplication.getPackageManager().packagesWithUpdate.length > 0
anchors.right: installedTabButton.right
anchors.verticalCenter: installedTabButton.verticalCenter
labelText:
{
const itemCount = CuraApplication.getPackageManager().packagesWithUpdate.length
return itemCount > 9 ? "9+" : itemCount
}
}
ToolboxShadow ToolboxShadow
{ {
anchors.top: bar.bottom anchors.top: bar.bottom

View File

@ -10,7 +10,7 @@ import Cura 1.1 as Cura
Column Column
{ {
property bool canUpdate: false property bool canUpdate: CuraApplication.getPackageManager().packagesWithUpdate.indexOf(model.id) != -1
property bool canDowngrade: false property bool canDowngrade: false
property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn property bool loginRequired: model.login_required && !Cura.API.account.isLoggedIn
width: UM.Theme.getSize("toolbox_action_button").width width: UM.Theme.getSize("toolbox_action_button").width
@ -83,7 +83,6 @@ Column
target: toolbox target: toolbox
onMetadataChanged: onMetadataChanged:
{ {
canUpdate = toolbox.canUpdate(model.id)
canDowngrade = toolbox.canDowngrade(model.id) canDowngrade = toolbox.canDowngrade(model.id)
} }
} }

View File

@ -9,14 +9,17 @@ Button
{ {
id: control id: control
property bool active: false property bool active: false
hoverEnabled: true
implicitWidth: UM.Theme.getSize("toolbox_header_tab").width
implicitHeight: UM.Theme.getSize("toolbox_header_tab").height
background: Item background: Item
{ {
implicitWidth: UM.Theme.getSize("toolbox_header_tab").width id: backgroundItem
implicitHeight: UM.Theme.getSize("toolbox_header_tab").height
Rectangle Rectangle
{ {
id: highlight
visible: control.active visible: control.active
color: UM.Theme.getColor("primary") color: UM.Theme.getColor("primary")
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
@ -24,28 +27,42 @@ Button
height: UM.Theme.getSize("toolbox_header_highlight").height height: UM.Theme.getSize("toolbox_header_highlight").height
} }
} }
contentItem: Label contentItem: Label
{ {
id: label id: label
text: control.text text: control.text
color: color: UM.Theme.getColor("toolbox_header_button_text_inactive")
{ font: UM.Theme.getFont("medium")
if(control.hovered)
{
return UM.Theme.getColor("toolbox_header_button_text_hovered");
}
if(control.active)
{
return UM.Theme.getColor("toolbox_header_button_text_active");
}
else
{
return UM.Theme.getColor("toolbox_header_button_text_inactive");
}
}
font: control.enabled ? (control.active ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")) : UM.Theme.getFont("default_italic")
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
renderType: Text.NativeRendering renderType: Text.NativeRendering
} }
states:
[
State
{
name: "disabled"
when: !control.enabled
PropertyChanges
{
target: label
font: UM.Theme.getFont("default_italic")
}
},
State
{
name: "active"
when: control.active
PropertyChanges
{
target: label
font: UM.Theme.getFont("medium_bold")
color: UM.Theme.getColor("toolbox_header_button_text_active")
}
}
]
} }

View File

@ -190,8 +190,10 @@ class Toolbox(QObject, Extension):
"packages": QUrl("{base_url}/packages".format(base_url = self._api_url)) "packages": QUrl("{base_url}/packages".format(base_url = self._api_url))
} }
@pyqtSlot() # Request the latest and greatest!
def browsePackages(self) -> None: self._fetchPackageData()
def _fetchPackageData(self):
# Create the network manager: # Create the network manager:
# This was formerly its own function but really had no reason to be as # This was formerly its own function but really had no reason to be as
# it was never called more than once ever. # it was never called more than once ever.
@ -209,6 +211,10 @@ class Toolbox(QObject, Extension):
# Gather installed packages: # Gather installed packages:
self._updateInstalledModels() self._updateInstalledModels()
@pyqtSlot()
def browsePackages(self) -> None:
self._fetchPackageData()
if not self._dialog: if not self._dialog:
self._dialog = self._createDialog("Toolbox.qml") self._dialog = self._createDialog("Toolbox.qml")
@ -455,36 +461,6 @@ class Toolbox(QObject, Extension):
break break
return remote_package return remote_package
# Checks
# --------------------------------------------------------------------------
@pyqtSlot(str, result = bool)
def canUpdate(self, package_id: str) -> bool:
local_package = self._package_manager.getInstalledPackageInfo(package_id)
if local_package is None:
local_package = self.getOldPluginPackageMetadata(package_id)
if local_package is None:
return False
remote_package = self.getRemotePackage(package_id)
if remote_package is None:
return False
local_version = Version(local_package["package_version"])
remote_version = Version(remote_package["package_version"])
can_upgrade = False
if remote_version > local_version:
can_upgrade = True
# A package with the same version can be built to have different SDK versions. So, for a package with the same
# version, we also need to check if the current one has a lower SDK version. If so, this package should also
# be upgradable.
elif remote_version == local_version:
# First read sdk_version_semver. If that doesn't exist, read just sdk_version (old version system).
remote_sdk_version = Version(remote_package.get("sdk_version_semver", remote_package.get("sdk_version", 0)))
local_sdk_version = Version(local_package.get("sdk_version_semver", local_package.get("sdk_version", 0)))
can_upgrade = local_sdk_version < remote_sdk_version
return can_upgrade
@pyqtSlot(str, result = bool) @pyqtSlot(str, result = bool)
def canDowngrade(self, package_id: str) -> bool: def canDowngrade(self, package_id: str) -> bool:
# If the currently installed version is higher than the bundled version (if present), the we can downgrade # If the currently installed version is higher than the bundled version (if present), the we can downgrade
@ -636,6 +612,7 @@ class Toolbox(QObject, Extension):
self._models[response_type].setFilter({"type": "plugin"}) self._models[response_type].setFilter({"type": "plugin"})
self.reBuildMaterialsModels() self.reBuildMaterialsModels()
self.reBuildPluginsModels() self.reBuildPluginsModels()
self._notifyPackageManager()
elif response_type is "authors": elif response_type is "authors":
self._models[response_type].setFilter({"package_types": "material"}) self._models[response_type].setFilter({"package_types": "material"})
self._models[response_type].setFilter({"tags": "generic"}) self._models[response_type].setFilter({"tags": "generic"})
@ -656,6 +633,11 @@ class Toolbox(QObject, Extension):
# Ignore any operation that is not a get operation # Ignore any operation that is not a get operation
pass pass
# This function goes through all known remote versions of a package and notifies the package manager of this change
def _notifyPackageManager(self):
for package in self._server_response_data["packages"]:
self._package_manager.addAvailablePackageVersion(package["package_id"], Version(package["package_version"]))
def _onDownloadProgress(self, bytes_sent: int, bytes_total: int) -> None: def _onDownloadProgress(self, bytes_sent: int, bytes_total: int) -> None:
if bytes_total > 0: if bytes_total > 0:
new_progress = bytes_sent / bytes_total * 100 new_progress = bytes_sent / bytes_total * 100

View File

@ -117,6 +117,25 @@ Item
rightMargin: UM.Theme.getSize("default_margin").width rightMargin: UM.Theme.getSize("default_margin").width
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
Cura.NotificationIcon
{
id: marketplaceNotificationIcon
anchors
{
top: parent.top
right: parent.right
rightMargin: (-0.5 * width) | 0
topMargin: (-0.5 * height) | 0
}
visible: CuraApplication.getPackageManager().packagesWithUpdate.length > 0
labelText:
{
const itemCount = CuraApplication.getPackageManager().packagesWithUpdate.length
return itemCount > 9 ? "9+" : itemCount
}
}
} }
AccountWidget AccountWidget

View File

@ -0,0 +1,35 @@
// Copyright (c) 2019 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
import QtQuick.Controls 2.3
import UM 1.4 as UM
//
// A notification icon which is a circle with a number at the center, that can be used to indicate, for example, how
// many new messages that are available.
//
Rectangle
{
id: notificationIcon
color: UM.Theme.getColor("notification_icon")
width: UM.Theme.getSize("notification_icon").width
height: UM.Theme.getSize("notification_icon").height
radius: (0.5 * width) | 0
property alias labelText: notificationLabel.text
property alias labelFont: notificationLabel.font
Label
{
id: notificationLabel
anchors.centerIn: parent
anchors.fill: parent
color: UM.Theme.getColor("primary_text")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("small")
}
}

View File

@ -17,3 +17,5 @@ SettingView 1.0 SettingView.qml
ProfileMenu 1.0 ProfileMenu.qml ProfileMenu 1.0 ProfileMenu.qml
CheckBoxWithTooltip 1.0 CheckBoxWithTooltip.qml CheckBoxWithTooltip 1.0 CheckBoxWithTooltip.qml
ToolTip 1.0 ToolTip.qml ToolTip 1.0 ToolTip.qml
NotificationIcon 1.0 NotificationIcon.qml

View File

@ -214,7 +214,6 @@
"toolbox_header_button_text_active": [255, 255, 255, 255], "toolbox_header_button_text_active": [255, 255, 255, 255],
"toolbox_header_button_text_inactive": [128, 128, 128, 255], "toolbox_header_button_text_inactive": [128, 128, 128, 255],
"toolbox_header_button_text_hovered": [255, 255, 255, 255],
"monitor_printer_family_tag": [86, 86, 106, 255], "monitor_printer_family_tag": [86, 86, 106, 255],
"monitor_text_primary": [229, 229, 229, 255], "monitor_text_primary": [229, 229, 229, 255],

View File

@ -189,6 +189,8 @@
"toolbar_background": [255, 255, 255, 255], "toolbar_background": [255, 255, 255, 255],
"notification_icon": [255, 0, 0, 255],
"printer_type_label_background": [228, 228, 242, 255], "printer_type_label_background": [228, 228, 242, 255],
"text": [25, 25, 25, 255], "text": [25, 25, 25, 255],
@ -384,7 +386,6 @@
"toolbox_header_button_text_active": [0, 0, 0, 255], "toolbox_header_button_text_active": [0, 0, 0, 255],
"toolbox_header_button_text_inactive": [0, 0, 0, 255], "toolbox_header_button_text_inactive": [0, 0, 0, 255],
"toolbox_header_button_text_hovered": [0, 0, 0, 255],
"favorites_header_bar": [245, 245, 245, 255], "favorites_header_bar": [245, 245, 245, 255],
"favorites_header_hover": [245, 245, 245, 255], "favorites_header_hover": [245, 245, 245, 255],
@ -595,6 +596,8 @@
"toolbox_action_button": [8.0, 2.5], "toolbox_action_button": [8.0, 2.5],
"toolbox_loader": [2.0, 2.0], "toolbox_loader": [2.0, 2.0],
"notification_icon": [1.4, 1.4],
"avatar_image": [6.8, 6.8], "avatar_image": [6.8, 6.8],
"monitor_config_override_box": [1.0, 14.0], "monitor_config_override_box": [1.0, 14.0],