Merge branch 'master' into feature-backup-manager

* master:
  Adds release notes link in version upgrade messagebox CURA-5348
  CURA-5385 Project summary should use scroll view
  CURA-5296 Small QML bug fix
  Enabled drag-n-drop for curapackages
  CURA-5296 Added "canDowngrade" functionality
  Fix CURA_PACKAGES_VERSION
  CURA-5254 Keep track of the latest manual entry key, so it is then selected in the list.
  CURA-5296 Improve button styling
  Add CURA_PACKAGES_VERSION to CMakeLists.txt
  Add CuraPackageVersion
  Remove extra "if" statement and unused code
  Fix support blocker on older (legacy) opengl
  Correct the test to hide bed temperature when no heated bed is present.
This commit is contained in:
ChrisTerBeke 2018-05-22 19:03:09 +02:00
commit a91916cc1d
No known key found for this signature in database
GPG key ID: A49F1AB9D7E0C263
17 changed files with 398 additions and 259 deletions

View file

@ -9,7 +9,6 @@ import UM 1.1 as UM
Item
{
id: tile
property bool installed: toolbox.isInstalled(model.id)
width: detailList.width - UM.Theme.getSize("wide_margin").width
height: normalData.height + compatibilityChart.height + 4 * UM.Theme.getSize("default_margin").height
Item
@ -46,7 +45,7 @@ Item
}
}
Item
ToolboxDetailTileActions
{
id: controls
anchors.right: tile.right
@ -54,28 +53,6 @@ Item
width: childrenRect.width
height: childrenRect.height
ToolboxProgressButton
{
id: installButton
active: toolbox.isDownloading && toolbox.activePackage == model
complete: tile.installed
readyAction: function()
{
toolbox.activePackage = model
toolbox.startDownload(model.download_url)
}
activeAction: function()
{
toolbox.cancelDownload()
}
completeAction: function()
{
toolbox.viewCategory = "installed"
}
// Don't allow installing while another download is running
enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model)
opacity: enabled ? 1.0 : 0.5
}
}
ToolboxCompatibilityChart
@ -94,9 +71,4 @@ Item
anchors.top: compatibilityChart.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height + UM.Theme.getSize("wide_margin").height //Normal margin for spacing after chart, wide margin between items.
}
Connections
{
target: toolbox
onInstallChanged: installed = toolbox.isInstalled(model.id)
}
}

View file

@ -0,0 +1,66 @@
// Copyright (c) 2018 Ultimaker B.V.
// Toolbox is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import UM 1.1 as UM
Column
{
property bool installed: toolbox.isInstalled(model.id)
property bool canUpdate: toolbox.canUpdate(model.id)
width: UM.Theme.getSize("toolbox_action_button").width
spacing: UM.Theme.getSize("narrow_margin").height
ToolboxProgressButton
{
id: installButton
active: toolbox.isDownloading && toolbox.activePackage == model
complete: installed
readyAction: function()
{
toolbox.activePackage = model
toolbox.startDownload(model.download_url)
}
activeAction: function()
{
toolbox.cancelDownload()
}
completeAction: function()
{
toolbox.viewCategory = "installed"
}
// Don't allow installing while another download is running
enabled: installed || !(toolbox.isDownloading && toolbox.activePackage != model)
opacity: enabled ? 1.0 : 0.5
}
ToolboxProgressButton
{
id: updateButton
active: toolbox.isDownloading && toolbox.activePackage == model
readyLabel: catalog.i18nc("@action:button", "Update")
activeLabel: catalog.i18nc("@action:button", "Updating")
completeLabel: catalog.i18nc("@action:button", "Updated")
readyAction: function()
{
toolbox.activePackage = model
toolbox.update(model.id)
}
activeAction: function()
{
toolbox.cancelDownload()
}
// Don't allow installing while another download is running
enabled: !(toolbox.isDownloading && toolbox.activePackage != model)
opacity: enabled ? 1.0 : 0.5
visible: installed && canUpdate
}
Connections
{
target: toolbox
onInstallChanged: installed = toolbox.isInstalled(model.id)
onMetadataChanged: canUpdate = toolbox.canUpdate(model.id)
}
}

View file

@ -10,7 +10,6 @@ Item
{
height: UM.Theme.getSize("toolbox_installed_tile").height
width: parent.width
property bool canUpdate: false
property bool isEnabled: true
Rectangle
@ -109,7 +108,6 @@ Item
{
target: toolbox
onEnabledChanged: isEnabled = toolbox.isEnabled(model.id)
onMetadataChanged: canUpdate = toolbox.canUpdate(model.id)
}
}
}

View file

@ -8,6 +8,8 @@ import UM 1.1 as UM
Column
{
property bool canUpdate: false
property bool canDowngrade: false
width: UM.Theme.getSize("toolbox_action_button").width
spacing: UM.Theme.getSize("narrow_margin").height
@ -36,7 +38,7 @@ Column
Button
{
id: removeButton
text: catalog.i18nc("@action:button", "Uninstall")
text: canDowngrade ? catalog.i18nc("@action:button", "Downgrade") : catalog.i18nc("@action:button", "Uninstall")
visible: !model.is_bundled
enabled: !toolbox.isDownloading
style: ButtonStyle
@ -49,7 +51,17 @@ Column
border
{
width: UM.Theme.getSize("default_lining").width
color: UM.Theme.getColor("lining")
color:
{
if (control.hovered)
{
return UM.Theme.getColor("primary_hover")
}
else
{
return UM.Theme.getColor("lining")
}
}
}
}
label: Label
@ -58,8 +70,18 @@ Column
color: UM.Theme.getColor("text")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font: UM.Theme.getFont("default")
}
}
onClicked: toolbox.uninstall(model.id)
Connections
{
target: toolbox
onMetadataChanged:
{
canUpdate = toolbox.canUpdate(model.id)
canDowngrade = toolbox.canDowngrade(model.id)
}
}
}
}

View file

@ -68,7 +68,7 @@ Item
{
if (base.complete)
{
return UM.Theme.getColor("action_button_disabled")
return "transparent"
}
else
{
@ -82,6 +82,31 @@ Item
}
}
}
border
{
width:
{
if (base.complete)
{
UM.Theme.getSize("default_lining").width
}
else
{
return 0
}
}
color:
{
if (control.hovered)
{
return UM.Theme.getColor("primary_hover")
}
else
{
return UM.Theme.getColor("lining")
}
}
}
}
label: Label
{
@ -90,7 +115,7 @@ Item
{
if (base.complete)
{
return UM.Theme.getColor("action_button_disabled_text")
return UM.Theme.getColor("text")
}
else
{
@ -106,7 +131,17 @@ Item
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font: UM.Theme.getFont("default_bold")
font:
{
if (base.complete)
{
return UM.Theme.getFont("default")
}
else
{
return UM.Theme.getFont("default_bold")
}
}
}
}
}

View file

@ -318,6 +318,20 @@ class Toolbox(QObject, Extension):
remote_version = Version(remote_package["package_version"])
return remote_version > local_version
@pyqtSlot(str, result=bool)
def canDowngrade(self, package_id: str) -> bool:
local_package = self._package_manager.getInstalledPackageInfo(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"])
return remote_version < local_version
@pyqtSlot(str, result = bool)
def isInstalled(self, package_id: str) -> bool:
return self._package_manager.isPackageInstalled(package_id)

View file

@ -45,6 +45,8 @@ class DiscoverUM3Action(MachineAction):
@pyqtSlot()
def reset(self):
Logger.log("d", "Reset the list of found devices.")
if self._network_plugin:
self._network_plugin.resetLastManualDevice()
self.discoveredDevicesChanged.emit()
@pyqtSlot()
@ -83,15 +85,8 @@ class DiscoverUM3Action(MachineAction):
@pyqtProperty("QVariantList", notify = discoveredDevicesChanged)
def foundDevices(self):
if self._network_plugin:
# TODO: Check if this needs to stay.
if Application.getInstance().getGlobalContainerStack():
global_printer_type = Application.getInstance().getGlobalContainerStack().getBottom().getId()
else:
global_printer_type = "unknown"
printers = list(self._network_plugin.getDiscoveredDevices().values())
# TODO; There are still some testing printers that don't have a correct printer type, so don't filter out unkown ones just yet.
#printers = [printer for printer in printers if printer.printerType == global_printer_type or printer.printerType == "unknown"]
printers.sort(key = lambda k: k.name)
return printers
else:
@ -138,7 +133,7 @@ class DiscoverUM3Action(MachineAction):
self._network_plugin.reCheckConnections()
@pyqtSlot(result = str)
def getStoredKey(self):
def getStoredKey(self) -> str:
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
meta_data = global_container_stack.getMetaData()
@ -147,6 +142,12 @@ class DiscoverUM3Action(MachineAction):
return ""
@pyqtSlot(result = str)
def getLastManualEntryKey(self) -> str:
if self._network_plugin:
return self._network_plugin.getLastManualDevice()
return ""
@pyqtSlot(str, result = bool)
def existsKey(self, key) -> bool:
return Application.getInstance().getMachineManager().existNetworkInstances(network_key = key)

View file

@ -158,7 +158,10 @@ Cura.MachineAction
model: manager.foundDevices
onModelChanged:
{
var selectedKey = manager.getStoredKey();
var selectedKey = manager.getLastManualEntryKey()
// If there is no last manual entry key, then we select the stored key (if any)
if (selectedKey == "")
selectedKey = manager.getStoredKey()
for(var i = 0; i < model.length; i++) {
if(model[i].key == selectedKey)
{

View file

@ -60,6 +60,9 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
self._manual_instances = self._preferences.getValue("um3networkprinting/manual_instances").split(",")
# Store the last manual entry key
self._last_manual_entry_key = "" # type: str
# The zero-conf service changed requests are handled in a separate thread, so we can re-schedule the requests
# which fail to get detailed service info.
# Any new or re-scheduled requests will be appended to the request queue, and the handling thread will pick
@ -72,6 +75,12 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
def getDiscoveredDevices(self):
return self._discovered_devices
def getLastManualDevice(self) -> str:
return self._last_manual_entry_key
def resetLastManualDevice(self) -> None:
self._last_manual_entry_key = ""
## Start looking for devices on network.
def start(self):
self.startDiscovery()
@ -93,6 +102,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
for address in self._manual_instances:
if address:
self.addManualDevice(address)
self.resetLastManualDevice()
def reCheckConnections(self):
active_machine = Application.getInstance().getGlobalContainerStack()
@ -136,6 +146,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
if not address:
address = self._discovered_devices[key].ipAddress
self._onRemoveDevice(key)
self.resetLastManualDevice()
if address in self._manual_instances:
self._manual_instances.remove(address)
@ -157,6 +168,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
if instance_name not in self._discovered_devices:
# Add a preliminary printer instance
self._onAddDevice(instance_name, address, properties)
self._last_manual_entry_key = instance_name
self._checkManualDevice(address)