123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- # Copyright (c) 2018 Ultimaker B.V.
- # Cura is released under the terms of the LGPLv3 or higher.
- from typing import Optional
- import os
- import urllib.parse
- from configparser import ConfigParser
- from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot
- from UM.Logger import Logger
- from UM.Qt.ListModel import ListModel
- from UM.Preferences import Preferences
- from UM.Resources import Resources
- from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError
- from UM.i18n import i18nCatalog
- catalog = i18nCatalog("cura")
- class SettingVisibilityPresetsModel(ListModel):
- IdRole = Qt.UserRole + 1
- NameRole = Qt.UserRole + 2
- SettingsRole = Qt.UserRole + 3
- def __init__(self, parent = None):
- super().__init__(parent)
- self.addRoleName(self.IdRole, "id")
- self.addRoleName(self.NameRole, "name")
- self.addRoleName(self.SettingsRole, "settings")
- self._populate()
- basic_item = self.items[1]
- basic_visibile_settings = ";".join(basic_item["settings"])
- self._preferences = Preferences.getInstance()
- # 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"))
- # 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 _getItem(self, item_id: str) -> Optional[dict]:
- result = None
- for item in self.items:
- if item["id"] == item_id:
- result = item
- break
- return result
- def _populate(self):
- from cura.CuraApplication import CuraApplication
- items = []
- for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.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,
- })
- 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": []})
- self.setItems(items)
- @pyqtSlot(str)
- def setActivePreset(self, preset_id: str):
- 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
- 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"
- 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"])
- if preset_id == "custom":
- # Get settings from the stored custom data
- new_visibility_string = self._preferences.getValue("cura/custom_visible_settings")
- if new_visibility_string is None:
- new_visibility_string = self._preferences.getValue("general/visible_settings")
- self._preferences.setValue("general/visible_settings", new_visibility_string)
- self._preferences.setValue("cura/active_setting_visibility_preset", preset_id)
- 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"]
- def _onPreferencesChanged(self, name: str):
- if name != "general/visible_settings":
- return
- # Find the preset that matches with the current visible settings setup
- visibility_string = self._preferences.getValue("general/visible_settings")
- if not visibility_string:
- return
- visibility_set = set(visibility_string.split(";"))
- matching_preset_item = None
- for item in self.items:
- if item["id"] == "custom":
- continue
- 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":
- # 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
- else:
- item_to_set = matching_preset_item
- 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.activePresetChanged.emit()
|