Refactor setting visibility preset

CURA-5088
This commit is contained in:
Lipu Fei 2018-03-15 12:04:14 +01:00
parent 83175b00c2
commit 8e39849aad
3 changed files with 109 additions and 114 deletions

View File

@ -1,11 +1,12 @@
# Copyright (c) 2018 Ultimaker B.V. # Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher. # Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
import os import os
import urllib import urllib.parse
from configparser import ConfigParser from configparser import ConfigParser
from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QUrl from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot
from UM.Logger import Logger from UM.Logger import Logger
from UM.Qt.ListModel import ListModel from UM.Qt.ListModel import ListModel
@ -13,13 +14,14 @@ from UM.Preferences import Preferences
from UM.Resources import Resources from UM.Resources import Resources
from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError
import cura.CuraApplication from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
class SettingVisibilityPresetsModel(ListModel): class SettingVisibilityPresetsModel(ListModel):
IdRole = Qt.UserRole + 1 IdRole = Qt.UserRole + 1
NameRole = Qt.UserRole + 2 NameRole = Qt.UserRole + 2
SettingsRole = Qt.UserRole + 4 SettingsRole = Qt.UserRole + 3
def __init__(self, parent = None): def __init__(self, parent = None):
super().__init__(parent) super().__init__(parent)
@ -28,39 +30,51 @@ class SettingVisibilityPresetsModel(ListModel):
self.addRoleName(self.SettingsRole, "settings") self.addRoleName(self.SettingsRole, "settings")
self._populate() self._populate()
basic_item = self.items[1]
basic_visibile_settings = ";".join(basic_item["settings"])
self._preferences = Preferences.getInstance() self._preferences = Preferences.getInstance()
self._preferences.addPreference("cura/active_setting_visibility_preset", "custom") # Preference to store which preset is currently selected # Preference to store which preset is currently selected
self._preferences.addPreference("cura/custom_visible_settings", "") # Preference that stores the "custom" set so it can always be restored (even after a restart) 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._preferences.preferenceChanged.connect(self._onPreferencesChanged)
self._active_preset = self._preferences.getValue("cura/active_setting_visibility_preset") self._active_preset_item = self._getItem(self._preferences.getValue("cura/active_setting_visibility_preset"))
if self.find("id", self._active_preset) < 0: # Initialize visible settings if it is not done yet
self._active_preset = "custom" 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.activePresetChanged.emit() 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): def _populate(self):
from cura.CuraApplication import CuraApplication
items = [] items = []
for item in Resources.getAllResourcesOfType(cura.CuraApplication.CuraApplication.ResourceTypes.SettingVisibilityPreset): for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset):
try: try:
mime_type = MimeTypeDatabase.getMimeTypeForFile(item) mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path)
except MimeTypeNotFoundError: except MimeTypeNotFoundError:
Logger.log("e", "Could not determine mime type of file %s", item) Logger.log("e", "Could not determine mime type of file %s", file_path)
continue continue
id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(item))) item_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_path)))
if not os.path.isfile(file_path):
if not os.path.isfile(item): Logger.log("e", "[%s] is not a file", file_path)
continue continue
parser = ConfigParser(allow_no_value=True) # accept options without any value, parser = ConfigParser(allow_no_value = True) # accept options without any value,
try: try:
parser.read([item]) parser.read([file_path])
if not parser.has_option("general", "name") or not parser.has_option("general", "weight"):
if not parser.has_option("general", "name") and not parser.has_option("general", "weight"):
continue continue
settings = [] settings = []
@ -73,48 +87,90 @@ class SettingVisibilityPresetsModel(ListModel):
settings.append(option) settings.append(option)
items.append({ items.append({
"id": id, "id": item_id,
"name": parser["general"]["name"], "name": catalog.i18nc("@action:inmenu", parser["general"]["name"]),
"weight": parser["general"]["weight"], "weight": parser["general"]["weight"],
"settings": settings "settings": settings,
}) })
except Exception as e: except Exception:
Logger.log("e", "Failed to load setting preset %s: %s", file_path, str(e)) 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.sort(key = lambda k: (k["weight"], k["id"]))
self.setItems(items) self.setItems(items)
@pyqtSlot(str) @pyqtSlot(str)
def setActivePreset(self, preset_id): def setActivePreset(self, preset_id: str):
if preset_id != "custom" and self.find("id", preset_id) == -1: if preset_id == self._active_preset_item["id"]:
Logger.log("w", "Tried to set active preset to unknown id %s", preset_id) Logger.log("d", "Same setting visibility preset [%s] selected, do nothing.", preset_id)
return return
if preset_id == "custom" and self._active_preset == "custom": preset_item = None
# Copy current visibility set to custom visibility set preference so it can be restored later for item in self.items:
visibility_string = self._preferences.getValue("general/visible_settings") if item["id"] == preset_id:
self._preferences.setValue("cura/custom_visible_settings", visibility_string) 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._preferences.setValue("cura/active_setting_visibility_preset", preset_id)
self._active_preset_item = preset_item
self._active_preset = preset_id
self.activePresetChanged.emit() self.activePresetChanged.emit()
activePresetChanged = pyqtSignal() activePresetChanged = pyqtSignal()
@pyqtProperty(str, notify = activePresetChanged) @pyqtProperty(str, notify = activePresetChanged)
def activePreset(self): def activePreset(self) -> str:
return self._active_preset return self._active_preset_item["id"]
def _onPreferencesChanged(self, name): def _onPreferencesChanged(self, name: str):
if name != "general/visible_settings": if name != "general/visible_settings":
return return
if self._active_preset != "custom": # Find the preset that matches with the current visible settings setup
visibility_string = self._preferences.getValue("general/visible_settings")
if not visibility_string:
return return
# Copy current visibility set to custom visibility set preference so it can be restored later visibility_set = set(visibility_string.split(";"))
visibility_string = self._preferences.getValue("general/visible_settings") matching_preset_item = None
self._preferences.setValue("cura/custom_visible_settings", visibility_string) for item in self.items:
if item["id"] == "custom":
continue
if set(item["settings"]) == visibility_set:
matching_preset_item = item
break
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:
self._active_preset_item = self.items[0] # 0 is custom
self.activePresetChanged.emit()
else:
self._active_preset_item = matching_preset_item
self.activePresetChanged.emit()

View File

@ -1,8 +1,8 @@
// Copyright (c) 2018 Ultimaker B.V. // Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher. // Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.2 import QtQuick 2.7
import QtQuick.Controls 1.1 import QtQuick.Controls 1.4
import UM 1.2 as UM import UM 1.2 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
@ -19,22 +19,6 @@ Menu
signal showAllSettings() signal showAllSettings()
signal showSettingVisibilityProfile() signal showSettingVisibilityProfile()
MenuItem
{
text: catalog.i18nc("@action:inmenu", "Custom selection")
checkable: true
checked: !showingSearchResults && !showingAllSettings && settingVisibilityPresetsModel.activePreset == "custom"
exclusiveGroup: group
onTriggered:
{
settingVisibilityPresetsModel.setActivePreset("custom");
// Restore custom set from preference
UM.Preferences.setValue("general/visible_settings", UM.Preferences.getValue("cura/custom_visible_settings"));
showSettingVisibilityProfile();
}
}
MenuSeparator { }
Instantiator Instantiator
{ {
model: settingVisibilityPresetsModel model: settingVisibilityPresetsModel
@ -48,9 +32,6 @@ Menu
onTriggered: onTriggered:
{ {
settingVisibilityPresetsModel.setActivePreset(model.id); settingVisibilityPresetsModel.setActivePreset(model.id);
UM.Preferences.setValue("general/visible_settings", model.settings.join(";"));
showSettingVisibilityProfile(); showSettingVisibilityProfile();
} }
} }

View File

@ -29,8 +29,7 @@ UM.PreferencesPage
// After calling this function update Setting visibility preset combobox. // After calling this function update Setting visibility preset combobox.
// Reset should set default setting preset ("Basic") // Reset should set default setting preset ("Basic")
visibilityPreset.setDefaultPreset() visibilityPreset.currentIndex = 1
} }
resetEnabled: true; resetEnabled: true;
@ -39,8 +38,6 @@ UM.PreferencesPage
id: base; id: base;
anchors.fill: parent; anchors.fill: parent;
property bool inhibitSwitchToCustom: false
CheckBox CheckBox
{ {
id: toggleVisibleSettings id: toggleVisibleSettings
@ -114,11 +111,6 @@ UM.PreferencesPage
ComboBox ComboBox
{ {
function setDefaultPreset()
{
visibilityPreset.currentIndex = 0
}
id: visibilityPreset id: visibilityPreset
width: 150 * screenScaleFactor width: 150 * screenScaleFactor
anchors anchors
@ -127,50 +119,25 @@ UM.PreferencesPage
right: parent.right right: parent.right
} }
model: ListModel model: settingVisibilityPresetsModel
{ textRole: "name"
id: visibilityPresetsModel
Component.onCompleted:
{
visibilityPresetsModel.append({text: catalog.i18nc("@action:inmenu", "Custom selection"), id: "custom"});
for(var i = 0; i < settingVisibilityPresetsModel.rowCount(); i++)
{
visibilityPresetsModel.append({text: settingVisibilityPresetsModel.getItem(i)["name"], id: settingVisibilityPresetsModel.getItem(i)["id"]});
}
}
}
currentIndex: currentIndex:
{ {
// Load previously selected preset. // Load previously selected preset.
var index = settingVisibilityPresetsModel.find("id", settingVisibilityPresetsModel.activePreset); var index = settingVisibilityPresetsModel.find("id", settingVisibilityPresetsModel.activePreset)
if(index == -1) if (index == -1)
{ {
return 0; return 0
} }
return index + 1; // "Custom selection" entry is added in front, so index is off by 1 return index
} }
onActivated: onActivated:
{ {
base.inhibitSwitchToCustom = true; var preset_id = settingVisibilityPresetsModel.getItem(index).id;
var preset_id = visibilityPresetsModel.get(index).id;
settingVisibilityPresetsModel.setActivePreset(preset_id); settingVisibilityPresetsModel.setActivePreset(preset_id);
UM.Preferences.setValue("cura/active_setting_visibility_preset", preset_id);
if (preset_id != "custom")
{
UM.Preferences.setValue("general/visible_settings", settingVisibilityPresetsModel.getItem(index - 1).settings.join(";"));
// "Custom selection" entry is added in front, so index is off by 1
}
else
{
// Restore custom set from preference
UM.Preferences.setValue("general/visible_settings", UM.Preferences.getValue("cura/custom_visible_settings"));
}
base.inhibitSwitchToCustom = false;
} }
} }
@ -200,16 +167,7 @@ UM.PreferencesPage
exclude: ["machine_settings", "command_line_settings"] exclude: ["machine_settings", "command_line_settings"]
showAncestors: true showAncestors: true
expanded: ["*"] expanded: ["*"]
visibilityHandler: UM.SettingPreferenceVisibilityHandler visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
{
onVisibilityChanged:
{
if(settingVisibilityPresetsModel.activePreset != "" && !base.inhibitSwitchToCustom)
{
settingVisibilityPresetsModel.setActivePreset("custom");
}
}
}
} }
delegate: Loader delegate: Loader