Merge branch 'main' into CURA-9422_abstract_cloud_monitor_redux

# Conflicts:
#	resources/qml/PrinterSelector/MachineListButton.qml
This commit is contained in:
c.lamboo 2022-08-31 16:05:00 +02:00
commit c73b980a3d
5 changed files with 235 additions and 137 deletions

View File

@ -94,7 +94,7 @@ class MachineAction(QObject, PluginObject):
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if plugin_path is None:
Logger.log("e", "Cannot create QML view: cannot find plugin path for plugin [%s]", self.getPluginId())
Logger.error(f"Cannot create QML view: cannot find plugin path for plugin {self.getPluginId()}")
return None
path = os.path.join(plugin_path, self._qml_url)
@ -106,7 +106,7 @@ class MachineAction(QObject, PluginObject):
def qmlPath(self) -> "QUrl":
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if plugin_path is None:
Logger.log("e", "Cannot create QML view: cannot find plugin path for plugin [%s]", self.getPluginId())
Logger.error(f"Cannot create QML view: cannot find plugin path for plugin {self.getPluginId()}")
return QUrl("")
path = os.path.join(plugin_path, self._qml_url)
return QUrl.fromLocalFile(path)

View File

@ -5,7 +5,7 @@
# online cloud connected printers are represented within this ListModel. Additional information such as the number of
# connected printers for each printer type is gathered.
from PyQt6.QtCore import Qt, QTimer
from PyQt6.QtCore import Qt, QTimer, pyqtSlot, pyqtProperty, pyqtSignal
from UM.Qt.ListModel import ListModel
from UM.Settings.ContainerStack import ContainerStack
@ -24,11 +24,14 @@ class MachineListModel(ListModel):
MetaDataRole = Qt.ItemDataRole.UserRole + 4
IsOnlineRole = Qt.ItemDataRole.UserRole + 5
MachineCountRole = Qt.ItemDataRole.UserRole + 6
IsAbstractMachine = Qt.ItemDataRole.UserRole + 7
IsAbstractMachineRole = Qt.ItemDataRole.UserRole + 7
ComponentTypeRole = Qt.ItemDataRole.UserRole + 8
def __init__(self, parent=None) -> None:
super().__init__(parent)
self._show_cloud_printers = False
self._catalog = i18nCatalog("cura")
self.addRoleName(self.NameRole, "name")
@ -37,7 +40,8 @@ class MachineListModel(ListModel):
self.addRoleName(self.MetaDataRole, "metadata")
self.addRoleName(self.IsOnlineRole, "isOnline")
self.addRoleName(self.MachineCountRole, "machineCount")
self.addRoleName(self.IsAbstractMachine, "isAbstractMachine")
self.addRoleName(self.IsAbstractMachineRole, "isAbstractMachine")
self.addRoleName(self.ComponentTypeRole, "componentType")
self._change_timer = QTimer()
self._change_timer.setInterval(200)
@ -50,6 +54,18 @@ class MachineListModel(ListModel):
CuraContainerRegistry.getInstance().containerRemoved.connect(self._onContainerChanged)
self._updateDelayed()
showCloudPrintersChanged = pyqtSignal(bool)
@pyqtProperty(bool, notify=showCloudPrintersChanged)
def showCloudPrinters(self) -> bool:
return self._show_cloud_printers
@pyqtSlot(bool)
def setShowCloudPrinters(self, show_cloud_printers: bool) -> None:
self._show_cloud_printers = show_cloud_printers
self._updateDelayed()
self.showCloudPrintersChanged.emit(show_cloud_printers)
def _onContainerChanged(self, container) -> None:
"""Handler for container added/removed events from registry"""
@ -61,13 +77,12 @@ class MachineListModel(ListModel):
self._change_timer.start()
def _update(self) -> None:
self.setItems([]) # Clear items
self.clear()
other_machine_stacks = CuraContainerRegistry.getInstance().findContainerStacks(type="machine")
abstract_machine_stacks = CuraContainerRegistry.getInstance().findContainerStacks(is_abstract_machine = "True")
abstract_machine_stacks.sort(key = lambda machine: machine.getName(), reverse = True)
for abstract_machine in abstract_machine_stacks:
definition_id = abstract_machine.definition.getId()
from cura.CuraApplication import CuraApplication
@ -77,14 +92,31 @@ class MachineListModel(ListModel):
# Create a list item for abstract machine
self.addItem(abstract_machine, len(online_machine_stacks))
other_machine_stacks.remove(abstract_machine)
if abstract_machine in online_machine_stacks:
online_machine_stacks.remove(abstract_machine)
# Create list of machines that are children of the abstract machine
for stack in online_machine_stacks:
self.addItem(stack)
if self._show_cloud_printers:
self.addItem(stack)
# Remove this machine from the other stack list
if stack in other_machine_stacks:
other_machine_stacks.remove(stack)
if len(abstract_machine_stacks) > 0:
if self._show_cloud_printers:
self.appendItem({"componentType": "HIDE_BUTTON",
"isOnline": True,
"isAbstractMachine": False,
"machineCount": 0
})
else:
self.appendItem({"componentType": "SHOW_BUTTON",
"isOnline": True,
"isAbstractMachine": False,
"machineCount": 0
})
for stack in other_machine_stacks:
self.addItem(stack)
@ -99,7 +131,9 @@ class MachineListModel(ListModel):
for connection_type in [ConnectionType.NetworkConnection.value, ConnectionType.CloudConnection.value]:
has_connection |= connection_type in container_stack.configuredConnectionTypes
self.appendItem({"name": container_stack.getName(),
self.appendItem({
"componentType": "MACHINE",
"name": container_stack.getName(),
"id": container_stack.getId(),
"metadata": container_stack.getMetaData().copy(),
"isOnline": parseBool(container_stack.getMetaDataEntry("is_online", False)) and has_connection,

View File

@ -1443,7 +1443,63 @@
"value": "0",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true,
"enabled": "top_layers > 0"
"enabled": "top_layers > 0",
"children": {
"roofing_line_width":
{
"label": "Top Surface Skin Line Width",
"description": "Width of a single line of the areas at the top of the print.",
"unit": "mm",
"minimum_value": "0.001",
"minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"default_value": 0.4,
"type": "float",
"value": "skin_line_width",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true,
"enabled": "roofing_layer_count > 0 and top_layers > 0"
},
"roofing_pattern":
{
"label": "Top Surface Skin Pattern",
"description": "The pattern of the top most layers.",
"type": "enum",
"options":
{
"lines": "Lines",
"concentric": "Concentric",
"zigzag": "Zig Zag"
},
"default_value": "lines",
"value": "top_bottom_pattern",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true,
"enabled": "roofing_layer_count > 0 and top_layers > 0"
},
"roofing_monotonic":
{
"label": "Monotonic Top Surface Order",
"description": "Print top surface lines in an ordering that causes them to always overlap with adjacent lines in a single direction. This takes slightly more time to print, but makes flat surfaces look more consistent.",
"type": "bool",
"default_value": false,
"value": "skin_monotonic",
"enabled": "roofing_layer_count > 0 and top_layers > 0 and roofing_pattern != 'concentric'",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true
},
"roofing_angles":
{
"label": "Top Surface Skin Line Directions",
"description": "A list of integer line directions to use when the top surface skin layers use the lines or zig zag pattern. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the traditional default angles (45 and 135 degrees).",
"type": "[int]",
"default_value": "[ ]",
"value": "skin_angles",
"enabled": "roofing_pattern != 'concentric' and roofing_layer_count > 0 and top_layers > 0",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true
}
}
},
"top_bottom_extruder_nr":
{
@ -6646,60 +6702,6 @@
"default_value": "middle",
"settable_per_mesh": true
},
"roofing_line_width":
{
"label": "Top Surface Skin Line Width",
"description": "Width of a single line of the areas at the top of the print.",
"unit": "mm",
"minimum_value": "0.001",
"minimum_value_warning": "0.1 + 0.4 * machine_nozzle_size",
"maximum_value_warning": "2 * machine_nozzle_size",
"default_value": 0.4,
"type": "float",
"value": "skin_line_width",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true,
"enabled": "roofing_layer_count > 0 and top_layers > 0"
},
"roofing_pattern":
{
"label": "Top Surface Skin Pattern",
"description": "The pattern of the top most layers.",
"type": "enum",
"options":
{
"lines": "Lines",
"concentric": "Concentric",
"zigzag": "Zig Zag"
},
"default_value": "lines",
"value": "top_bottom_pattern",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true,
"enabled": "roofing_layer_count > 0 and top_layers > 0"
},
"roofing_monotonic":
{
"label": "Monotonic Top Surface Order",
"description": "Print top surface lines in an ordering that causes them to always overlap with adjacent lines in a single direction. This takes slightly more time to print, but makes flat surfaces look more consistent.",
"type": "bool",
"default_value": false,
"value": "skin_monotonic",
"enabled": "roofing_layer_count > 0 and top_layers > 0 and roofing_pattern != 'concentric'",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true
},
"roofing_angles":
{
"label": "Top Surface Skin Line Directions",
"description": "A list of integer line directions to use when the top surface skin layers use the lines or zig zag pattern. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the traditional default angles (45 and 135 degrees).",
"type": "[int]",
"default_value": "[ ]",
"value": "skin_angles",
"enabled": "roofing_pattern != 'concentric' and roofing_layer_count > 0 and top_layers > 0",
"limit_to_extruder": "roofing_extruder_nr",
"settable_per_mesh": true
},
"infill_enable_travel_optimization":
{
"label": "Infill Travel Optimization",

View File

@ -7,81 +7,133 @@ import QtQuick.Controls 2.3
import UM 1.5 as UM
import Cura 1.0 as Cura
Button
{
id: machineListButton
Loader {
id: loader
width: parent.width
height: UM.Theme.getSize("large_button").height
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
checkable: true
hoverEnabled: true
sourceComponent: {
switch (model.componentType) {
case "HIDE_BUTTON":
hideButtonComponent
break;
case "SHOW_BUTTON":
showButtonComponent
break;
case "MACHINE":
machineListButtonComponent
break;
default:
}
}
property var onClicked
contentItem: Item
Component
{
width: machineListButton.width - machineListButton.leftPadding - machineListButton.rightPadding
height: UM.Theme.getSize("action_button").height
UM.ColorImage
id: hideButtonComponent
Cura.TertiaryButton
{
id: printerIcon
height: UM.Theme.getSize("medium_button").height
width: UM.Theme.getSize("medium_button").width
color: UM.Theme.getColor("machine_selector_printer_icon")
visible: model.isAbstractMachine || !model.isOnline
source: model.isAbstractMachine ? UM.Theme.getIcon("PrinterTriple", "medium") : UM.Theme.getIcon("Printer", "medium")
anchors
{
left: parent.left
verticalCenter: parent.verticalCenter
}
}
UM.Label
{
id: buttonText
anchors
{
left: printerIcon.right
right: printerCount.left
verticalCenter: parent.verticalCenter
leftMargin: UM.Theme.getSize("default_margin").width
}
text: machineListButton.text
font: model.isAbstractMachine ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")
visible: text != ""
elide: Text.ElideRight
}
Rectangle
{
id: printerCount
color: UM.Theme.getColor("background_2")
radius: height
width: height
anchors
{
right: parent.right
top: buttonText.top
bottom: buttonText.bottom
}
visible: model.isAbstractMachine ? model.isAbstractMachine : false
UM.Label
{
text: model.machineCount ? model.machineCount : ""
anchors.centerIn: parent
font: UM.Theme.getFont("default_bold")
}
text: catalog.i18nc("@label", "Hide all connected printers")
height: UM.Theme.getSize("large_button").height
onClicked: if (loader.onClicked) loader.onClicked()
iconSource: UM.Theme.getIcon("ChevronSingleUp")
width: parent.width
}
}
background: Rectangle
Component
{
id: backgroundRect
color: machineListButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent"
id: showButtonComponent
Cura.TertiaryButton
{
text: catalog.i18nc("@label", "Show all connected printers")
height: UM.Theme.getSize("large_button").height
onClicked: if (loader.onClicked) loader.onClicked()
iconSource: UM.Theme.getIcon("ChevronSingleDown")
width: parent.width
}
}
Component
{
id: machineListButtonComponent
Button
{
id: machineListButton
onClicked: if (loader.onClicked) loader.onClicked()
width: parent.width
height: UM.Theme.getSize("large_button").height
leftPadding: UM.Theme.getSize("default_margin").width
rightPadding: UM.Theme.getSize("default_margin").width
checkable: true
hoverEnabled: true
contentItem: Item
{
width: machineListButton.width - machineListButton.leftPadding - machineListButton.rightPadding
height: UM.Theme.getSize("action_button").height
UM.ColorImage
{
id: printerIcon
height: UM.Theme.getSize("medium_button").height
width: UM.Theme.getSize("medium_button").width
color: UM.Theme.getColor("machine_selector_printer_icon")
visible: model.isAbstractMachine || !model.isOnline
source: model.isAbstractMachine ? UM.Theme.getIcon("PrinterTriple", "medium") : UM.Theme.getIcon("Printer", "medium")
anchors
{
left: parent.left
verticalCenter: parent.verticalCenter
}
}
UM.Label
{
id: buttonText
anchors
{
left: printerIcon.right
right: printerCount.left
verticalCenter: parent.verticalCenter
leftMargin: UM.Theme.getSize("default_margin").width
}
text: model.name ? model.name : ""
font: model.isAbstractMachine ? UM.Theme.getFont("medium_bold") : UM.Theme.getFont("medium")
visible: text != ""
elide: Text.ElideRight
}
Rectangle
{
id: printerCount
color: UM.Theme.getColor("background_2")
radius: height
width: height
anchors
{
right: parent.right
top: buttonText.top
bottom: buttonText.bottom
}
visible: model.isAbstractMachine ? model.isAbstractMachine : false
UM.Label
{
text: model.machineCount ? model.machineCount : ""
anchors.centerIn: parent
font: UM.Theme.getFont("default_bold")
}
}
}
background: Rectangle
{
id: backgroundRect
color: machineListButton.hovered ? UM.Theme.getColor("action_button_hovered") : "transparent"
}
}
}
}

View File

@ -22,8 +22,8 @@ ListView
section.delegate: UM.Label
{
text: section == "true" ? catalog.i18nc("@label", "Connected printers") : catalog.i18nc("@label", "Other printers")
width: parent.width - scrollBar.width
height: UM.Theme.getSize("action_button").height
width: parent.width - scrollBar.width
leftPadding: UM.Theme.getSize("default_margin").width
font: UM.Theme.getFont("medium")
color: UM.Theme.getColor("text_medium")
@ -31,13 +31,23 @@ ListView
delegate: MachineListButton
{
text: model.name ? model.name : ""
width: listView.width - scrollBar.width
onClicked:
onClicked: function()
{
toggleContent()
Cura.MachineManager.setActiveMachine(model.id)
switch (model.componentType) {
case "HIDE_BUTTON":
listView.model.setShowCloudPrinters(false);
break;
case "SHOW_BUTTON":
listView.model.setShowCloudPrinters(true);
break;
case "MACHINE":
toggleContent()
Cura.MachineManager.setActiveMachine(model.id)
break;
default:
}
}
}
}