From 05643eca11e8c4cd58645d519db67ad90a4bf4e7 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 08:11:53 +0200 Subject: [PATCH 1/8] Fix renaming profiles from the Profiles page CURA-1585 --- cura/MachineManagerModel.py | 9 +++++++++ resources/qml/Preferences/ProfilesPage.qml | 14 +++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 6d6ff10a4b..6e0e0a6127 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -312,6 +312,15 @@ class MachineManagerModel(QObject): return "" + @pyqtSlot(str, str) + def renameQualityContainer(self, container_id, new_name): + containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id, type = "quality") + if containers: + new_name = self._createUniqueName("machine", new_name, catalog.i18nc("@label", "Custom profile")) + containers[0].setName(new_name) + UM.Settings.ContainerRegistry.getInstance().containerChanged.emit(containers[0]) + + @pyqtSlot(str) def removeQualityContainer(self, container_id): containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = container_id) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index 52ab10cfd6..c031ed9f20 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -184,19 +184,19 @@ UM.ManagementPage UM.ConfirmRemoveDialog { - id: confirmDialog; - object: base.currentItem != null ? base.currentItem.name : ""; - onYes: Cura.MachineManager.removeQualityContainer(base.currentItem.id); + id: confirmDialog + object: base.currentItem != null ? base.currentItem.name : "" + onYes: Cura.MachineManager.removeQualityContainer(base.currentItem.id) } UM.RenameDialog { id: renameDialog; - object: base.currentItem != null ? base.currentItem.name : ""; - property bool removeWhenRejected: false; - onAccepted: base.model.rename(base.currentItem.id, newName.trim()); + object: base.currentItem != null ? base.currentItem.name : "" + property bool removeWhenRejected: false + onAccepted: Cura.MachineManager.renameQualityContainer(base.currentItem.id, newName) onRejected: { if(removeWhenRejected) { - base.model.removeProfile(base.currentItem.name) + Cura.MachineManager.removeQualityContainer(base.currentItem.id) } } } From a6870b555b644f2fa91ea313f010551d4f64b61a Mon Sep 17 00:00:00 2001 From: Simon Edwards Date: Tue, 7 Jun 2016 10:34:08 +0200 Subject: [PATCH 2/8] Fix up my comment, make it clearer. Fixes CURA-1630 Settings disappear after selecting all options of Experimental Modes --- resources/qml/Settings/SettingView.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index ed66661a8e..7191bff3ef 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -24,7 +24,7 @@ ScrollView { id: contents spacing: UM.Theme.getSize("default_lining").height; - cacheBuffer: 1000000; // A huge to cache to effectively cache everything. + cacheBuffer: 1000000; // Set a large cache to effectively just cache every list item. model: UM.SettingDefinitionsModel { id: definitionsModel; From ce388c4b231aaedc8377668b6c27cdc9d7ed96d8 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 11:18:09 +0200 Subject: [PATCH 3/8] Show settings in profile as a sorted list with section headers CURA-1585 --- resources/qml/Preferences/ProfilesPage.qml | 103 ++++++++++----------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml index c031ed9f20..28248b23f4 100644 --- a/resources/qml/Preferences/ProfilesPage.qml +++ b/resources/qml/Preferences/ProfilesPage.qml @@ -91,70 +91,63 @@ UM.ManagementPage elide: Text.ElideRight } - ScrollView { + Row { + id: currentSettingsActions + visible: base.currentItem.id == -1 || currentItem.id == Cura.MachineManager.activeQualityId + anchors.left: parent.left anchors.top: profileName.bottom anchors.topMargin: UM.Theme.getSize("default_margin").height + + Button + { + text: { + var profileName = Cura.MachineManager.activeQualityName; + profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; + return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); + } + enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) + onClicked: Cura.MachineManager.updateUserContainerToQuality() + } + + Button + { + text: catalog.i18nc("@action:button", "Discard changes"); + enabled: Cura.MachineManager.hasUserSettings + onClicked: Cura.MachineManager.clearUserSettings(); + } + } + + ScrollView { + id: scrollView + + anchors.left: parent.left + anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : profileName.bottom + anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.right: parent.right anchors.bottom: parent.bottom - Column - { - spacing: UM.Theme.getSize("default_margin").height - - Row - { - visible: base.currentItem.id == -1 || currentItem.id == Cura.MachineManager.activeQualityId - Button - { - text: { - var profileName = Cura.MachineManager.activeQualityName; - profileName = (profileName.length > 20) ? profileName.substring(0, 20) + '...' : profileName; - return catalog.i18nc("@action:button", "Update \"%1\"".arg(profileName)); - } - enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId) - onClicked: Cura.MachineManager.updateUserContainerToQuality() + ListView { + model: base.currentItem ? base.currentItem.settings: null + delegate: Row { + spacing: UM.Theme.getSize("default_margin").width + Label { + text: model.label + elide: Text.ElideMiddle + width: scrollView.width / 100 * 40 } - - Button - { - text: catalog.i18nc("@action:button", "Discard changes"); - enabled: Cura.MachineManager.hasUserSettings - onClicked: Cura.MachineManager.clearUserSettings(); + Label { + text: model.value.toString() + } + Label { + text: model.unit } } - - Grid - { - id: containerGrid - columns: 2 - spacing: UM.Theme.getSize("default_margin").width - - Label { - text: base.currentItem == null ? "" : - base.currentItem.id == -1 ? catalog.i18nc("@label", "Based on") : catalog.i18nc("@label", "Profile type") - } - Label { - text: base.currentItem == null ? "" : - base.currentItem.id == -1 ? Cura.MachineManager.activeQualityName: - base.currentItem.metadata.read_only ? catalog.i18nc("@label", "Protected profile") : catalog.i18nc("@label", "Custom profile") - } - - Column { - Repeater { - model: base.currentItem ? base.currentItem.settings : null - Label { - text: modelData.label - elide: Text.ElideMiddle; - } - } - } - Column { - Repeater { - model: base.currentItem ? base.currentItem.settings : null - Label { text: modelData.value.toString(); } - } - } + section.property: "category" + section.criteria: ViewSection.FullString + section.delegate: Label { + text: section + font.bold: true } } } From 890303da146a77d6be6be51bb1eda1104930f556 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:33:10 +0200 Subject: [PATCH 4/8] Add function to add all extruder trains of a machine This function only adds extruder trains if they have not been added already. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 41 +++++++++++++++++++++++++++++++++---- cura/MachineManagerModel.py | 9 +------- 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index aae90afdc5..8c467ede00 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -61,6 +61,38 @@ class ExtruderManager(QObject): self._active_extruder_index = index self.activeExtruderChanged.emit() + ## Adds all extruders of a specific machine definition to the extruder + # manager. + # + # \param machine_definition The machine to add the extruders for. + def addMachineExtruders(self, machine_definition): + machine_id = machine_definition.getId() + if not self._extruder_trains[machine_id]: + self._extruder_trains[machine_id] = { } + + container_registry = UM.Settings.ContainerRegistry.getInstance() + if not container_registry: #Then we shouldn't have any machine definition either. In any case, there are no extruder trains then so bye bye. + return + + #Add the extruder trains that don't exist yet. + for position, extruder_definition_id in machine_definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): + extruder_definition = container_registry.findDefinitionContainers(id = extruder_definition_id) + if extruder_definition: + extruder_definition = extruder_definition[0] + else: + Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", machine_definition.getName(), extruder_definition_id) + continue + name = self._uniqueName(extruder_definition_id) #Make a name based on the ID of the definition. + if not container_registry.findContainerStacks(id = name): #Doesn't exist yet. + self.createExtruderTrain(extruder_definition, machine_definition, name, position) + + #Gets the extruder trains that we just created as well as any that still existed. + extruder_trains = container_registry.findContainerStacks(type = "extruder_train", machine = machine_definition.getId()) + for extruder_train in extruder_trains: + self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() + if extruder_trains: + self.extrudersChanged.emit() + ## (Re)populates the collections of extruders by machine. def _repopulate(self): self._extruder_trains = { } @@ -78,13 +110,14 @@ class ExtruderManager(QObject): self._extruder_trains[machine_id][extruder_train.getMetaDataEntry("position")] = extruder_train.getId() self.extrudersChanged.emit() - def createExtruderTrain(self, extruder_definition, machine_definition, extruder_id): + def createExtruderTrain(self, extruder_definition, machine_definition, extruder_train_id, position): container_registry = UM.Settings.ContainerRegistry.getInstance() #Create a container stack for this extruder. - name = self._uniqueName(extruder_id) - container_stack = UM.Settings.ContainerStack(name) + container_stack = UM.Settings.ContainerStack(extruder_train_id) container_stack.addMetaDataEntry("type", "extruder_train") + container_stack.addMetaDataEntry("machine", machine_definition.getId()) + container_stack.addMetaDataEntry("position", position) container_stack.addContainer(extruder_definition) """ @@ -133,7 +166,7 @@ class ExtruderManager(QObject): """ #Add an empty user profile. - user_profile = UM.Settings.InstanceContainer(name + "_current_settings") + user_profile = UM.Settings.InstanceContainer(extruder_train_id + "_current_settings") user_profile.addMetaDataEntry("type", "user") user_profile.setDefinition(machine_definition) container_stack.addContainer(user_profile) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 576cf1acc0..86e74e8302 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -135,14 +135,7 @@ class MachineManagerModel(QObject): new_global_stack.addContainer(quality_instance_container) new_global_stack.addContainer(current_settings_instance_container) - for position, extruder_train_id in definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): - extruder_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id = extruder_train_id) - if extruder_definition: - extruder_definition = extruder_definition[0] - else: - Logger.log("w", "Machine %s references an extruder with ID %s, which doesn't exist.", definition.getName(), extruder_train_id) - continue - ExtruderManager.ExtruderManager.getInstance().createExtruderTrain(extruder_definition, definition, extruder_train_id) + ExtruderManager.ExtruderManager.getInstance().addMachineExtruders(definition) Application.getInstance().setGlobalContainerStack(new_global_stack) From 9fe543596316fb11c5478b750465f958228983a9 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:34:00 +0200 Subject: [PATCH 5/8] Rename parameter in _uniqueName Original means the original name. That's better. Contributes to issues CURA-1278 and CURA-340. --- cura/ExtruderManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 8c467ede00..15fbbe2a1c 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -177,10 +177,10 @@ class ExtruderManager(QObject): container_registry.addContainer(container_stack) - def _uniqueName(self, extruder): + def _uniqueName(self, original): container_registry = UM.Settings.ContainerRegistry.getInstance() - name = extruder.strip() + name = original.strip() num_check = re.compile("(.*?)\s*#\d$").match(name) if num_check: # There is a number in the name. name = num_check.group(1) # Filter out the number. From dff94b4559e558aeadea7a8694393557b838c3f5 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:54:16 +0200 Subject: [PATCH 6/8] Make ExtruderManager a QML context item There were two singletons of this manager: One created by QML and managed by QML, and one created by us and managed by our own singleton pattern. That won't work! So we now manage just our own singleton type, and make it a context item for QML so it can use the manager too. Contributes to issues CURA-340 and CURA-1278. --- cura/CuraApplication.py | 7 +++++-- cura/ExtruderManager.py | 6 +----- resources/qml/Settings/SettingView.qml | 2 +- resources/qml/SidebarHeader.qml | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 126d8b2864..7edb0bf8bd 100644 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -353,8 +353,6 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(MachineManagerModel.MachineManagerModel, "Cura", 1, 0, "MachineManager", MachineManagerModel.createMachineManagerModel) - qmlRegisterSingletonType(ExtruderManager.ExtruderManager, "Cura", 1, 0, "ExtruderManager", - ExtruderManager.createExtruderManager) self.setMainQml(Resources.getPath(self.ResourceTypes.QmlFiles, "Cura.qml")) self._qml_import_paths.append(Resources.getPath(self.ResourceTypes.QmlFiles)) @@ -386,6 +384,9 @@ class CuraApplication(QtApplication): def getPrintInformation(self): return self._print_information + ## Registers objects for the QML engine to use. + # + # \param engine The QML engine. def registerObjects(self, engine): engine.rootContext().setContextProperty("Printer", self) self._print_information = PrintInformation.PrintInformation() @@ -399,6 +400,8 @@ class CuraApplication(QtApplication): qmlRegisterSingletonType(QUrl.fromLocalFile(Resources.getPath(CuraApplication.ResourceTypes.QmlFiles, "Actions.qml")), "Cura", 1, 0, "Actions") + engine.rootContext().setContextProperty("ExtruderManager", ExtruderManager.ExtruderManager.getInstance()) + for path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.QmlFiles): type_name = os.path.splitext(os.path.basename(path))[0] if type_name in ("Cura", "Actions"): diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 15fbbe2a1c..4f8c58be07 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -76,7 +76,7 @@ class ExtruderManager(QObject): #Add the extruder trains that don't exist yet. for position, extruder_definition_id in machine_definition.getMetaDataEntry("machine_extruder_trains", default = {}).items(): - extruder_definition = container_registry.findDefinitionContainers(id = extruder_definition_id) + extruder_definition = container_registry.findDefinitionContainers(machine = machine_definition.getId()) if extruder_definition: extruder_definition = extruder_definition[0] else: @@ -194,7 +194,3 @@ class ExtruderManager(QObject): i += 1 # Try next numbering. unique_name = "%s #%d" % (name, i) # Fill name like this: "Extruder #2". return unique_name - - -def createExtruderManager(engine, script_engine): - return ExtruderManager() \ No newline at end of file diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml index 7191bff3ef..6261496c84 100644 --- a/resources/qml/Settings/SettingView.qml +++ b/resources/qml/Settings/SettingView.qml @@ -80,7 +80,7 @@ ScrollView { id: provider - containerStackId: Cura.ExtruderManager.activeExtruderStackId ? Cura.ExtruderManager.activeExtruderStackId : Cura.MachineManager.activeMachineId + containerStackId: ExtruderManager.activeExtruderStackId ? ExtruderManager.activeExtruderStackId : Cura.MachineManager.activeMachineId key: model.key watchedProperties: [ "value", "enabled", "state", "validationState" ] storeIndex: 0 diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml index b38f65772d..237746ac0d 100644 --- a/resources/qml/SidebarHeader.qml +++ b/resources/qml/SidebarHeader.qml @@ -111,7 +111,7 @@ Item onClicked: { base.currentExtruderIndex = index - Cura.ExtruderManager.setActiveExtruderIndex(index) + ExtruderManager.setActiveExtruderIndex(index) } style: ButtonStyle { From 66bf0831f310e7f56090843d31db0ba057218903 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Tue, 7 Jun 2016 11:55:07 +0200 Subject: [PATCH 7/8] Document _uniqueName This function should really just be moved to ContainerRegistry... I'll do that later. Contributes to issues CURA-340 and CURA-1278. --- cura/ExtruderManager.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cura/ExtruderManager.py b/cura/ExtruderManager.py index 4f8c58be07..f8bcd75151 100644 --- a/cura/ExtruderManager.py +++ b/cura/ExtruderManager.py @@ -176,7 +176,14 @@ class ExtruderManager(QObject): container_registry.addContainer(container_stack) - + ## Creates a new unique name for a container that doesn't exist yet. + # + # It tries if the original name you provide exists, and if it doesn't + # it'll add a " #1" or " #2" after the name to make it unique. + # + # \param original The original name that may not be unique. + # \return A unique name that looks a lot like the original but may have + # a number behind it to make it unique. def _uniqueName(self, original): container_registry = UM.Settings.ContainerRegistry.getInstance() @@ -189,8 +196,7 @@ class ExtruderManager(QObject): unique_name = name i = 1 - while container_registry.findContainers(id=unique_name) or container_registry.findContainers( - name=unique_name): # A container already has this name. + while container_registry.findContainers(id = unique_name) or container_registry.findContainers(name = unique_name): # A container already has this name. i += 1 # Try next numbering. unique_name = "%s #%d" % (name, i) # Fill name like this: "Extruder #2". return unique_name From 4fb66afe069ba9f6b7dff397448d6f659232cb79 Mon Sep 17 00:00:00 2001 From: fieldOfView Date: Tue, 7 Jun 2016 11:58:44 +0200 Subject: [PATCH 8/8] Mark duplicated profiles as non-read-only CURA-1585 --- cura/MachineManagerModel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cura/MachineManagerModel.py b/cura/MachineManagerModel.py index 576cf1acc0..e179eb2ebd 100644 --- a/cura/MachineManagerModel.py +++ b/cura/MachineManagerModel.py @@ -304,6 +304,7 @@ class MachineManagerModel(QObject): ## Copy all values new_container.deserialize(containers[0].serialize()) + new_container.setMetaDataEntry("read_only", False) new_container.setName(new_name) new_container._id = new_name UM.Settings.ContainerRegistry.getInstance().addContainer(new_container)