From c9144460608e4b37ce850c51ac71439b54b14930 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 27 May 2016 11:26:41 +0200 Subject: [PATCH 1/5] Initial changes for perobject stuff CURA-1278 --- cura/SettingOverrideDecorator.py | 4 +- .../PerObjectSettingsTool/PerObjectItem.qml | 4 +- .../PerObjectSettingVisibilityHandler.py | 76 +++++++++++++++++ .../PerObjectSettingsModel.py | 33 +++----- .../PerObjectSettingsPanel.qml | 82 ++++++------------- plugins/PerObjectSettingsTool/__init__.py | 4 + 6 files changed, 119 insertions(+), 84 deletions(-) create mode 100644 plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py diff --git a/cura/SettingOverrideDecorator.py b/cura/SettingOverrideDecorator.py index 826970c51f..ae06be8512 100644 --- a/cura/SettingOverrideDecorator.py +++ b/cura/SettingOverrideDecorator.py @@ -14,8 +14,8 @@ from UM.Application import Application class SettingOverrideDecorator(SceneNodeDecorator): def __init__(self): super().__init__() - self._stack = ContainerStack(id = "SettingOverrideStack") - self._instance = InstanceContainer(id = "SettingOverrideInstanceContainer") + self._stack = ContainerStack(stack_id = "SettingOverrideStack") + self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer") self._stack.addContainer(self._instance) Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged) diff --git a/plugins/PerObjectSettingsTool/PerObjectItem.qml b/plugins/PerObjectSettingsTool/PerObjectItem.qml index d2243ab562..e0d389443f 100644 --- a/plugins/PerObjectSettingsTool/PerObjectItem.qml +++ b/plugins/PerObjectSettingsTool/PerObjectItem.qml @@ -16,13 +16,13 @@ UM.TooltipArea width: childrenRect.width; height: childrenRect.height; - Button + CheckBox { id: check text: definition.label - //onClicked: delegateItem.settingsModel.setSettingVisible(model.key, checked); + onClicked: addedSettingsModel.setVisible(model.key, checked); } } diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py new file mode 100644 index 0000000000..e56ad520c6 --- /dev/null +++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py @@ -0,0 +1,76 @@ +from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal +from UM.Application import Application +from UM.Settings.SettingInstance import SettingInstance +from UM.Logger import Logger + +from cura.SettingOverrideDecorator import SettingOverrideDecorator + + +class PerObjectSettingVisibilityHandler(QObject): + def __init__(self, parent = None, *args, **kwargs): + super().__init__(parent = parent, *args, **kwargs) + self._selected_object_id = None + + visibilityChanged = pyqtSignal() + + def setSelectedObjectId(self, id): + self._selected_object_id = id + self.visibilityChanged.emit() + + @pyqtProperty("quint64", fset = setSelectedObjectId) + def selectedObjectId(self): + pass + + def setVisible(self, visible): + node = Application.getInstance().getController().getScene().findObject(self._selected_object_id) + if not node: + return + stack = node.callDecoration("getStack") + if not stack: + node.addDecorator(SettingOverrideDecorator()) + stack = node.callDecoration("getStack") + + settings = stack.getTop() + all_instances = settings.findInstances(**{}) + visibility_changed = False # Flag to check if at the end the signal needs to be emitted + + # Remove all instances that are not in visibility list + for instance in all_instances: + if instance.definition.key not in visible: + settings.removeInstance(instance.definition.key) + visibility_changed = True + + # Add all instances that are not added, but are in visiblity list + for item in visible: + if not settings.getInstance(item): + definition_container = Application.getInstance().getGlobalContainerStack().getBottom() + definitions = definition_container.findDefinitions(key = item) + if definitions: + settings.addInstance(SettingInstance(definitions[0], settings)) + visibility_changed = True + else: + Logger.log("w", "Unable to add instance (%s) to perobject visibility because we couldn't find the matching definition", item) + + if visibility_changed: + self.visibilityChanged.emit() + #settings.addInstance(SettingInstance()) + + def getVisible(self): + visible_settings = set() + node = Application.getInstance().getController().getScene().findObject(self._selected_object_id) + if not node: + return visible_settings + + stack = node.callDecoration("getStack") + if not stack: + return visible_settings + + settings = stack.getTop() + if not settings: + return visible_settings + + all_instances = settings.findInstances(**{}) + for instance in all_instances: + visible_settings.add(instance.definition.key) + return visible_settings + diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py index cbe22d129e..74a1fbed9a 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsModel.py @@ -13,21 +13,14 @@ from UM.Scene.SceneNode import SceneNode from . import SettingOverrideModel class PerObjectSettingsModel(ListModel): - IdRole = Qt.UserRole + 1 - XRole = Qt.UserRole + 2 - YRole = Qt.UserRole + 3 - MaterialRole = Qt.UserRole + 4 - ProfileRole = Qt.UserRole + 5 - SettingsRole = Qt.UserRole + 6 + IdRole = Qt.UserRole + 1 # ID of the node def __init__(self, parent = None): super().__init__(parent) self._scene = Application.getInstance().getController().getScene() self._root = self._scene.getRoot() self.addRoleName(self.IdRole,"id") - self.addRoleName(self.MaterialRole, "material") - self.addRoleName(self.ProfileRole, "profile") - self.addRoleName(self.SettingsRole, "settings") + self._updateModel() @pyqtSlot("quint64", str) @@ -48,7 +41,7 @@ class PerObjectSettingsModel(ListModel): node.removeDecorator(ProfileOverrideDecorator)''' @pyqtSlot("quint64", str) - def addSettingOverride(self, object_id, key): + def addOverride(self, object_id, key): machine = Application.getInstance().getMachineManager().getActiveMachineInstance() if not machine: return @@ -60,7 +53,7 @@ class PerObjectSettingsModel(ListModel): node.callDecoration("addSetting", key) @pyqtSlot("quint64", str) - def removeSettingOverride(self, object_id, key): + def removerOverride(self, object_id, key): node = self._scene.findObject(object_id) node.callDecoration("removeSetting", key) @@ -69,18 +62,14 @@ class PerObjectSettingsModel(ListModel): def _updateModel(self): self.clear() + for node in BreadthFirstIterator(self._root): if type(node) is not SceneNode or not node.isSelectable(): continue - node_profile = node.callDecoration("getProfile") - if not node_profile: - node_profile = "global" - else: - node_profile = node_profile.getName() - self.appendItem({ - "id": id(node), - "material": "", - "profile": node_profile, - "settings": SettingOverrideModel.SettingOverrideModel(node) - }) + node_stack = node.callDecoration("getStack") + + if not node_stack: + self.appendItem({ + "id": id(node) + }) diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml index 9b78116d24..5213c7ee58 100644 --- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml +++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml @@ -20,73 +20,38 @@ Item { width: childrenRect.width; height: childrenRect.height; - Column { + Column + { id: items anchors.top: parent.top; anchors.left: parent.left; spacing: UM.Theme.getSize("default_margin").height; - - Column { - id: customisedSettings + height: childrenRect.height; + ListView + { + id: contents spacing: UM.Theme.getSize("default_lining").height; - width: UM.Theme.getSize("setting").width + UM.Theme.getSize("setting").height/2; + height: childrenRect.height; - Repeater { - id: settings; - - model: UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).settings - - UM.SettingItem { - width: UM.Theme.getSize("setting").width; - height: UM.Theme.getSize("setting").height; - - name: model.label; - type: model.type; - value: model.value; - description: model.description; - unit: model.unit; - valid: model.valid; - visible: !model.global_only - options: model.options - indent: false - - style: UM.Theme.styles.setting_item; - - onItemValueChanged: { - settings.model.setSettingValue(model.key, value) - } - - Button - { - anchors.left: parent.right; - - width: UM.Theme.getSize("setting").height; - height: UM.Theme.getSize("setting").height; - - onClicked: UM.ActiveTool.properties.getValue("Model").removeSettingOverride(UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).id, model.key) - - style: ButtonStyle - { - background: Rectangle - { - color: control.hovered ? control.parent.style.controlHighlightColor : control.parent.style.controlColor; - UM.RecolorImage - { - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width/2 - height: parent.height/2 - sourceSize.width: width - sourceSize.height: width - color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button") - source: UM.Theme.getIcon("cross1") - } - } - } - } + model: UM.SettingDefinitionsModel { + id: addedSettingsModel; + containerId: Cura.MachineManager.activeDefinitionId + visibilityHandler: Cura.PerObjectSettingVisibilityHandler { + selectedObjectId: UM.ActiveTool.properties.getValue("Model").getItem(base.currentIndex).id } } + + delegate:Button + { + anchors.left: parent.right; + + width: 150 + height:50 + + text: model.label + } + } Button @@ -184,6 +149,7 @@ Item { { "global_only": false } + visibilityHandler: UM.SettingPreferenceVisibilityHandler {} } delegate:Loader { diff --git a/plugins/PerObjectSettingsTool/__init__.py b/plugins/PerObjectSettingsTool/__init__.py index d5d249b430..1779556ade 100644 --- a/plugins/PerObjectSettingsTool/__init__.py +++ b/plugins/PerObjectSettingsTool/__init__.py @@ -2,6 +2,8 @@ # Uranium is released under the terms of the AGPLv3 or higher. from . import PerObjectSettingsTool +from . import PerObjectSettingVisibilityHandler +from PyQt5.QtQml import qmlRegisterType from UM.i18n import i18nCatalog i18n_catalog = i18nCatalog("cura") @@ -25,4 +27,6 @@ def getMetaData(): } def register(app): + qmlRegisterType(PerObjectSettingVisibilityHandler.PerObjectSettingVisibilityHandler, "Cura", 1, 0, + "PerObjectSettingVisibilityHandler") return { "tool": PerObjectSettingsTool.PerObjectSettingsTool() } From 64a613f407ad4065d5c30a96dbad82eae59c63d9 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 May 2016 11:47:50 +0200 Subject: [PATCH 2/5] Fix "Activate" button on the Manage Printers page CURA-1278 --- resources/qml/MachinesPage.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/qml/MachinesPage.qml b/resources/qml/MachinesPage.qml index 14425acc05..8c7a2c521d 100644 --- a/resources/qml/MachinesPage.qml +++ b/resources/qml/MachinesPage.qml @@ -22,9 +22,11 @@ UM.ManagementPage onAddObject: Printer.requestAddPrinter() onRemoveObject: confirmDialog.open(); onRenameObject: renameDialog.open(); + onActivateObject: Cura.MachineManager.setActiveMachine(base.currentItem.id) - removeEnabled: numInstances > 1 - renameEnabled: numInstances > 0 + removeEnabled: base.currentItem != null && numInstances > 1 + renameEnabled: base.currentItem != null && numInstances > 0 + activateEnabled: base.currentItem != null Flow { From 63556318425f595129aaee1aa8b6e98f1c9d1e39 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Fri, 27 May 2016 11:53:53 +0200 Subject: [PATCH 3/5] Activate another machine when we remove the currently active MachineManagerModel CURA-1278 --- cura/MachineManagerModel.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 11cb55d2b4..7b42483fca 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -266,6 +266,11 @@ class MachineManagerModel(QObject): @pyqtSlot(str) def removeMachine(self, machine_id): + # If the machine that is being removed is the currently active machine, set another machine as the active machine + if self._global_container_stack and self._global_container_stack.getId() == machine_id: + containers = UM.Settings.ContainerRegistry.getInstance().findContainerStacks() + if containers: + Application.getInstance().setGlobalContainerStack(containers[0]) UM.Settings.ContainerRegistry.getInstance().removeContainer(machine_id) @pyqtProperty(bool, notify = globalContainerChanged) From aa2d09aa0863b42284b001bbe99171ae26bbc2a0 Mon Sep 17 00:00:00 2001 From: Tim Kuipers Date: Fri, 27 May 2016 12:44:49 +0200 Subject: [PATCH 4/5] JSON lil fix: superflious comma (CURA-1616) --- resources/definitions/fdmextruder.def.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json index 6533d211c5..e9be929e72 100644 --- a/resources/definitions/fdmextruder.def.json +++ b/resources/definitions/fdmextruder.def.json @@ -112,7 +112,7 @@ "unit": "mm", "default_value": 0, "global_only": "True" - }, + } } } } From 990d05815be06e3929978f67c61465b611898e5d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Fri, 27 May 2016 14:00:38 +0200 Subject: [PATCH 5/5] Added qml files to import path --- cura/CuraApplication.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0e7f3b4b42..29e2fe4667 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -320,6 +320,7 @@ class CuraApplication(QtApplication): MachineManagerModel.createMachineManagerModel) self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) + self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) self.initializeEngine() if self._engine.rootObjects: