Ejemplo n.º 1
0
    def createQualityChanges(self, base_name: str) -> None:
        machine_manager = self._application.getMachineManager()

        global_stack = machine_manager.activeMachine
        if not global_stack:
            return

        active_quality_name = machine_manager.activeQualityOrQualityChangesName
        if active_quality_name == "":
            Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
            return

        machine_manager.blurSettings.emit()
        if base_name is None or base_name == "":
            base_name = active_quality_name
        unique_name = self._container_registry.uniqueName(base_name)

        # Go through the active stacks and create quality_changes containers from the user containers.
        stack_list = [global_stack] + list(global_stack.extruders.values())
        for stack in stack_list:
            user_container = stack.userChanges
            quality_container = stack.quality
            quality_changes_container = stack.qualityChanges
            if not quality_container or not quality_changes_container:
                Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
                continue
            quality_type = quality_container.getMetaDataEntry("quality_type")
            extruder_stack = None
            if isinstance(stack, ExtruderStack):
                extruder_stack = stack
            new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_stack)
            from cura.Settings.ContainerManager import ContainerManager
            ContainerManager.getInstance()._performMerge(new_changes, quality_changes_container, clear_settings = False)
            ContainerManager.getInstance()._performMerge(new_changes, user_container)
            self._container_registry.addContainer(new_changes)
Ejemplo n.º 2
0
 def _materialWarningMessageAction(self, message, button):
     if button == "Undo":
         container_manager = ContainerManager.getInstance()
         container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "properties/diameter", self._material_diameter_warning_message.previous_diameter)
         message.hide()
     else:
         Logger.log("w", "Unknown button action for material diameter warning message: {action}".format(action = button))
Ejemplo n.º 3
0
    def setUp(self):

        self._application = MagicMock()
        self._container_registry = MagicMock()
        self._machine_manager = MagicMock()

        self._mocked_mime = MagicMock()
        self._mocked_mime.preferredSuffix = "omg"
        self._mocked_mime.suffixes = ["omg"]
        self._mocked_mime.comment = "UnitTest!"

        self._mocked_container = MagicMock()
        self._mocked_container_data = "SOME DATA :D"
        self._mocked_container.serialize = MagicMock(return_value = self._mocked_container_data)

        self._containers_meta_data = [{"id": "test", "test_data": "omg"}]
        self._container_registry.findContainersMetadata = MagicMock(return_value = self._containers_meta_data)
        self._container_registry.getMimeTypeForContainer = MagicMock(return_value = self._mocked_mime)
        self._container_registry.findContainers = MagicMock(return_value = [self._mocked_container])
        self._application.getContainerRegistry = MagicMock(return_value = self._container_registry)
        self._application.getMachineManager = MagicMock(return_value = self._machine_manager)

        # Destroy the previous instance of the container manager
        if ContainerManager.getInstance() is not None:
            ContainerManager._ContainerManager__instance = None

        self._container_manager = ContainerManager(self._application)
        MimeTypeDatabase.addMimeType(self._mocked_mime)
    def setUp(self):

        self._application = MagicMock()
        self._container_registry = MagicMock()
        self._machine_manager = MagicMock()

        self._mocked_mime = MagicMock()
        self._mocked_mime.preferredSuffix = "omg"
        self._mocked_mime.suffixes = ["omg"]
        self._mocked_mime.comment = "UnitTest!"

        self._mocked_container = MagicMock()
        self._mocked_container_data = "SOME DATA :D"
        self._mocked_container.serialize = MagicMock(
            return_value=self._mocked_container_data)

        self._containers_meta_data = [{"id": "test", "test_data": "omg"}]
        self._container_registry.findContainersMetadata = MagicMock(
            return_value=self._containers_meta_data)
        self._container_registry.getMimeTypeForContainer = MagicMock(
            return_value=self._mocked_mime)
        self._container_registry.findContainers = MagicMock(
            return_value=[self._mocked_container])
        self._application.getContainerRegistry = MagicMock(
            return_value=self._container_registry)
        self._application.getMachineManager = MagicMock(
            return_value=self._machine_manager)

        # Destroy the previous instance of the container manager
        if ContainerManager.getInstance() is not None:
            ContainerManager._ContainerManager__instance = None

        self._container_manager = ContainerManager(self._application)
        MimeTypeDatabase.addMimeType(self._mocked_mime)
Ejemplo n.º 5
0
    def _sendMaterialProfiles(self):
        Logger.log("i", "Sending material profiles to printer")

        # TODO: Might want to move this to a job...
        for container in ContainerRegistry.getInstance(
        ).findInstanceContainers(type="material"):
            try:
                xml_data = container.serialize()
                if xml_data == "" or xml_data is None:
                    continue

                names = ContainerManager.getInstance().getLinkedMaterials(
                    container.getId())
                if names:
                    # There are other materials that share this GUID.
                    if not container.isReadOnly():
                        continue  # If it's not readonly, it's created by user, so skip it.

                file_name = "none.xml"

                self.postForm("materials",
                              "form-data; name=\"file\";filename=\"%s\"" %
                              file_name,
                              xml_data.encode(),
                              on_finished=None)

            except NotImplementedError:
                # If the material container is not the most "generic" one it can't be serialized an will raise a
                # NotImplementedError. We can simply ignore these.
                pass
Ejemplo n.º 6
0
    def duplicateMaterial(self, message: QDBusMessage):
        from cura.Settings.ContainerManager import ContainerManager
        container_manager = ContainerManager.getInstance()

        base_material_id = message.arguments()[0]  # material to duplicate from
        new_id = message.arguments()[1]  # (preferred) duplicated material ID

        container_manager.duplicateMaterial(base_material_id, new_id)
Ejemplo n.º 7
0
    def createMaterial(self, message: QDBusMessage):
        from cura.Settings.ContainerManager import ContainerManager
        container_manager = ContainerManager.getInstance()

        new_id = message.arguments()[0]
        new_name = message.arguments()[1]

        container_manager.createMaterial(new_id=new_id, new_name=new_name)
Ejemplo n.º 8
0
 def _materialWarningMessageAction(self, message, button):
     if button == "Undo":
         container_manager = ContainerManager.getInstance()
         container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "properties/diameter", self._material_diameter_warning_message.previous_diameter)
         approximate_previous_diameter = str(round(float(self._material_diameter_warning_message.previous_diameter)))
         container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "approximate_diameter", approximate_previous_diameter)
         message.hide()
     else:
         Logger.log("w", "Unknown button action for material diameter warning message: {action}".format(action = button))
Ejemplo n.º 9
0
    def exportMaterial(self, message: QDBusMessage):
        material_id = message.arguments()[0]
        material_file_path = message.arguments()[1]

        from cura.Settings.ContainerManager import ContainerManager
        container_manager = ContainerManager.getInstance()
        container_manager.exportContainer(
            material_id,
            container_manager.getContainerNameFilters("material")[0],
            material_file_path)
Ejemplo n.º 10
0
    def createQualityChanges(self, base_name: str) -> None:
        machine_manager = cura.CuraApplication.CuraApplication.getInstance(
        ).getMachineManager()

        global_stack = machine_manager.activeMachine
        if not global_stack:
            return

        active_quality_name = machine_manager.activeQualityOrQualityChangesName
        if active_quality_name == "":
            Logger.log(
                "w",
                "No quality container found in stack %s, cannot create profile",
                global_stack.getId())
            return

        machine_manager.blurSettings.emit()
        if base_name is None or base_name == "":
            base_name = active_quality_name
        container_registry = cura.CuraApplication.CuraApplication.getInstance(
        ).getContainerRegistry()
        unique_name = container_registry.uniqueName(base_name)

        # Go through the active stacks and create quality_changes containers from the user containers.
        container_manager = ContainerManager.getInstance()
        stack_list = [global_stack] + list(global_stack.extruders.values())
        for stack in stack_list:
            quality_container = stack.quality
            quality_changes_container = stack.qualityChanges
            if not quality_container or not quality_changes_container:
                Logger.log(
                    "w",
                    "No quality or quality changes container found in stack %s, ignoring it",
                    stack.getId())
                continue

            extruder_stack = None
            intent_category = None
            if stack.getMetaDataEntry("position") is not None:
                extruder_stack = stack
                intent_category = stack.intent.getMetaDataEntry(
                    "intent_category")
            new_changes = self._createQualityChanges(
                quality_container.getMetaDataEntry("quality_type"),
                intent_category, unique_name, global_stack, extruder_stack)
            container_manager._performMerge(new_changes,
                                            quality_changes_container,
                                            clear_settings=False)
            container_manager._performMerge(new_changes, stack.userChanges)

            container_registry.addContainer(new_changes)
Ejemplo n.º 11
0
    def createQualityChanges(self, base_name: str) -> None:
        machine_manager = self._application.getMachineManager()

        global_stack = machine_manager.activeMachine
        if not global_stack:
            return

        active_quality_name = machine_manager.activeQualityOrQualityChangesName
        if active_quality_name == "":
            Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
            return

        machine_manager.blurSettings.emit()
        if base_name is None or base_name == "":
            base_name = active_quality_name
        unique_name = self._container_registry.uniqueName(base_name)

        # Go through the active stacks and create quality_changes containers from the user containers.
        stack_list = [global_stack] + list(global_stack.extruders.values())
        for stack in stack_list:
            user_container = stack.userChanges
            quality_container = stack.quality
            quality_changes_container = stack.qualityChanges
            if not quality_container or not quality_changes_container:
                Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
                continue

            quality_type = quality_container.getMetaDataEntry("quality_type")
            extruder_stack = None
            if isinstance(stack, ExtruderStack):
                extruder_stack = stack
            new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_stack)
            from cura.Settings.ContainerManager import ContainerManager
            ContainerManager.getInstance()._performMerge(new_changes, quality_changes_container, clear_settings = False)
            ContainerManager.getInstance()._performMerge(new_changes, user_container)

            self._container_registry.addContainer(new_changes)
Ejemplo n.º 12
0
    def createQualityChanges(self, base_name: str) -> None:
        """Create quality changes containers from the user containers in the active stacks.

        This will go through the global and extruder stacks and create quality_changes containers from the user
        containers in each stack. These then replace the quality_changes containers in the stack and clear the user
        settings.

        :param base_name: The new name for the quality changes profile. The final name of the profile might be
        different from this, because it needs to be made unique.
        """

        machine_manager = cura.CuraApplication.CuraApplication.getInstance().getMachineManager()

        global_stack = machine_manager.activeMachine
        if not global_stack:
            return

        active_quality_name = machine_manager.activeQualityOrQualityChangesName
        if active_quality_name == "":
            Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
            return

        machine_manager.blurSettings.emit()
        if base_name is None or base_name == "":
            base_name = active_quality_name
        container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
        unique_name = container_registry.uniqueName(base_name)

        # Go through the active stacks and create quality_changes containers from the user containers.
        container_manager = ContainerManager.getInstance()
        stack_list = [global_stack] + global_stack.extruderList
        for stack in stack_list:
            quality_container = stack.quality
            quality_changes_container = stack.qualityChanges
            if not quality_container or not quality_changes_container:
                Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
                continue

            extruder_stack = None
            intent_category = None
            if stack.getMetaDataEntry("position") is not None:
                extruder_stack = stack
                intent_category = stack.intent.getMetaDataEntry("intent_category")
            new_changes = self._createQualityChanges(quality_container.getMetaDataEntry("quality_type"), intent_category, unique_name, global_stack, extruder_stack)
            container_manager._performMerge(new_changes, quality_changes_container, clear_settings = False)
            container_manager._performMerge(new_changes, stack.userChanges)

            container_registry.addContainer(new_changes)
Ejemplo n.º 13
0
    def _sendMaterialProfiles(self):
        Logger.log("i", "Sending material profiles to printer")

        # TODO: Might want to move this to a job...
        for container in ContainerRegistry.getInstance().findInstanceContainers(type="material"):
            try:
                xml_data = container.serialize()
                if xml_data == "" or xml_data is None:
                    continue

                names = ContainerManager.getInstance().getLinkedMaterials(container.getId())
                if names:
                    # There are other materials that share this GUID.
                    if not container.isReadOnly():
                        continue  # If it's not readonly, it's created by user, so skip it.

                file_name = "none.xml"

                self.postForm("materials", "form-data; name=\"file\";filename=\"%s\"" % file_name, xml_data.encode(), on_finished=None)

            except NotImplementedError:
                # If the material container is not the most "generic" one it can't be serialized an will raise a
                # NotImplementedError. We can simply ignore these.
                pass
Ejemplo n.º 14
0
    def importProfile(self, file_name):
        Logger.log("d", "Attempting to import profile %s", file_name)
        if not file_name:
            return {
                "status": "error",
                "message": catalog.i18nc(
                    "@info:status",
                    "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>",
                    file_name,
                    "Invalid path",
                ),
            }

        plugin_registry = PluginRegistry.getInstance()
        extension = file_name.split(".")[-1]

        global_container_stack = Application.getInstance().getGlobalContainerStack()
        if not global_container_stack:
            return

        machine_extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()))
        machine_extruders.sort(key=lambda k: k.getMetaDataEntry("position"))

        for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
            if meta_data["profile_reader"][0]["extension"] != extension:
                continue

            profile_reader = plugin_registry.getPluginObject(plugin_id)
            try:
                profile_or_list = profile_reader.read(file_name)  # Try to open the file with the profile reader.
            except Exception as e:
                # Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
                Logger.log(
                    "e",
                    "Failed to import profile from %s: %s while using profile reader. Got exception %s",
                    file_name,
                    profile_reader.getPluginId(),
                    str(e),
                )
                return {
                    "status": "error",
                    "message": catalog.i18nc(
                        "@info:status",
                        "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>",
                        file_name,
                        str(e),
                    ),
                }
            if profile_or_list:  # Success!
                name_seed = os.path.splitext(os.path.basename(file_name))[0]
                new_name = self.uniqueName(name_seed)
                if type(profile_or_list) is not list:
                    profile = profile_or_list
                    self._configureProfile(profile, name_seed, new_name)
                    return {
                        "status": "ok",
                        "message": catalog.i18nc(
                            "@info:status", "Successfully imported profile {0}", profile.getName()
                        ),
                    }
                else:
                    profile_index = -1
                    global_profile = None

                    for profile in profile_or_list:
                        if profile_index >= 0:
                            if len(machine_extruders) > profile_index:
                                extruder_id = (
                                    Application.getInstance()
                                    .getMachineManager()
                                    .getQualityDefinitionId(machine_extruders[profile_index].getBottom())
                                )
                                # Ensure the extruder profiles get non-conflicting names
                                # NB: these are not user-facing
                                if "extruder" in profile.getMetaData():
                                    profile.setMetaDataEntry("extruder", extruder_id)
                                else:
                                    profile.addMetaDataEntry("extruder", extruder_id)
                                profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_")
                            elif profile_index == 0:
                                # Importing a multiextrusion profile into a single extrusion machine; merge 1st extruder profile into global profile
                                profile._id = self.uniqueName("temporary_profile")
                                self.addContainer(profile)
                                ContainerManager.getInstance().mergeContainers(global_profile.getId(), profile.getId())
                                self.removeContainer(profile.getId())
                                break
                            else:
                                # The imported composite profile has a profile for an extruder that this machine does not have. Ignore this extruder-profile
                                break
                        else:
                            global_profile = profile
                            profile_id = (
                                (global_container_stack.getBottom().getId() + "_" + name_seed).lower().replace(" ", "_")
                            )

                        self._configureProfile(profile, profile_id, new_name)

                        profile_index += 1

                    return {
                        "status": "ok",
                        "message": catalog.i18nc(
                            "@info:status", "Successfully imported profile {0}", profile_or_list[0].getName()
                        ),
                    }

        # If it hasn't returned by now, none of the plugins loaded the profile successfully.
        return {
            "status": "error",
            "message": catalog.i18nc(
                "@info:status", "Profile {0} has an unknown file type or is corrupted.", file_name
            ),
        }
Ejemplo n.º 15
0
    def importMaterial(self, message: QDBusMessage):
        material_file_path = message.arguments()[0]

        from cura.Settings.ContainerManager import ContainerManager
        container_manager = ContainerManager.getInstance()
        container_manager.importContainer(material_file_path)
Ejemplo n.º 16
0
    def importProfile(self, file_name):
        Logger.log("d", "Attempting to import profile %s", file_name)
        if not file_name:
            return {
                "status":
                "error",
                "message":
                catalog.i18nc(
                    "@info:status",
                    "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>",
                    file_name, "Invalid path")
            }

        plugin_registry = PluginRegistry.getInstance()
        extension = file_name.split(".")[-1]

        global_container_stack = Application.getInstance(
        ).getGlobalContainerStack()
        if not global_container_stack:
            return

        machine_extruders = list(
            ExtruderManager.getInstance().getMachineExtruders(
                global_container_stack.getId()))
        machine_extruders.sort(key=lambda k: k.getMetaDataEntry("position"))

        for plugin_id, meta_data in self._getIOPlugins("profile_reader"):
            if meta_data["profile_reader"][0]["extension"] != extension:
                continue

            profile_reader = plugin_registry.getPluginObject(plugin_id)
            try:
                profile_or_list = profile_reader.read(
                    file_name)  # Try to open the file with the profile reader.
            except Exception as e:
                # Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
                Logger.log(
                    "e",
                    "Failed to import profile from %s: %s while using profile reader. Got exception %s",
                    file_name, profile_reader.getPluginId(), str(e))
                return {
                    "status":
                    "error",
                    "message":
                    catalog.i18nc(
                        "@info:status",
                        "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>",
                        file_name, str(e))
                }
            if profile_or_list:  # Success!
                name_seed = os.path.splitext(os.path.basename(file_name))[0]
                new_name = self.uniqueName(name_seed)
                if type(profile_or_list) is not list:
                    profile = profile_or_list
                    self._configureProfile(profile, name_seed, new_name)
                    return {
                        "status":
                        "ok",
                        "message":
                        catalog.i18nc("@info:status",
                                      "Successfully imported profile {0}",
                                      profile.getName())
                    }
                else:
                    profile_index = -1
                    global_profile = None

                    for profile in profile_or_list:
                        if profile_index >= 0:
                            if len(machine_extruders) > profile_index:
                                extruder_id = Application.getInstance(
                                ).getMachineManager().getQualityDefinitionId(
                                    machine_extruders[profile_index].getBottom(
                                    ))
                                # Ensure the extruder profiles get non-conflicting names
                                # NB: these are not user-facing
                                if "extruder" in profile.getMetaData():
                                    profile.setMetaDataEntry(
                                        "extruder", extruder_id)
                                else:
                                    profile.addMetaDataEntry(
                                        "extruder", extruder_id)
                                profile_id = (extruder_id + "_" +
                                              name_seed).lower().replace(
                                                  " ", "_")
                            elif profile_index == 0:
                                # Importing a multiextrusion profile into a single extrusion machine; merge 1st extruder profile into global profile
                                profile._id = self.uniqueName(
                                    "temporary_profile")
                                self.addContainer(profile)
                                ContainerManager.getInstance().mergeContainers(
                                    global_profile.getId(), profile.getId())
                                self.removeContainer(profile.getId())
                                break
                            else:
                                # The imported composite profile has a profile for an extruder that this machine does not have. Ignore this extruder-profile
                                break
                        else:
                            global_profile = profile
                            profile_id = (
                                global_container_stack.getBottom().getId() +
                                "_" + name_seed).lower().replace(" ", "_")

                        self._configureProfile(profile, profile_id, new_name)

                        profile_index += 1

                    return {
                        "status":
                        "ok",
                        "message":
                        catalog.i18nc("@info:status",
                                      "Successfully imported profile {0}",
                                      profile_or_list[0].getName())
                    }

        # If it hasn't returned by now, none of the plugins loaded the profile successfully.
        return {
            "status":
            "error",
            "message":
            catalog.i18nc(
                "@info:status",
                "Profile {0} has an unknown file type or is corrupted.",
                file_name)
        }