WIP: Add printers via network

This commit is contained in:
Lipu Fei 2019-03-08 11:02:30 +01:00
parent a55808b24a
commit 940a833e73
9 changed files with 145 additions and 46 deletions

View file

@ -114,6 +114,8 @@ from cura.Settings.CuraFormulaFunctions import CuraFormulaFunctions
from cura.ObjectsModel import ObjectsModel from cura.ObjectsModel import ObjectsModel
from cura.Machines.Models.DiscoveredPrintersModel import DiscoveredPrinterModel
from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutputDevice import PrinterOutputDevice
from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage from cura.PrinterOutput.NetworkMJPGImage import NetworkMJPGImage
@ -210,6 +212,8 @@ class CuraApplication(QtApplication):
self._cura_scene_controller = None self._cura_scene_controller = None
self._machine_error_checker = None self._machine_error_checker = None
self._discovered_printer_model = DiscoveredPrinterModel(self)
self._welcome_pages_model = WelcomePagesModel(self) self._welcome_pages_model = WelcomePagesModel(self)
self._quality_profile_drop_down_menu_model = None self._quality_profile_drop_down_menu_model = None
@ -846,6 +850,10 @@ class CuraApplication(QtApplication):
# Hide the splash screen # Hide the splash screen
self.closeSplash() self.closeSplash()
@pyqtSlot(result = QObject)
def getDiscoveredPrinterModel(self, *args) -> "DiscoveredPrinterModel":
return self._discovered_printer_model
@pyqtSlot(result = QObject) @pyqtSlot(result = QObject)
def getSettingVisibilityPresetsModel(self, *args) -> SettingVisibilityPresetsModel: def getSettingVisibilityPresetsModel(self, *args) -> SettingVisibilityPresetsModel:
return self._setting_visibility_presets_model return self._setting_visibility_presets_model
@ -1003,6 +1011,8 @@ class CuraApplication(QtApplication):
qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel") qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
qmlRegisterType(MachineManagementModel, "Cura", 1, 0, "MachineManagementModel") qmlRegisterType(MachineManagementModel, "Cura", 1, 0, "MachineManagementModel")
qmlRegisterType(DiscoveredPrinterModel, "Cura", 1, 0, "DiscoveredPrinterModel")
qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0, qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0,
"QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel) "QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel)
qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0, qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,

View file

@ -0,0 +1,104 @@
from typing import Callable, Optional, TYPE_CHECKING
from PyQt5.QtCore import pyqtSlot, pyqtProperty, pyqtSignal, QObject
from UM.Logger import Logger
if TYPE_CHECKING:
from PyQt5.QtCore import QObject
class DiscoveredPrinter(QObject):
def __init__(self, ip_address: str, key: str, name: str, create_callback: Callable[[str], None], machine_type: str,
device, parent = None) -> None:
super().__init__(parent)
self._ip_address = ip_address
self._key = key
self._name = name
self._create_callback = create_callback
self._machine_type = machine_type
self._device = device
nameChanged = pyqtSignal()
@pyqtProperty(str, notify = nameChanged)
def name(self) -> str:
return self._name
def setName(self, name: str) -> None:
if self._name != name:
self._name = name
self.nameChanged.emit()
machineTypeChanged = pyqtSignal()
@pyqtProperty(str, notify = machineTypeChanged)
def machine_type(self) -> str:
return self._machine_type
def setMachineType(self, machine_type: str) -> None:
if self._machine_type != machine_type:
self._machine_type = machine_type
self.machineTypeChanged.emit()
@pyqtProperty(QObject, constant = True)
def device(self):
return self._device
#
# Discovered printers are all the printers that were found on the network, which provide a more convenient way
# to add networked printers (Plugin finds a bunch of printers, user can select one from the list, plugin can then
# add that printer to Cura as the active one).
#
class DiscoveredPrinterModel(QObject):
def __init__(self, parent: Optional["QObject"]) -> None:
super().__init__(parent)
self._discovered_printer_dict = dict()
discoveredPrintersChanged = pyqtSignal()
@pyqtProperty(list, notify = discoveredPrintersChanged)
def discovered_printers(self) -> "list":
item_list = list(x for x in self._discovered_printer_dict.values())
item_list.sort(key = lambda x: x.name)
return item_list
def addDiscoveredPrinter(self, ip_address: str, key: str, name: str, create_callback: Callable[[str], None],
machine_type: str, device) -> None:
if ip_address in self._discovered_printer_dict:
Logger.log("e", "+++++++++++++ printer with ip [%s] has already been added", ip_address)
return
discovered_printer = DiscoveredPrinter(ip_address, key, name, create_callback, machine_type, device, parent = self)
self._discovered_printer_dict[ip_address] = discovered_printer
self.discoveredPrintersChanged.emit()
def updateDiscoveredPrinter(self, ip_address: str,
name: Optional[str] = None,
machine_type: Optional[str] = None) -> None:
if ip_address not in self._discovered_printer_dict:
Logger.log("e", "+++++++++++++ printer with ip [%s] is not known", ip_address)
return
item = self._discovered_printer_dict[ip_address]
if name is not None:
item.setName(name)
if machine_type is not None:
item.setMachineType(machine_type)
def removeDiscoveredPrinter(self, ip_address: str) -> None:
if ip_address not in self._discovered_printer_dict:
Logger.log("i", "Key [%s] does not exist in the discovered printers list.", ip_address)
return
del self._discovered_printer_dict[ip_address]
self.discoveredPrintersChanged.emit()
@pyqtSlot("QVariant")
def createMachineFromDiscoveredPrinter(self, discovered_printer: "DiscoveredPrinter") -> None:
discovered_printer.create_callback()

View file

@ -4,7 +4,7 @@
import time import time
import re import re
import unicodedata import unicodedata
from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast, NamedTuple, Callable from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@ -49,8 +49,6 @@ if TYPE_CHECKING:
from cura.Machines.QualityChangesGroup import QualityChangesGroup from cura.Machines.QualityChangesGroup import QualityChangesGroup
from cura.Machines.QualityGroup import QualityGroup from cura.Machines.QualityGroup import QualityGroup
DiscoveredPrinter = NamedTuple("DiscoveredPrinter", [("key", str), ("name", str), ("create_callback", Callable[[str], None]), ("machine_type", "str")])
class MachineManager(QObject): class MachineManager(QObject):
def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None: def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
@ -136,9 +134,6 @@ class MachineManager(QObject):
self.globalContainerChanged.connect(self.printerConnectedStatusChanged) self.globalContainerChanged.connect(self.printerConnectedStatusChanged)
self.outputDevicesChanged.connect(self.printerConnectedStatusChanged) self.outputDevicesChanged.connect(self.printerConnectedStatusChanged)
# This will contain all discovered network printers
self._discovered_printers = {} # type: Dict[str, DiscoveredPrinter]
activeQualityGroupChanged = pyqtSignal() activeQualityGroupChanged = pyqtSignal()
activeQualityChangesGroupChanged = pyqtSignal() activeQualityChangesGroupChanged = pyqtSignal()
@ -178,30 +173,6 @@ class MachineManager(QObject):
self.outputDevicesChanged.emit() self.outputDevicesChanged.emit()
# Discovered printers are all the printers that were found on the network, which provide a more convenient way
# to add networked printers (Plugin finds a bunch of printers, user can select one from the list, plugin can then
# add that printer to Cura as the active one).
def addDiscoveredPrinter(self, key: str, name: str, create_callback: Callable[[str], None], machine_type: str) -> None:
if key not in self._discovered_printers:
self._discovered_printers[key] = DiscoveredPrinter(key, name, create_callback, machine_type)
self.discoveredPrintersChanged.emit()
else:
Logger.log("e", "Printer with the key %s was already in the discovered printer list", key)
def removeDiscoveredPrinter(self, key: str) -> None:
if key in self._discovered_printers:
del self._discovered_printers[key]
self.discoveredPrintersChanged.emit()
@pyqtProperty("QVariantList", notify = discoveredPrintersChanged)
def discoveredPrinters(self):
return list(self._discovered_printers.values())
@pyqtSlot(str)
def addMachineFromDiscoveredPrinter(self, key: str) -> None:
if key in self._discovered_printers:
self._discovered_printers[key].create_callback(key)
@pyqtProperty(QObject, notify = currentConfigurationChanged) @pyqtProperty(QObject, notify = currentConfigurationChanged)
def currentConfiguration(self) -> ConfigurationModel: def currentConfiguration(self) -> ConfigurationModel:
return self._current_printer_configuration return self._current_printer_configuration

View file

@ -624,6 +624,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
printer.updateName(data["friendly_name"]) printer.updateName(data["friendly_name"])
printer.updateKey(data["uuid"]) printer.updateKey(data["uuid"])
printer.updateType(data["machine_variant"]) printer.updateType(data["machine_variant"])
self._application.getDiscoveredPrinterModel().updateDiscoveredPrinter(data["ip_address"],
name = data["friendly_name"],
machine_type = data["machine_variant"])
# Do not store the build plate information that comes from connect if the current printer has not build plate information # Do not store the build plate information that comes from connect if the current printer has not build plate information
if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False): if "build_plate" in data and machine_definition.getMetaDataEntry("has_variant_buildplates", False):

View file

@ -298,7 +298,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
except TypeError: except TypeError:
# Disconnect already happened. # Disconnect already happened.
pass pass
self._application.getMachineManager().removeDiscoveredPrinter(device.getId()) self._application.getDiscoveredPrinterModel().removeDiscoveredPrinter(device.getId())
self.discoveredDevicesChanged.emit() self.discoveredDevicesChanged.emit()
def _onAddDevice(self, name, address, properties): def _onAddDevice(self, name, address, properties):
@ -323,7 +323,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
device = ClusterUM3OutputDevice.ClusterUM3OutputDevice(name, address, properties) device = ClusterUM3OutputDevice.ClusterUM3OutputDevice(name, address, properties)
else: else:
device = LegacyUM3OutputDevice.LegacyUM3OutputDevice(name, address, properties) device = LegacyUM3OutputDevice.LegacyUM3OutputDevice(name, address, properties)
self._application.getMachineManager().addDiscoveredPrinter(device.getId(), name, self._createMachineFromDiscoveredPrinter, properties[b"printer_type"].decode("utf-8")) self._application.getDiscoveredPrinterModel().addDiscoveredPrinter(address, device.getId(), name, self._createMachineFromDiscoveredPrinter, properties[b"printer_type"].decode("utf-8"), device)
self._discovered_devices[device.getId()] = device self._discovered_devices[device.getId()] = device
self.discoveredDevicesChanged.emit() self.discoveredDevicesChanged.emit()

View file

@ -24,7 +24,7 @@ Button
function updatePrinterTypesList() function updatePrinterTypesList()
{ {
printerTypesList = (checked && (outputDevice != null)) ? outputDevice.uniquePrinterTypes : [] printerTypesList = (outputDevice != null) ? outputDevice.uniquePrinterTypes : []
} }
contentItem: Item contentItem: Item
@ -82,12 +82,6 @@ Button
border.color: machineSelectorButton.checked ? UM.Theme.getColor("primary") : "transparent" border.color: machineSelectorButton.checked ? UM.Theme.getColor("primary") : "transparent"
} }
onClicked:
{
toggleContent()
Cura.MachineManager.setActiveMachine(model.id)
}
Connections Connections
{ {
target: outputDevice target: outputDevice

View file

@ -42,5 +42,11 @@ ListView
} }
return result return result
} }
onClicked:
{
toggleContent()
Cura.MachineManager.setActiveMachine(model.id)
}
} }
} }

View file

@ -57,10 +57,11 @@ Item
ScrollView ScrollView
{ {
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff id: networkPrinterScrollView
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.vertical.policy: ScrollBar.AlwaysOn ScrollBar.vertical.policy: ScrollBar.AlwaysOn
property int maxItemCountAtOnce: 5 // show at max 5 items at once, otherwise you need to scroll. property int maxItemCountAtOnce: 8 // show at max 8 items at once, otherwise you need to scroll.
height: maxItemCountAtOnce * (UM.Theme.getSize("action_button").height) height: maxItemCountAtOnce * (UM.Theme.getSize("action_button").height)
clip: true clip: true
@ -69,15 +70,17 @@ Item
{ {
id: networkPrinterListView id: networkPrinterListView
anchors.fill: parent anchors.fill: parent
model: Cura.GlobalStacksModel {} // TODO: change this to the network printers model: CuraApplication.getDiscoveredPrinterModel().discovered_printers
visible: len(model) > 0
delegate: MachineSelectorButton delegate: MachineSelectorButton
{ {
text: model.name text: modelData.device.name
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 10 anchors.rightMargin: 10
outputDevice: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null outputDevice: modelData.device
checked: ListView.view.currentIndex == index checked: ListView.view.currentIndex == index
onClicked: onClicked:
@ -86,6 +89,14 @@ Item
} }
} }
} }
Label
{
id: noNetworkPrinterLabel
text: catalog.i18nc("@label", "There is no printer found over your network.")
renderType: Text.NativeRendering
visible: !networkPrinterListView.visible
}
} }
} }
} }
@ -109,7 +120,7 @@ Item
} }
} }
contentComponent: localPrinterListComponent //contentComponent: localPrinterListComponent
Component Component
{ {