Browse Source

Merge CURA-6179

Lipu Fei 6 years ago
parent
commit
ffb8aed4c3

+ 1 - 0
cura/CuraApplication.py

@@ -749,6 +749,7 @@ class CuraApplication(QtApplication):
         # Initialize Cura API
         self._cura_API.initialize()
 
+        self._output_device_manager.start()
         self._welcome_pages_model.initialize()
 
         # Detect in which mode to run and execute that mode

+ 41 - 4
cura/Settings/MachineManager.py

@@ -4,7 +4,7 @@
 import time
 import re
 import unicodedata
-from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast
+from typing import Any, List, Dict, TYPE_CHECKING, Optional, cast, NamedTuple, Callable
 
 from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
 from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@@ -49,6 +49,8 @@ if TYPE_CHECKING:
     from cura.Machines.QualityChangesGroup import QualityChangesGroup
     from cura.Machines.QualityGroup import QualityGroup
 
+DiscoveredPrinter = NamedTuple("DiscoveredPrinter", [("key", str), ("name", str), ("create_callback", Callable[[str], None]), ("machine_type", "str")])
+
 
 class MachineManager(QObject):
     def __init__(self, application: "CuraApplication", parent: Optional["QObject"] = None) -> None:
@@ -134,6 +136,9 @@ class MachineManager(QObject):
         self.globalContainerChanged.connect(self.printerConnectedStatusChanged)
         self.outputDevicesChanged.connect(self.printerConnectedStatusChanged)
 
+        # This will contain all discovered network printers
+        self._discovered_printers = {}  # type: Dict[str, DiscoveredPrinter]
+
     activeQualityGroupChanged = pyqtSignal()
     activeQualityChangesGroupChanged = pyqtSignal()
 
@@ -157,6 +162,7 @@ class MachineManager(QObject):
     printerConnectedStatusChanged = pyqtSignal() # Emitted every time the active machine change or the outputdevices change
 
     rootMaterialChanged = pyqtSignal()
+    discoveredPrintersChanged = pyqtSignal()
 
     def setInitialActiveMachine(self) -> None:
         active_machine_id = self._application.getPreferences().getValue("cura/active_machine")
@@ -171,7 +177,30 @@ class MachineManager(QObject):
                 self._printer_output_devices.append(printer_output_device)
 
         self.outputDevicesChanged.emit()
-        self.printerConnectedStatusChanged.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)
     def currentConfiguration(self) -> ConfigurationModel:
@@ -386,9 +415,17 @@ class MachineManager(QObject):
                 return machine
         return None
 
+    @pyqtSlot(str)
     @pyqtSlot(str, str)
-    def addMachine(self, name: str, definition_id: str) -> None:
-        new_stack = CuraStackBuilder.createMachine(name, definition_id)
+    def addMachine(self, definition_id: str, name: Optional[str] = None) -> None:
+        if name is None:
+            definitions = CuraContainerRegistry.getInstance().findDefinitionContainers(id = definition_id)
+            if definitions:
+                name = definitions[0].getName()
+            else:
+                name = definition_id
+
+        new_stack = CuraStackBuilder.createMachine(cast(str, name), definition_id)
         if new_stack:
             # Instead of setting the global container stack here, we set the active machine and so the signals are emitted
             self.setActiveMachine(new_stack.getId())

+ 7 - 2
plugins/UM3NetworkPrinting/src/UM3OutputDevicePlugin.py

@@ -213,6 +213,11 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
 
         self._checkManualDevice(address)
 
+    def _createMachineFromDiscoveredPrinter(self, key: str) -> None:
+        # TODO: This needs to be implemented. It's supposed to create a machine given a unique key as already discovered
+        # by this plugin.
+        pass
+
     def _checkManualDevice(self, address):
         # Check if a UM3 family device exists at this address.
         # If a printer responds, it will replace the preliminary printer created above
@@ -293,7 +298,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
                 except TypeError:
                     # Disconnect already happened.
                     pass
-
+            self._application.getMachineManager().removeDiscoveredPrinter(device.getId())
             self.discoveredDevicesChanged.emit()
 
     def _onAddDevice(self, name, address, properties):
@@ -318,7 +323,7 @@ class UM3OutputDevicePlugin(OutputDevicePlugin):
             device = ClusterUM3OutputDevice.ClusterUM3OutputDevice(name, address, properties)
         else:
             device = LegacyUM3OutputDevice.LegacyUM3OutputDevice(name, address, properties)
-
+        self._application.getMachineManager().addDiscoveredPrinter(device.getId(), name, self._createMachineFromDiscoveredPrinter, properties[b"printer_type"].decode("utf-8"))
         self._discovered_devices[device.getId()] = device
         self.discoveredDevicesChanged.emit()
 

+ 1 - 1
resources/qml/Dialogs/AddMachineDialog.qml

@@ -303,7 +303,7 @@ UM.Dialog
     {
         base.visible = false
         var item = machineList.model.getItem(machineList.currentIndex);
-        Cura.MachineManager.addMachine(machineName.text, item.id)
+        Cura.MachineManager.addMachine(item.id, machineName.text)
         base.machineAdded(item.id) // Emit signal that the user added a machine.
     }
 

+ 21 - 0
tests/TestMachineManager.py

@@ -11,13 +11,18 @@ from cura.Settings.MachineManager import MachineManager
 def container_registry() -> ContainerRegistry:
     return MagicMock()
 
+
 @pytest.fixture()
 def extruder_manager(application, container_registry) -> ExtruderManager:
     with patch("cura.CuraApplication.CuraApplication.getInstance", MagicMock(return_value=application)):
         with patch("UM.Settings.ContainerRegistry.ContainerRegistry.getInstance", MagicMock(return_value=container_registry)):
+            manager = ExtruderManager.getInstance()
+            if manager is None:
                 manager = ExtruderManager()
+
     return manager
 
+
 @pytest.fixture()
 def machine_manager(application, extruder_manager, container_registry) -> MachineManager:
     application.getExtruderManager = MagicMock(return_value = extruder_manager)
@@ -41,3 +46,19 @@ def test_setActiveMachine(machine_manager):
             # Although we mocked the application away, we still want to know if it was notified about the attempted change.
             machine_manager._application.setGlobalContainerStack.assert_called_with(mocked_global_stack)
 
+
+def test_discoveredMachine(machine_manager):
+    mocked_callback = MagicMock()
+    machine_manager.addDiscoveredPrinter("test", "zomg", mocked_callback, "derp")
+    machine_manager.addMachineFromDiscoveredPrinter("test")
+    mocked_callback.assert_called_with("test")
+
+    assert len(machine_manager.discoveredPrinters) == 1
+
+    # Test if removing it works
+    machine_manager.removeDiscoveredPrinter("test")
+    assert len(machine_manager.discoveredPrinters) == 0
+
+    # Just in case, nothing should happen.
+    machine_manager.addMachineFromDiscoveredPrinter("test")
+    assert mocked_callback.call_count == 1