From fc9f05fc8b434630759d00a47a0eba51c93319bd Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 1 Oct 2018 11:32:55 +0200 Subject: [PATCH 1/9] Moved SettingVisibilityPreset loading to it's own class Since there was so much debate regarding the unit testing of the visiblity presets, i had another look at it. The old version was almost untestable because all functionalities were mushed together into a single class. CURA-5734 --- cura/CuraApplication.py | 4 +- .../Models/SettingVisibilityPresetsModel.py | 128 ++++++++---------- cura/Settings/SettingVisibilityPreset.py | 87 ++++++++++++ .../Menus/SettingVisibilityPresetsMenu.qml | 8 +- .../qml/Preferences/SettingVisibilityPage.qml | 17 ++- 5 files changed, 154 insertions(+), 90 deletions(-) create mode 100644 cura/Settings/SettingVisibilityPreset.py diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index dbaef4df34..18f86959a7 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -701,10 +701,8 @@ class CuraApplication(QtApplication): self._print_information = PrintInformation.PrintInformation(self) self._cura_actions = CuraActions.CuraActions(self) - # Initialize setting visibility presets model + # Initialize setting visibility presets model. self._setting_visibility_presets_model = SettingVisibilityPresetsModel(self) - default_visibility_profile = self._setting_visibility_presets_model.getItem(0) - self.getPreferences().setDefault("general/visible_settings", ";".join(default_visibility_profile["settings"])) # Detect in which mode to run and execute that mode if self._is_headless: diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index d5fa51d20a..38c6176e4e 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -1,12 +1,13 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import Optional +from typing import Optional, List import os import urllib.parse from configparser import ConfigParser -from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot +from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QObject + from UM.Application import Application from UM.Logger import Logger @@ -15,121 +16,101 @@ from UM.Resources import Resources from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError from UM.i18n import i18nCatalog +from cura.Settings.SettingVisibilityPreset import SettingVisibilityPreset + catalog = i18nCatalog("cura") -class SettingVisibilityPresetsModel(ListModel): - IdRole = Qt.UserRole + 1 - NameRole = Qt.UserRole + 2 - SettingsRole = Qt.UserRole + 3 +class SettingVisibilityPresetsModel(QObject): + onItemsChanged = pyqtSignal() + activePresetChanged = pyqtSignal() def __init__(self, parent = None): super().__init__(parent) - self.addRoleName(self.IdRole, "id") - self.addRoleName(self.NameRole, "name") - self.addRoleName(self.SettingsRole, "settings") + self._items = [] # type: List[SettingVisibilityPreset] self._populate() - basic_item = self.items[1] - basic_visibile_settings = ";".join(basic_item["settings"]) + + basic_item = self._getVisibilityPresetById("basic") + basic_visibile_settings = ";".join(basic_item.settings) self._preferences = Application.getInstance().getPreferences() + # Preference to store which preset is currently selected self._preferences.addPreference("cura/active_setting_visibility_preset", "basic") + # Preference that stores the "custom" set so it can always be restored (even after a restart) self._preferences.addPreference("cura/custom_visible_settings", basic_visibile_settings) self._preferences.preferenceChanged.connect(self._onPreferencesChanged) - self._active_preset_item = self._getItem(self._preferences.getValue("cura/active_setting_visibility_preset")) + self._active_preset_item = self._getVisibilityPresetById(self._preferences.getValue("cura/active_setting_visibility_preset")) + # Initialize visible settings if it is not done yet visible_settings = self._preferences.getValue("general/visible_settings") if not visible_settings: - self._preferences.setValue("general/visible_settings", ";".join(self._active_preset_item["settings"])) + self._preferences.setValue("general/visible_settings", ";".join(self._active_preset_item.settings)) + else: self._onPreferencesChanged("general/visible_settings") self.activePresetChanged.emit() - def _getItem(self, item_id: str) -> Optional[dict]: + def _getVisibilityPresetById(self, item_id: str) -> Optional[SettingVisibilityPreset]: result = None - for item in self.items: - if item["id"] == item_id: + for item in self._items: + if item.id == item_id: result = item break return result def _populate(self) -> None: from cura.CuraApplication import CuraApplication - items = [] + items = [] # type: List[SettingVisibilityPreset] + + custom_preset = SettingVisibilityPreset(id = "custom", name = "Custom selection", weight = -100) + items.append(custom_preset) for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset): + setting_visibility_preset = SettingVisibilityPreset() try: - mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) - except MimeTypeNotFoundError: - Logger.log("e", "Could not determine mime type of file %s", file_path) - continue - - item_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_path))) - if not os.path.isfile(file_path): - Logger.log("e", "[%s] is not a file", file_path) - continue - - parser = ConfigParser(allow_no_value = True) # accept options without any value, - try: - parser.read([file_path]) - if not parser.has_option("general", "name") or not parser.has_option("general", "weight"): - continue - - settings = [] - for section in parser.sections(): - if section == 'general': - continue - - settings.append(section) - for option in parser[section].keys(): - settings.append(option) - - items.append({ - "id": item_id, - "name": catalog.i18nc("@action:inmenu", parser["general"]["name"]), - "weight": parser["general"]["weight"], - "settings": settings, - }) - + setting_visibility_preset.loadFromFile(file_path) except Exception: Logger.logException("e", "Failed to load setting preset %s", file_path) - items.sort(key = lambda k: (int(k["weight"]), k["id"])) - # Put "custom" at the top - items.insert(0, {"id": "custom", - "name": "Custom selection", - "weight": -100, - "settings": []}) + items.append(setting_visibility_preset) + + # Sort them on weight (and if that fails, use ID) + items.sort(key = lambda k: (int(k.weight), k.id)) self.setItems(items) + @pyqtProperty("QVariantList", notify = onItemsChanged) + def items(self): + return self._items + + def setItems(self, items: List[SettingVisibilityPreset]) -> None: + if self._items != items: + self._items = items + self.onItemsChanged.emit() + @pyqtSlot(str) - def setActivePreset(self, preset_id: str): - if preset_id == self._active_preset_item["id"]: + def setActivePreset(self, preset_id: str) -> None: + if preset_id == self._active_preset_item.id: Logger.log("d", "Same setting visibility preset [%s] selected, do nothing.", preset_id) return - preset_item = None - for item in self.items: - if item["id"] == preset_id: - preset_item = item - break + preset_item = self._getVisibilityPresetById(preset_id) if preset_item is None: Logger.log("w", "Tried to set active preset to unknown id [%s]", preset_id) return - need_to_save_to_custom = self._active_preset_item["id"] == "custom" and preset_id != "custom" + need_to_save_to_custom = self._active_preset_item.id == "custom" and preset_id != "custom" if need_to_save_to_custom: # Save the current visibility settings to custom current_visibility_string = self._preferences.getValue("general/visible_settings") if current_visibility_string: self._preferences.setValue("cura/custom_visible_settings", current_visibility_string) - new_visibility_string = ";".join(preset_item["settings"]) + new_visibility_string = ";".join(preset_item.settings) if preset_id == "custom": # Get settings from the stored custom data new_visibility_string = self._preferences.getValue("cura/custom_visible_settings") @@ -141,11 +122,9 @@ class SettingVisibilityPresetsModel(ListModel): self._active_preset_item = preset_item self.activePresetChanged.emit() - activePresetChanged = pyqtSignal() - @pyqtProperty(str, notify = activePresetChanged) def activePreset(self) -> str: - return self._active_preset_item["id"] + return self._active_preset_item.id def _onPreferencesChanged(self, name: str) -> None: if name != "general/visible_settings": @@ -158,25 +137,26 @@ class SettingVisibilityPresetsModel(ListModel): visibility_set = set(visibility_string.split(";")) matching_preset_item = None - for item in self.items: - if item["id"] == "custom": + for item in self._items: + if item.id == "custom": continue - if set(item["settings"]) == visibility_set: + if set(item.settings) == visibility_set: matching_preset_item = item break item_to_set = self._active_preset_item if matching_preset_item is None: # The new visibility setup is "custom" should be custom - if self._active_preset_item["id"] == "custom": + if self._active_preset_item.id == "custom": # We are already in custom, just save the settings self._preferences.setValue("cura/custom_visible_settings", visibility_string) else: - item_to_set = self.items[0] # 0 is custom + # We need to move to custom preset. + item_to_set = self._getVisibilityPresetById("custom") else: item_to_set = matching_preset_item - if self._active_preset_item is None or self._active_preset_item["id"] != item_to_set["id"]: + if self._active_preset_item is None or self._active_preset_item.id != item_to_set.id: self._active_preset_item = item_to_set - self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item["id"]) + self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item.id) self.activePresetChanged.emit() diff --git a/cura/Settings/SettingVisibilityPreset.py b/cura/Settings/SettingVisibilityPreset.py new file mode 100644 index 0000000000..8b175a0d01 --- /dev/null +++ b/cura/Settings/SettingVisibilityPreset.py @@ -0,0 +1,87 @@ +import os +import urllib.parse +from configparser import ConfigParser +from typing import List + +from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal + +from UM.Logger import Logger +from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError + + +class SettingVisibilityPreset(QObject): + onSettingsChanged = pyqtSignal() + onNameChanged = pyqtSignal() + onWeightChanged = pyqtSignal() + onIdChanged = pyqtSignal() + + def __init__(self, id: str = "", name: str = "" , weight: int = 0, parent = None) -> None: + super().__init__(parent) + self._settings = [] # type: List[str] + self._id = id + self._weight = weight + self._name = name + + @pyqtProperty("QStringList", notify = onSettingsChanged) + def settings(self) -> List[str]: + return self._settings + + @pyqtProperty(str, notify=onIdChanged) + def id(self) -> str: + return self._id + + @pyqtProperty(int, notify=onWeightChanged) + def weight(self) -> int: + return self._weight + + @pyqtProperty(str, notify=onNameChanged) + def name(self) -> str: + return self._name + + def setName(self, name: str) -> None: + if name != self._name: + self._name = name + self.onNameChanged.emit() + + def setId(self, id: int) -> None: + if id != self._id: + self._id = id + self.onIdChanged.emit() + + def setWeight(self, weight: str) -> None: + if weight != self._weight: + self._weight = weight + self.onWeightChanged.emit() + + def setSettings(self, settings: List[str]) -> None: + if settings != self._settings: + self._settings = settings + self.onSettingsChanged.emit() + + def loadFromFile(self, file_path: str) -> None: + mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) + + item_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_path))) + if not os.path.isfile(file_path): + Logger.log("e", "[%s] is not a file", file_path) + return None + + parser = ConfigParser(allow_no_value=True) # Accept options without any value, + + parser.read([file_path]) + if not parser.has_option("general", "name") or not parser.has_option("general", "weight"): + return None + + settings = [] # type: List[str] + for section in parser.sections(): + if section == "general": + continue + + settings.append(section) + for option in parser[section].keys(): + settings.append(option) + self.setSettings(settings) + self.setId(item_id) + self.setName(parser["general"]["name"]) + self.setWeight(parser["general"]["weight"]) + diff --git a/resources/qml/Menus/SettingVisibilityPresetsMenu.qml b/resources/qml/Menus/SettingVisibilityPresetsMenu.qml index c34dc2a484..fecabfa860 100644 --- a/resources/qml/Menus/SettingVisibilityPresetsMenu.qml +++ b/resources/qml/Menus/SettingVisibilityPresetsMenu.qml @@ -18,17 +18,17 @@ Menu Instantiator { - model: settingVisibilityPresetsModel + model: settingVisibilityPresetsModel.items MenuItem { - text: model.name + text: modelData.name checkable: true - checked: model.id == settingVisibilityPresetsModel.activePreset + checked: modelData.id == settingVisibilityPresetsModel.activePreset exclusiveGroup: group onTriggered: { - settingVisibilityPresetsModel.setActivePreset(model.id); + settingVisibilityPresetsModel.setActivePreset(modelData.id); } } diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 0f39a3c047..90c805f854 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -110,24 +110,23 @@ UM.PreferencesPage right: parent.right } - model: settingVisibilityPresetsModel + model: settingVisibilityPresetsModel.items textRole: "name" currentIndex: { - // Load previously selected preset. - var index = settingVisibilityPresetsModel.find("id", settingVisibilityPresetsModel.activePreset) - if (index == -1) - { - return 0 + for(var i = 0; i < settingVisibilityPresetsModel.items.length; ++i) { + if(settingVisibilityPresetsModel.items[i].id == settingVisibilityPresetsModel.activePreset) { + currentIndex = i; + return; + } } - - return index + return -1 } onActivated: { - var preset_id = settingVisibilityPresetsModel.getItem(index).id; + var preset_id = settingVisibilityPresetsModel.items[index].id; settingVisibilityPresetsModel.setActivePreset(preset_id); } } From 7e7afa7c063de3af0b28b40aa5fe1b769872daf5 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 1 Oct 2018 11:51:07 +0200 Subject: [PATCH 2/9] Ensure that the SettingVisibilityPresetsModel doesn't have duplicated settings CURA-5734 --- cura/Machines/Models/SettingVisibilityPresetsModel.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index 38c6176e4e..cd0233747d 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -81,7 +81,8 @@ class SettingVisibilityPresetsModel(QObject): # Sort them on weight (and if that fails, use ID) items.sort(key = lambda k: (int(k.weight), k.id)) - self.setItems(items) + # Set items and ensure there are no duplicated values + self.setItems(list(set(items))) @pyqtProperty("QVariantList", notify = onItemsChanged) def items(self): From edb5de99542cae94d97a861cd8725d216985919a Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 1 Oct 2018 14:50:53 +0200 Subject: [PATCH 3/9] Added unit test for settingvisibility presets CURA-5734 --- cura/CuraApplication.py | 2 +- .../Models/SettingVisibilityPresetsModel.py | 19 ++-- cura/Settings/SettingVisibilityPreset.py | 4 +- .../Settings/TestSettingVisibilityPresets.py | 90 +++++++++++++++++++ .../setting_visiblity_preset_test.cfg | 11 +++ 5 files changed, 113 insertions(+), 13 deletions(-) create mode 100644 tests/Settings/TestSettingVisibilityPresets.py create mode 100644 tests/Settings/setting_visiblity_preset_test.cfg diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 18f86959a7..989ed27dea 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -702,7 +702,7 @@ class CuraApplication(QtApplication): self._cura_actions = CuraActions.CuraActions(self) # Initialize setting visibility presets model. - self._setting_visibility_presets_model = SettingVisibilityPresetsModel(self) + self._setting_visibility_presets_model = SettingVisibilityPresetsModel(self.getPreferences(), parent = self) # Detect in which mode to run and execute that mode if self._is_headless: diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index cd0233747d..8ce87f4640 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -25,16 +25,16 @@ class SettingVisibilityPresetsModel(QObject): onItemsChanged = pyqtSignal() activePresetChanged = pyqtSignal() - def __init__(self, parent = None): + def __init__(self, preferences, parent = None): super().__init__(parent) self._items = [] # type: List[SettingVisibilityPreset] self._populate() - basic_item = self._getVisibilityPresetById("basic") + basic_item = self.getVisibilityPresetById("basic") basic_visibile_settings = ";".join(basic_item.settings) - self._preferences = Application.getInstance().getPreferences() + self._preferences = preferences # Preference to store which preset is currently selected self._preferences.addPreference("cura/active_setting_visibility_preset", "basic") @@ -43,19 +43,19 @@ class SettingVisibilityPresetsModel(QObject): self._preferences.addPreference("cura/custom_visible_settings", basic_visibile_settings) self._preferences.preferenceChanged.connect(self._onPreferencesChanged) - self._active_preset_item = self._getVisibilityPresetById(self._preferences.getValue("cura/active_setting_visibility_preset")) + self._active_preset_item = self.getVisibilityPresetById(self._preferences.getValue("cura/active_setting_visibility_preset")) # Initialize visible settings if it is not done yet visible_settings = self._preferences.getValue("general/visible_settings") + if not visible_settings: self._preferences.setValue("general/visible_settings", ";".join(self._active_preset_item.settings)) - else: self._onPreferencesChanged("general/visible_settings") self.activePresetChanged.emit() - def _getVisibilityPresetById(self, item_id: str) -> Optional[SettingVisibilityPreset]: + def getVisibilityPresetById(self, item_id: str) -> Optional[SettingVisibilityPreset]: result = None for item in self._items: if item.id == item_id: @@ -81,8 +81,7 @@ class SettingVisibilityPresetsModel(QObject): # Sort them on weight (and if that fails, use ID) items.sort(key = lambda k: (int(k.weight), k.id)) - # Set items and ensure there are no duplicated values - self.setItems(list(set(items))) + self.setItems(items) @pyqtProperty("QVariantList", notify = onItemsChanged) def items(self): @@ -99,7 +98,7 @@ class SettingVisibilityPresetsModel(QObject): Logger.log("d", "Same setting visibility preset [%s] selected, do nothing.", preset_id) return - preset_item = self._getVisibilityPresetById(preset_id) + preset_item = self.getVisibilityPresetById(preset_id) if preset_item is None: Logger.log("w", "Tried to set active preset to unknown id [%s]", preset_id) return @@ -153,7 +152,7 @@ class SettingVisibilityPresetsModel(QObject): self._preferences.setValue("cura/custom_visible_settings", visibility_string) else: # We need to move to custom preset. - item_to_set = self._getVisibilityPresetById("custom") + item_to_set = self.getVisibilityPresetById("custom") else: item_to_set = matching_preset_item diff --git a/cura/Settings/SettingVisibilityPreset.py b/cura/Settings/SettingVisibilityPreset.py index 8b175a0d01..23bbbad951 100644 --- a/cura/Settings/SettingVisibilityPreset.py +++ b/cura/Settings/SettingVisibilityPreset.py @@ -54,8 +54,8 @@ class SettingVisibilityPreset(QObject): self.onWeightChanged.emit() def setSettings(self, settings: List[str]) -> None: - if settings != self._settings: - self._settings = settings + if set(settings) != set(self._settings): + self._settings = list(set(settings)) # filter out non unique self.onSettingsChanged.emit() def loadFromFile(self, file_path: str) -> None: diff --git a/tests/Settings/TestSettingVisibilityPresets.py b/tests/Settings/TestSettingVisibilityPresets.py new file mode 100644 index 0000000000..bdc3fdc43e --- /dev/null +++ b/tests/Settings/TestSettingVisibilityPresets.py @@ -0,0 +1,90 @@ +from unittest.mock import MagicMock + +from UM.Preferences import Preferences +import os.path + +from UM.Preferences import Preferences +from UM.Resources import Resources +from cura.CuraApplication import CuraApplication +from cura.Machines.Models.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel +from cura.Settings.SettingVisibilityPreset import SettingVisibilityPreset + +setting_visibility_preset_test_settings = set(["test", "zomg", "derp", "yay", "whoo"]) + +Resources.addSearchPath(os.path.abspath(os.path.join(os.path.join(os.path.dirname(__file__)), "../..", "resources"))) +Resources.addStorageType(CuraApplication.ResourceTypes.SettingVisibilityPreset, "setting_visibility") + + +def test_settingVisibilityPreset(): + # Simple creation test. This is seperated from the visibilityFromPrevious, since we can't check for the contents + # of the other profiles, since they might change over time. + visibility_preset = SettingVisibilityPreset() + + visibility_preset.loadFromFile(os.path.join(os.path.dirname(os.path.abspath(__file__)), "setting_visiblity_preset_test.cfg")) + assert setting_visibility_preset_test_settings == set(visibility_preset.settings) + + assert visibility_preset.name == "test" + assert visibility_preset.weight == '1' + assert visibility_preset.settings.count("yay") == 1 # It's in the file twice but we should load it once. + +def test_visibilityFromPrevious(): + # This test checks that all settings in basic are in advanced and all settings in advanced are in expert. + + visibility_model = SettingVisibilityPresetsModel(Preferences()) + + basic_visibility = visibility_model.getVisibilityPresetById("basic") + advanced_visibility = visibility_model.getVisibilityPresetById("advanced") + expert_visibility = visibility_model.getVisibilityPresetById("expert") + + # Check if there are settings that are in basic, but not in advanced. + settings_not_in_advanced = set(basic_visibility.settings) - set(advanced_visibility.settings) + assert len(settings_not_in_advanced) == 0 # All settings in basic should be in advanced + + # Check if there are settings that are in advanced, but not in expert. + settings_not_in_expert = set(advanced_visibility.settings) - set(expert_visibility.settings) + assert len(settings_not_in_expert) == 0 # All settings in advanced should be in expert. + + +def test_setActivePreset(): + preferences = Preferences() + visibility_model = SettingVisibilityPresetsModel(preferences) + visibility_model.activePresetChanged = MagicMock() + # Ensure that we start of with basic (since we didn't change anyting just yet!) + assert visibility_model.activePreset == "basic" + + # Everything should be the same. + visibility_model.setActivePreset("basic") + assert visibility_model.activePreset == "basic" + assert visibility_model.activePresetChanged.emit.call_count == 0 # No events should be sent. + + # Change it to existing type (should work...) + visibility_model.setActivePreset("advanced") + assert visibility_model.activePreset == "advanced" + assert visibility_model.activePresetChanged.emit.call_count == 1 + + # Change to unknown preset. Shouldn't do anything. + visibility_model.setActivePreset("OMGZOMGNOPE") + assert visibility_model.activePreset == "advanced" + assert visibility_model.activePresetChanged.emit.call_count == 1 + + +def test_preferenceChanged(): + preferences = Preferences() + # Set the visible_settings to something silly + preferences.addPreference("general/visible_settings", "omgzomg") + visibility_model = SettingVisibilityPresetsModel(preferences) + visibility_model.activePresetChanged = MagicMock() + + assert visibility_model.activePreset == "custom" # This should make the model start at "custom + assert visibility_model.activePresetChanged.emit.call_count == 0 + + + basic_visibility = visibility_model.getVisibilityPresetById("basic") + new_visibility_string = ";".join(basic_visibility.settings) + preferences.setValue("general/visible_settings", new_visibility_string) + + # Fake a signal emit (since we didn't create the application, our own signals are not fired) + visibility_model._onPreferencesChanged("general/visible_settings") + # Set the visibility settings to basic + assert visibility_model.activePreset == "basic" + assert visibility_model.activePresetChanged.emit.call_count == 1 diff --git a/tests/Settings/setting_visiblity_preset_test.cfg b/tests/Settings/setting_visiblity_preset_test.cfg new file mode 100644 index 0000000000..0a89bf6b14 --- /dev/null +++ b/tests/Settings/setting_visiblity_preset_test.cfg @@ -0,0 +1,11 @@ +[general] +name = test +weight = 1 + +[test] +zomg +derp +yay + +[whoo] +yay \ No newline at end of file From fe9db9a26010b0b7f6170be0865f853c74468172 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 1 Oct 2018 14:51:11 +0200 Subject: [PATCH 4/9] Removed the old setting check script CURA-5734 --- scripts/check_setting_visibility.py | 239 ---------------------------- 1 file changed, 239 deletions(-) delete mode 100755 scripts/check_setting_visibility.py diff --git a/scripts/check_setting_visibility.py b/scripts/check_setting_visibility.py deleted file mode 100755 index 8fb5d5b293..0000000000 --- a/scripts/check_setting_visibility.py +++ /dev/null @@ -1,239 +0,0 @@ -#!/usr/bin/env python3 -# -# This script checks the correctness of the list of visibility settings -# -import collections -import configparser -import json -import os -import sys -from typing import Any, Dict, List - -# Directory where this python file resides -SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) - - -# -# This class -# -class SettingVisibilityInspection: - - def __init__(self) -> None: - # The order of settings type. If the setting is in basic list then it also should be in expert - self._setting_visibility_order = ["basic", "advanced", "expert"] - - # This is dictionary with categories as keys and all setting keys as values. - self.all_settings_keys = {} # type: Dict[str, List[str]] - - # Load all Cura setting keys from the given fdmprinter.json file - def loadAllCuraSettingKeys(self, fdmprinter_json_path: str) -> None: - with open(fdmprinter_json_path, "r", encoding = "utf-8") as f: - json_data = json.load(f) - - # Get all settings keys in each category - for key, data in json_data["settings"].items(): # top level settings are categories - if "type" in data and data["type"] == "category": - self.all_settings_keys[key] = [] - self._flattenSettings(data["children"], key) # actual settings are children of top level category-settings - - def _flattenSettings(self, settings: Dict[str, str], category: str) -> None: - for key, setting in settings.items(): - if "type" in setting and setting["type"] != "category": - self.all_settings_keys[category].append(key) - - if "children" in setting: - self._flattenSettings(setting["children"], category) - - # Loads the given setting visibility file and returns a dict with categories as keys and a list of setting keys as - # values. - def _loadSettingVisibilityConfigFile(self, file_name: str) -> Dict[str, List[str]]: - with open(file_name, "r", encoding = "utf-8") as f: - parser = configparser.ConfigParser(allow_no_value = True) - parser.read_file(f) - - data_dict = {} - for category, option_dict in parser.items(): - if category in (parser.default_section, "general"): - continue - - data_dict[category] = [] - for key in option_dict: - data_dict[category].append(key) - - return data_dict - - def validateSettingsVisibility(self, setting_visibility_files: Dict[str, str]) -> Dict[str, Dict[str, Any]]: - # First load all setting visibility files into the dict "setting_visibility_dict" in the following structure: - # -> -> - # "basic" -> "info" - setting_visibility_dict = {} # type: Dict[str, Dict[str, List[str]]] - for visibility_name, file_path in setting_visibility_files.items(): - setting_visibility_dict[visibility_name] = self._loadSettingVisibilityConfigFile(file_path) - - # The result is in the format: - # -> dict - # "basic" -> "file_name": "basic.cfg" - # "is_valid": True / False - # "invalid_categories": List[str] - # "invalid_settings": Dict[category -> List[str]] - # "missing_categories_from_previous": List[str] - # "missing_settings_from_previous": Dict[category -> List[str]] - all_result_dict = dict() # type: Dict[str, Dict[str, Any]] - - previous_result = None - previous_visibility_dict = None - is_all_valid = True - for visibility_name in self._setting_visibility_order: - invalid_categories = [] - invalid_settings = collections.defaultdict(list) - - this_visibility_dict = setting_visibility_dict[visibility_name] - # Check if categories and keys exist at all - for category, key_list in this_visibility_dict.items(): - if category not in self.all_settings_keys: - invalid_categories.append(category) - continue # If this category doesn't exist at all, not need to check for details - - for key in key_list: - if key not in self.all_settings_keys[category]: - invalid_settings[category].append(key) - - is_settings_valid = len(invalid_categories) == 0 and len(invalid_settings) == 0 - file_path = setting_visibility_files[visibility_name] - result_dict = {"file_name": os.path.basename(file_path), - "is_valid": is_settings_valid, - "invalid_categories": invalid_categories, - "invalid_settings": invalid_settings, - "missing_categories_from_previous": list(), - "missing_settings_from_previous": dict(), - } - - # If this is not the first item in the list, check if the settings are defined in the previous - # visibility file. - # A visibility with more details SHOULD add more settings. It SHOULD NOT remove any settings defined - # in the less detailed visibility. - if previous_visibility_dict is not None: - missing_categories_from_previous = [] - missing_settings_from_previous = collections.defaultdict(list) - - for prev_category, prev_key_list in previous_visibility_dict.items(): - # Skip the categories that are invalid - if prev_category in previous_result["invalid_categories"]: - continue - if prev_category not in this_visibility_dict: - missing_categories_from_previous.append(prev_category) - continue - - this_key_list = this_visibility_dict[prev_category] - for key in prev_key_list: - # Skip the settings that are invalid - if key in previous_result["invalid_settings"][prev_category]: - continue - - if key not in this_key_list: - missing_settings_from_previous[prev_category].append(key) - - result_dict["missing_categories_from_previous"] = missing_categories_from_previous - result_dict["missing_settings_from_previous"] = missing_settings_from_previous - is_settings_valid = len(missing_categories_from_previous) == 0 and len(missing_settings_from_previous) == 0 - result_dict["is_valid"] = result_dict["is_valid"] and is_settings_valid - - # Update the complete result dict - all_result_dict[visibility_name] = result_dict - previous_result = result_dict - previous_visibility_dict = this_visibility_dict - - is_all_valid = is_all_valid and result_dict["is_valid"] - - all_result_dict["all_results"] = {"is_valid": is_all_valid} - - return all_result_dict - - def printResults(self, all_result_dict: Dict[str, Dict[str, Any]]) -> None: - print("") - print("Setting Visibility Check Results:") - - prev_visibility_name = None - for visibility_name in self._setting_visibility_order: - if visibility_name not in all_result_dict: - continue - - result_dict = all_result_dict[visibility_name] - print("=============================") - result_str = "OK" if result_dict["is_valid"] else "INVALID" - print("[%s] : [%s] : %s" % (visibility_name, result_dict["file_name"], result_str)) - - if result_dict["is_valid"]: - continue - - # Print details of invalid settings - if result_dict["invalid_categories"]: - print("It has the following non-existing CATEGORIES:") - for category in result_dict["invalid_categories"]: - print(" - [%s]" % category) - - if result_dict["invalid_settings"]: - print("") - print("It has the following non-existing SETTINGS:") - for category, key_list in result_dict["invalid_settings"].items(): - for key in key_list: - print(" - [%s / %s]" % (category, key)) - - if prev_visibility_name is not None: - if result_dict["missing_categories_from_previous"]: - print("") - print("The following CATEGORIES are defined in the previous visibility [%s] but not here:" % prev_visibility_name) - for category in result_dict["missing_categories_from_previous"]: - print(" - [%s]" % category) - - if result_dict["missing_settings_from_previous"]: - print("") - print("The following SETTINGS are defined in the previous visibility [%s] but not here:" % prev_visibility_name) - for category, key_list in result_dict["missing_settings_from_previous"].items(): - for key in key_list: - print(" - [%s / %s]" % (category, key)) - - print("") - prev_visibility_name = visibility_name - - -# -# Returns a dictionary of setting visibility .CFG files in the given search directory. -# The dict has the name of the visibility type as the key (such as "basic", "advanced", "expert"), and -# the actual file path (absolute path). -# -def getAllSettingVisiblityFiles(search_dir: str) -> Dict[str, str]: - visibility_file_dict = dict() - extension = ".cfg" - for file_name in os.listdir(search_dir): - file_path = os.path.join(search_dir, file_name) - - # Only check files that has the .cfg extension - if not os.path.isfile(file_path): - continue - if not file_path.endswith(extension): - continue - - base_filename = os.path.basename(file_name)[:-len(extension)] - visibility_file_dict[base_filename] = file_path - return visibility_file_dict - - -def main() -> None: - setting_visibility_files_dir = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "resources", "setting_visibility")) - fdmprinter_def_path = os.path.abspath(os.path.join(SCRIPT_DIR, "..", "resources", "definitions", "fdmprinter.def.json")) - - setting_visibility_files_dict = getAllSettingVisiblityFiles(setting_visibility_files_dir) - - inspector = SettingVisibilityInspection() - inspector.loadAllCuraSettingKeys(fdmprinter_def_path) - - check_result = inspector.validateSettingsVisibility(setting_visibility_files_dict) - is_result_valid = check_result["all_results"]["is_valid"] - inspector.printResults(check_result) - - sys.exit(0 if is_result_valid else 1) - - -if __name__ == "__main__": - main() From 4def636fc97dca16fab99edd30e8bdb9d37a17aa Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 1 Oct 2018 14:54:08 +0200 Subject: [PATCH 5/9] Minor codecleanup (Typing & removing unused imports) CURA-5734 --- cura/Machines/Models/SettingVisibilityPresetsModel.py | 9 +-------- cura/Settings/SettingVisibilityPreset.py | 10 +++++----- tests/Settings/TestSettingVisibilityPresets.py | 2 +- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index 8ce87f4640..b5f7fa8626 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -2,18 +2,11 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import Optional, List -import os -import urllib.parse -from configparser import ConfigParser -from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QObject +from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject - -from UM.Application import Application from UM.Logger import Logger -from UM.Qt.ListModel import ListModel from UM.Resources import Resources -from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError from UM.i18n import i18nCatalog from cura.Settings.SettingVisibilityPreset import SettingVisibilityPreset diff --git a/cura/Settings/SettingVisibilityPreset.py b/cura/Settings/SettingVisibilityPreset.py index 23bbbad951..b1828362d1 100644 --- a/cura/Settings/SettingVisibilityPreset.py +++ b/cura/Settings/SettingVisibilityPreset.py @@ -6,7 +6,7 @@ from typing import List from PyQt5.QtCore import pyqtProperty, QObject, pyqtSignal from UM.Logger import Logger -from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError +from UM.MimeTypeDatabase import MimeTypeDatabase class SettingVisibilityPreset(QObject): @@ -15,7 +15,7 @@ class SettingVisibilityPreset(QObject): onWeightChanged = pyqtSignal() onIdChanged = pyqtSignal() - def __init__(self, id: str = "", name: str = "" , weight: int = 0, parent = None) -> None: + def __init__(self, id: str = "", name: str = "", weight: int = 0, parent = None) -> None: super().__init__(parent) self._settings = [] # type: List[str] self._id = id @@ -43,12 +43,12 @@ class SettingVisibilityPreset(QObject): self._name = name self.onNameChanged.emit() - def setId(self, id: int) -> None: + def setId(self, id: str) -> None: if id != self._id: self._id = id self.onIdChanged.emit() - def setWeight(self, weight: str) -> None: + def setWeight(self, weight: int) -> None: if weight != self._weight: self._weight = weight self.onWeightChanged.emit() @@ -83,5 +83,5 @@ class SettingVisibilityPreset(QObject): self.setSettings(settings) self.setId(item_id) self.setName(parser["general"]["name"]) - self.setWeight(parser["general"]["weight"]) + self.setWeight(int(parser["general"]["weight"])) diff --git a/tests/Settings/TestSettingVisibilityPresets.py b/tests/Settings/TestSettingVisibilityPresets.py index bdc3fdc43e..68e8a6eb7b 100644 --- a/tests/Settings/TestSettingVisibilityPresets.py +++ b/tests/Settings/TestSettingVisibilityPresets.py @@ -24,7 +24,7 @@ def test_settingVisibilityPreset(): assert setting_visibility_preset_test_settings == set(visibility_preset.settings) assert visibility_preset.name == "test" - assert visibility_preset.weight == '1' + assert visibility_preset.weight == 1 assert visibility_preset.settings.count("yay") == 1 # It's in the file twice but we should load it once. def test_visibilityFromPrevious(): From b37252f124c76fa06c860fa20de4b6cca85645a1 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 10 Oct 2018 14:18:37 +0200 Subject: [PATCH 6/9] Minor code style fixes Contributes to issue CURA-5734. --- cura/Machines/Models/SettingVisibilityPresetsModel.py | 2 +- cura/Settings/SettingVisibilityPreset.py | 8 ++++---- resources/qml/Preferences/SettingVisibilityPage.qml | 6 ++++-- tests/Settings/TestSettingVisibilityPresets.py | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index b5f7fa8626..d9bf105c0b 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -18,7 +18,7 @@ class SettingVisibilityPresetsModel(QObject): onItemsChanged = pyqtSignal() activePresetChanged = pyqtSignal() - def __init__(self, preferences, parent = None): + def __init__(self, preferences, parent = None): super().__init__(parent) self._items = [] # type: List[SettingVisibilityPreset] diff --git a/cura/Settings/SettingVisibilityPreset.py b/cura/Settings/SettingVisibilityPreset.py index b1828362d1..6e75a5a208 100644 --- a/cura/Settings/SettingVisibilityPreset.py +++ b/cura/Settings/SettingVisibilityPreset.py @@ -26,15 +26,15 @@ class SettingVisibilityPreset(QObject): def settings(self) -> List[str]: return self._settings - @pyqtProperty(str, notify=onIdChanged) + @pyqtProperty(str, notify = onIdChanged) def id(self) -> str: return self._id - @pyqtProperty(int, notify=onWeightChanged) + @pyqtProperty(int, notify = onWeightChanged) def weight(self) -> int: return self._weight - @pyqtProperty(str, notify=onNameChanged) + @pyqtProperty(str, notify = onNameChanged) def name(self) -> str: return self._name @@ -66,7 +66,7 @@ class SettingVisibilityPreset(QObject): Logger.log("e", "[%s] is not a file", file_path) return None - parser = ConfigParser(allow_no_value=True) # Accept options without any value, + parser = ConfigParser(allow_no_value = True) # Accept options without any value, parser.read([file_path]) if not parser.has_option("general", "name") or not parser.has_option("general", "weight"): diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml index 90c805f854..8896d0611e 100644 --- a/resources/qml/Preferences/SettingVisibilityPage.qml +++ b/resources/qml/Preferences/SettingVisibilityPage.qml @@ -115,8 +115,10 @@ UM.PreferencesPage currentIndex: { - for(var i = 0; i < settingVisibilityPresetsModel.items.length; ++i) { - if(settingVisibilityPresetsModel.items[i].id == settingVisibilityPresetsModel.activePreset) { + for(var i = 0; i < settingVisibilityPresetsModel.items.length; ++i) + { + if(settingVisibilityPresetsModel.items[i].id == settingVisibilityPresetsModel.activePreset) + { currentIndex = i; return; } diff --git a/tests/Settings/TestSettingVisibilityPresets.py b/tests/Settings/TestSettingVisibilityPresets.py index 68e8a6eb7b..1209437d25 100644 --- a/tests/Settings/TestSettingVisibilityPresets.py +++ b/tests/Settings/TestSettingVisibilityPresets.py @@ -49,7 +49,7 @@ def test_setActivePreset(): preferences = Preferences() visibility_model = SettingVisibilityPresetsModel(preferences) visibility_model.activePresetChanged = MagicMock() - # Ensure that we start of with basic (since we didn't change anyting just yet!) + # Ensure that we start off with basic (since we didn't change anyting just yet!) assert visibility_model.activePreset == "basic" # Everything should be the same. From d086e6fa86ce5f4ad32207a30bfa26fbdf55d8ca Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 17 Oct 2018 10:47:34 +0200 Subject: [PATCH 7/9] Fix review comments CURA-5734 --- .../Models/SettingVisibilityPresetsModel.py | 20 +++++++++---------- cura/Settings/SettingVisibilityPreset.py | 9 ++++++--- .../Menus/SettingVisibilityPresetsMenu.qml | 4 ++-- .../Settings/TestSettingVisibilityPresets.py | 3 +-- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/cura/Machines/Models/SettingVisibilityPresetsModel.py b/cura/Machines/Models/SettingVisibilityPresetsModel.py index d9bf105c0b..2702001d8a 100644 --- a/cura/Machines/Models/SettingVisibilityPresetsModel.py +++ b/cura/Machines/Models/SettingVisibilityPresetsModel.py @@ -51,7 +51,7 @@ class SettingVisibilityPresetsModel(QObject): def getVisibilityPresetById(self, item_id: str) -> Optional[SettingVisibilityPreset]: result = None for item in self._items: - if item.id == item_id: + if item.presetId == item_id: result = item break return result @@ -60,7 +60,7 @@ class SettingVisibilityPresetsModel(QObject): from cura.CuraApplication import CuraApplication items = [] # type: List[SettingVisibilityPreset] - custom_preset = SettingVisibilityPreset(id = "custom", name = "Custom selection", weight = -100) + custom_preset = SettingVisibilityPreset(preset_id="custom", name ="Custom selection", weight = -100) items.append(custom_preset) for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset): setting_visibility_preset = SettingVisibilityPreset() @@ -72,7 +72,7 @@ class SettingVisibilityPresetsModel(QObject): items.append(setting_visibility_preset) # Sort them on weight (and if that fails, use ID) - items.sort(key = lambda k: (int(k.weight), k.id)) + items.sort(key = lambda k: (int(k.weight), k.presetId)) self.setItems(items) @@ -87,7 +87,7 @@ class SettingVisibilityPresetsModel(QObject): @pyqtSlot(str) def setActivePreset(self, preset_id: str) -> None: - if preset_id == self._active_preset_item.id: + if preset_id == self._active_preset_item.presetId: Logger.log("d", "Same setting visibility preset [%s] selected, do nothing.", preset_id) return @@ -96,7 +96,7 @@ class SettingVisibilityPresetsModel(QObject): Logger.log("w", "Tried to set active preset to unknown id [%s]", preset_id) return - need_to_save_to_custom = self._active_preset_item.id == "custom" and preset_id != "custom" + need_to_save_to_custom = self._active_preset_item.presetId == "custom" and preset_id != "custom" if need_to_save_to_custom: # Save the current visibility settings to custom current_visibility_string = self._preferences.getValue("general/visible_settings") @@ -117,7 +117,7 @@ class SettingVisibilityPresetsModel(QObject): @pyqtProperty(str, notify = activePresetChanged) def activePreset(self) -> str: - return self._active_preset_item.id + return self._active_preset_item.presetId def _onPreferencesChanged(self, name: str) -> None: if name != "general/visible_settings": @@ -131,7 +131,7 @@ class SettingVisibilityPresetsModel(QObject): visibility_set = set(visibility_string.split(";")) matching_preset_item = None for item in self._items: - if item.id == "custom": + if item.presetId == "custom": continue if set(item.settings) == visibility_set: matching_preset_item = item @@ -140,7 +140,7 @@ class SettingVisibilityPresetsModel(QObject): item_to_set = self._active_preset_item if matching_preset_item is None: # The new visibility setup is "custom" should be custom - if self._active_preset_item.id == "custom": + if self._active_preset_item.presetId == "custom": # We are already in custom, just save the settings self._preferences.setValue("cura/custom_visible_settings", visibility_string) else: @@ -149,7 +149,7 @@ class SettingVisibilityPresetsModel(QObject): else: item_to_set = matching_preset_item - if self._active_preset_item is None or self._active_preset_item.id != item_to_set.id: + if self._active_preset_item is None or self._active_preset_item.presetId != item_to_set.presetId: self._active_preset_item = item_to_set - self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item.id) + self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item.presetId) self.activePresetChanged.emit() diff --git a/cura/Settings/SettingVisibilityPreset.py b/cura/Settings/SettingVisibilityPreset.py index 6e75a5a208..78807ea2fb 100644 --- a/cura/Settings/SettingVisibilityPreset.py +++ b/cura/Settings/SettingVisibilityPreset.py @@ -15,10 +15,10 @@ class SettingVisibilityPreset(QObject): onWeightChanged = pyqtSignal() onIdChanged = pyqtSignal() - def __init__(self, id: str = "", name: str = "", weight: int = 0, parent = None) -> None: + def __init__(self, preset_id: str = "", name: str = "", weight: int = 0, parent = None) -> None: super().__init__(parent) self._settings = [] # type: List[str] - self._id = id + self._id = preset_id self._weight = weight self._name = name @@ -27,7 +27,7 @@ class SettingVisibilityPreset(QObject): return self._settings @pyqtProperty(str, notify = onIdChanged) - def id(self) -> str: + def presetId(self) -> str: return self._id @pyqtProperty(int, notify = onWeightChanged) @@ -58,6 +58,9 @@ class SettingVisibilityPreset(QObject): self._settings = list(set(settings)) # filter out non unique self.onSettingsChanged.emit() + # Load a preset from file. We expect a file that can be parsed by means of the config parser. + # The sections indicate the categories and the parameters placed in it (which don't need values) are the settings + # that should be considered visible. def loadFromFile(self, file_path: str) -> None: mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path) diff --git a/resources/qml/Menus/SettingVisibilityPresetsMenu.qml b/resources/qml/Menus/SettingVisibilityPresetsMenu.qml index fecabfa860..8116b6def1 100644 --- a/resources/qml/Menus/SettingVisibilityPresetsMenu.qml +++ b/resources/qml/Menus/SettingVisibilityPresetsMenu.qml @@ -24,11 +24,11 @@ Menu { text: modelData.name checkable: true - checked: modelData.id == settingVisibilityPresetsModel.activePreset + checked: modelData.presetId == settingVisibilityPresetsModel.activePreset exclusiveGroup: group onTriggered: { - settingVisibilityPresetsModel.setActivePreset(modelData.id); + settingVisibilityPresetsModel.setActivePreset(modelData.presetId); } } diff --git a/tests/Settings/TestSettingVisibilityPresets.py b/tests/Settings/TestSettingVisibilityPresets.py index 1209437d25..48e8fc76cc 100644 --- a/tests/Settings/TestSettingVisibilityPresets.py +++ b/tests/Settings/TestSettingVisibilityPresets.py @@ -1,6 +1,5 @@ from unittest.mock import MagicMock -from UM.Preferences import Preferences import os.path from UM.Preferences import Preferences @@ -9,7 +8,7 @@ from cura.CuraApplication import CuraApplication from cura.Machines.Models.SettingVisibilityPresetsModel import SettingVisibilityPresetsModel from cura.Settings.SettingVisibilityPreset import SettingVisibilityPreset -setting_visibility_preset_test_settings = set(["test", "zomg", "derp", "yay", "whoo"]) +setting_visibility_preset_test_settings = {"test", "zomg", "derp", "yay", "whoo"} Resources.addSearchPath(os.path.abspath(os.path.join(os.path.join(os.path.dirname(__file__)), "../..", "resources"))) Resources.addStorageType(CuraApplication.ResourceTypes.SettingVisibilityPreset, "setting_visibility") From a58c63bbb8a031e0ea384a85093805fd889b73a2 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 17 Oct 2018 10:51:47 +0200 Subject: [PATCH 8/9] Minor fixes for visibility preset tests CURA-5734 --- tests/Settings/TestSettingVisibilityPresets.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Settings/TestSettingVisibilityPresets.py b/tests/Settings/TestSettingVisibilityPresets.py index 48e8fc76cc..b82aa62ea7 100644 --- a/tests/Settings/TestSettingVisibilityPresets.py +++ b/tests/Settings/TestSettingVisibilityPresets.py @@ -10,11 +10,11 @@ from cura.Settings.SettingVisibilityPreset import SettingVisibilityPreset setting_visibility_preset_test_settings = {"test", "zomg", "derp", "yay", "whoo"} -Resources.addSearchPath(os.path.abspath(os.path.join(os.path.join(os.path.dirname(__file__)), "../..", "resources"))) +Resources.addSearchPath(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "resources"))) Resources.addStorageType(CuraApplication.ResourceTypes.SettingVisibilityPreset, "setting_visibility") -def test_settingVisibilityPreset(): +def test_createVisibilityPresetFromLocalFile(): # Simple creation test. This is seperated from the visibilityFromPrevious, since we can't check for the contents # of the other profiles, since they might change over time. visibility_preset = SettingVisibilityPreset() From db0da61506b12e61dc276b79a4e3370c0a3c3c57 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 18 Oct 2018 14:54:20 +0200 Subject: [PATCH 9/9] Forbid interpolation in setting visibility preset files We might use characters that collide with this. Contributes to issue CURA-5734. --- cura/Settings/SettingVisibilityPreset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/SettingVisibilityPreset.py b/cura/Settings/SettingVisibilityPreset.py index 78807ea2fb..e8a4211d69 100644 --- a/cura/Settings/SettingVisibilityPreset.py +++ b/cura/Settings/SettingVisibilityPreset.py @@ -69,7 +69,7 @@ class SettingVisibilityPreset(QObject): Logger.log("e", "[%s] is not a file", file_path) return None - parser = ConfigParser(allow_no_value = True) # Accept options without any value, + parser = ConfigParser(interpolation = None, allow_no_value = True) # Accept options without any value, parser.read([file_path]) if not parser.has_option("general", "name") or not parser.has_option("general", "weight"):