Merge branch '3.2'

This commit is contained in:
Diego Prado Gesto 2018-01-31 09:13:29 +01:00
commit 81488e0bbc
12 changed files with 124 additions and 51 deletions

View file

@ -189,7 +189,7 @@ class CrashHandler:
json_metadata_file = os.path.join(directory, "plugin.json")
try:
with open(json_metadata_file, "r") as f:
with open(json_metadata_file, "r", encoding = "utf-8") as f:
try:
metadata = json.loads(f.read())
module_version = metadata["version"]
@ -217,9 +217,9 @@ class CrashHandler:
text_area = QTextEdit()
tmp_file_fd, tmp_file_path = tempfile.mkstemp(prefix = "cura-crash", text = True)
os.close(tmp_file_fd)
with open(tmp_file_path, "w") as f:
with open(tmp_file_path, "w", encoding = "utf-8") as f:
faulthandler.dump_traceback(f, all_threads=True)
with open(tmp_file_path, "r") as f:
with open(tmp_file_path, "r", encoding = "utf-8") as f:
logdata = f.read()
text_area.setText(logdata)

View file

@ -3,7 +3,7 @@
import copy
import os.path
import urllib
import urllib.parse
import uuid
from typing import Any, Dict, List, Union
@ -486,7 +486,7 @@ class ContainerManager(QObject):
container = container_type(container_id)
try:
with open(file_url, "rt") as f:
with open(file_url, "rt", encoding = "utf-8") as f:
container.deserialize(f.read())
except PermissionError:
return { "status": "error", "message": "Permission denied when trying to read the file"}

View file

@ -208,7 +208,7 @@ class CuraContainerRegistry(ContainerRegistry):
except Exception as e:
# Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
Logger.log("e", "Failed to import profile from %s: %s while using profile reader. Got exception %s", file_name,profile_reader.getPluginId(), str(e))
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, str(e))}
return { "status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Failed to import profile from <filename>{0}</filename>: <message>{1}</message>", file_name, "\n" + str(e))}
if profile_or_list:
# Ensure it is always a list of profiles
@ -246,6 +246,41 @@ class CuraContainerRegistry(ContainerRegistry):
if type(profile_or_list) is not list:
profile_or_list = [profile_or_list]
# Make sure that there are also extruder stacks' quality_changes, not just one for the global stack
if len(profile_or_list) == 1:
global_profile = profile_or_list[0]
extruder_profiles = []
for idx, extruder in enumerate(global_container_stack.extruders.values()):
profile_id = ContainerRegistry.getInstance().uniqueName(global_container_stack.getId() + "_extruder_" + str(idx + 1))
profile = InstanceContainer(profile_id)
profile.setName(global_profile.getName())
profile.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
profile.addMetaDataEntry("type", "quality_changes")
profile.addMetaDataEntry("definition", global_profile.getMetaDataEntry("definition"))
profile.addMetaDataEntry("quality_type", global_profile.getMetaDataEntry("quality_type"))
profile.addMetaDataEntry("extruder", extruder.getId())
profile.setDirty(True)
if idx == 0:
# move all per-extruder settings to the first extruder's quality_changes
for qc_setting_key in global_profile.getAllKeys():
settable_per_extruder = global_container_stack.getProperty(qc_setting_key,
"settable_per_extruder")
if settable_per_extruder:
setting_value = global_profile.getProperty(qc_setting_key, "value")
setting_definition = global_container_stack.getSettingDefinition(qc_setting_key)
new_instance = SettingInstance(setting_definition, profile)
new_instance.setProperty("value", setting_value)
new_instance.resetState() # Ensure that the state is not seen as a user state.
profile.addInstance(new_instance)
profile.setDirty(True)
global_profile.removeInstance(qc_setting_key, postpone_emit=True)
extruder_profiles.append(profile)
for profile in extruder_profiles:
profile_or_list.append(profile)
# Import all profiles
for profile_index, profile in enumerate(profile_or_list):
if profile_index == 0:
@ -296,7 +331,7 @@ class CuraContainerRegistry(ContainerRegistry):
profile.setDirty(True) # Ensure the profiles are correctly saved
new_id = self.createUniqueName("quality_changes", "", id_seed, catalog.i18nc("@label", "Custom profile"))
profile._id = new_id
profile.setMetaDataEntry("id", new_id)
profile.setName(new_name)
# Set the unique Id to the profile, so it's generating a new one even if the user imports the same profile
@ -507,9 +542,10 @@ class CuraContainerRegistry(ContainerRegistry):
user_container = InstanceContainer(user_container_id)
user_container.setName(user_container_name)
user_container.addMetaDataEntry("type", "user")
user_container.addMetaDataEntry("machine", extruder_stack.getId())
user_container.addMetaDataEntry("machine", machine.getId())
user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
user_container.setDefinition(machine.definition.getId())
user_container.setMetaDataEntry("extruder", extruder_stack.getId())
if machine.userChanges:
# for the newly created extruder stack, we need to move all "per-extruder" settings to the user changes
@ -693,7 +729,7 @@ class CuraContainerRegistry(ContainerRegistry):
continue
instance_container = InstanceContainer(container_id)
with open(file_path, "r") as f:
with open(file_path, "r", encoding = "utf-8") as f:
serialized = f.read()
instance_container.deserialize(serialized, file_path)
self.addContainer(instance_container)

View file

@ -30,8 +30,8 @@ if not known_args["debug"]:
if hasattr(sys, "frozen"):
dirpath = get_cura_dir_path()
os.makedirs(dirpath, exist_ok = True)
sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w")
sys.stderr = open(os.path.join(dirpath, "stderr.log"), "w")
sys.stdout = open(os.path.join(dirpath, "stdout.log"), "w", encoding = "utf-8")
sys.stderr = open(os.path.join(dirpath, "stderr.log"), "w", encoding = "utf-8")
import platform
import faulthandler

View file

@ -39,7 +39,7 @@ class CuraProfileReader(ProfileReader):
except zipfile.BadZipFile:
# It must be an older profile from Cura 2.1.
with open(file_name, encoding="utf-8") as fhandle:
with open(file_name, encoding = "utf-8") as fhandle:
serialized = fhandle.read()
return [self._loadProfile(serialized, profile_id) for serialized, profile_id in self._upgradeProfile(serialized, file_name)]
@ -52,10 +52,10 @@ class CuraProfileReader(ProfileReader):
parser = configparser.ConfigParser(interpolation=None)
parser.read_string(serialized)
if not "general" in parser:
if "general" not in parser:
Logger.log("w", "Missing required section 'general'.")
return []
if not "version" in parser["general"]:
if "version" not in parser["general"]:
Logger.log("w", "Missing required 'version' property")
return []

View file

@ -26,7 +26,7 @@ class GCodeReader(MeshReader):
# PreRead is used to get the correct flavor. If not, Marlin is set by default
def preRead(self, file_name, *args, **kwargs):
with open(file_name, "r") as file:
with open(file_name, "r", encoding = "utf-8") as file:
for line in file:
if line[:len(self._flavor_keyword)] == self._flavor_keyword:
try:

View file

@ -125,7 +125,10 @@ class LegacyProfileReader(ProfileReader):
Logger.log("e", "Dictionary of Doom has no translation. Is it the correct JSON file?")
return None
current_printer_definition = global_container_stack.definition
profile.setDefinition(current_printer_definition.getId())
quality_definition = current_printer_definition.getMetaDataEntry("quality_definition")
if not quality_definition:
quality_definition = current_printer_definition.getId()
profile.setDefinition(quality_definition)
for new_setting in dict_of_doom["translation"]: # Evaluate all new settings that would get a value from the translations.
old_setting_expression = dict_of_doom["translation"][new_setting]
compiled = compile(old_setting_expression, new_setting, "eval")
@ -162,20 +165,21 @@ class LegacyProfileReader(ProfileReader):
data = stream.getvalue()
profile.deserialize(data)
# The definition can get reset to fdmprinter during the deserialization's upgrade. Here we set the definition
# again.
profile.setDefinition(quality_definition)
#We need to return one extruder stack and one global stack.
global_container_id = container_registry.uniqueName("Global Imported Legacy Profile")
global_profile = profile.duplicate(new_id = global_container_id, new_name = profile_id) #Needs to have the same name as the extruder profile.
global_profile.setDirty(True)
#Only the extruder stack has an extruder metadata entry.
profile.addMetaDataEntry("extruder", ExtruderManager.getInstance().getActiveExtruderStack().definition.getId())
profile_definition = "fdmprinter"
from UM.Util import parseBool
if parseBool(global_container_stack.getMetaDataEntry("has_machine_quality", "False")):
profile_definition = global_container_stack.getMetaDataEntry("quality_definition")
if not profile_definition:
profile_definition = global_container_stack.definition.getId()
global_profile.setDefinition(profile_definition)
#Split all settings into per-extruder and global settings.
for setting_key in profile.getAllKeys():
settable_per_extruder = global_container_stack.getProperty(setting_key, "settable_per_extruder")
if settable_per_extruder:
global_profile.removeInstance(setting_key)
else:
profile.removeInstance(setting_key)
return [global_profile, profile]
return [global_profile]

View file

@ -2,7 +2,6 @@
# Uranium is released under the terms of the LGPLv3 or higher.
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.InstanceContainer import InstanceContainer
from cura.MachineAction import MachineAction
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
@ -11,8 +10,6 @@ from UM.Application import Application
from UM.Util import parseBool
catalog = i18nCatalog("cura")
import UM.Settings.InstanceContainer
## The Ultimaker 2 can have a few revisions & upgrades.
class UM2UpgradeSelection(MachineAction):
@ -22,18 +19,29 @@ class UM2UpgradeSelection(MachineAction):
self._container_registry = ContainerRegistry.getInstance()
self._current_global_stack = None
from cura.CuraApplication import CuraApplication
CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
self._reset()
def _reset(self):
self.hasVariantsChanged.emit()
def _onGlobalStackChanged(self):
if self._current_global_stack:
self._current_global_stack.metaDataChanged.disconnect(self._onGlobalStackMetaDataChanged)
self._current_global_stack = Application.getInstance().getGlobalContainerStack()
if self._current_global_stack:
self._current_global_stack.metaDataChanged.connect(self._onGlobalStackMetaDataChanged)
self._reset()
def _onGlobalStackMetaDataChanged(self):
self._reset()
hasVariantsChanged = pyqtSignal()
@pyqtProperty(bool, notify = hasVariantsChanged)
def hasVariants(self):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
return parseBool(global_container_stack.getMetaDataEntry("has_variants", "false"))
@pyqtSlot(bool)
def setHasVariants(self, has_variants = True):
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
@ -62,3 +70,9 @@ class UM2UpgradeSelection(MachineAction):
global_container_stack.extruders["0"].variant = ContainerRegistry.getInstance().getEmptyInstanceContainer()
Application.getInstance().globalContainerStackChanged.emit()
self._reset()
@pyqtProperty(bool, fset = setHasVariants, notify = hasVariantsChanged)
def hasVariants(self):
if self._current_global_stack:
return parseBool(self._current_global_stack.getMetaDataEntry("has_variants", "false"))

View file

@ -13,6 +13,7 @@ import Cura 1.0 as Cura
Cura.MachineAction
{
anchors.fill: parent;
Item
{
id: upgradeSelectionMachineAction
@ -39,12 +40,19 @@ Cura.MachineAction
CheckBox
{
id: olssonBlockCheckBox
anchors.top: pageDescription.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
text: catalog.i18nc("@label", "Olsson Block")
checked: manager.hasVariants
onClicked: manager.setHasVariants(checked)
onClicked: manager.hasVariants = checked
Connections
{
target: manager
onHasVariantsChanged: olssonBlockCheckBox.checked = manager.hasVariants
}
}
UM.I18nCatalog { id: catalog; name: "cura"; }

View file

@ -74,7 +74,7 @@ class VersionUpgrade22to24(VersionUpgrade):
def __convertVariant(self, variant_path):
# Copy the variant to the machine_instances/*_settings.inst.cfg
variant_config = configparser.ConfigParser(interpolation=None)
with open(variant_path, "r") as fhandle:
with open(variant_path, "r", encoding = "utf-8") as fhandle:
variant_config.read_file(fhandle)
config_name = "Unknown Variant"

View file

@ -59,6 +59,12 @@ _EMPTY_CONTAINER_DICT = {
}
# Renamed definition files
_RENAMED_DEFINITION_DICT = {
"jellybox": "imade3d_jellybox",
}
class VersionUpgrade30to31(VersionUpgrade):
## Gets the version number from a CFG file in Uranium's 3.0 format.
#
@ -111,16 +117,9 @@ class VersionUpgrade30to31(VersionUpgrade):
if not parser.has_section(each_section):
parser.add_section(each_section)
# Copy global quality changes to extruder quality changes for single extrusion machines
if parser["metadata"]["type"] == "quality_changes":
all_quality_changes = self._getSingleExtrusionMachineQualityChanges(parser)
# Note that DO NOT!!! use the quality_changes returned from _getSingleExtrusionMachineQualityChanges().
# Those are loaded from the hard drive which are original files that haven't been upgraded yet.
# NOTE 2: The number can be 0 or 1 depends on whether you are loading it from the qualities folder or
# from a project file. When you load from a project file, the custom profile may not be in cura
# yet, so you will get 0.
if len(all_quality_changes) <= 1 and not parser.has_option("metadata", "extruder"):
self._createExtruderQualityChangesForSingleExtrusionMachine(filename, parser)
# Check renamed definitions
if "definition" in parser["general"] and parser["general"]["definition"] in _RENAMED_DEFINITION_DICT:
parser["general"]["definition"] = _RENAMED_DEFINITION_DICT[parser["general"]["definition"]]
# Update version numbers
parser["general"]["version"] = "2"
@ -156,6 +155,10 @@ class VersionUpgrade30to31(VersionUpgrade):
if parser.has_option("containers", key) and parser["containers"][key] == "empty":
parser["containers"][key] = specific_empty_container
# check renamed definition
if parser.has_option("containers", "6") and parser["containers"]["6"] in _RENAMED_DEFINITION_DICT:
parser["containers"]["6"] = _RENAMED_DEFINITION_DICT[parser["containers"]["6"]]
# Update version numbers
if "general" not in parser:
parser["general"] = {}
@ -219,6 +222,10 @@ class VersionUpgrade30to31(VersionUpgrade):
extruder_quality_changes_parser["general"]["name"] = global_quality_changes["general"]["name"]
extruder_quality_changes_parser["general"]["definition"] = global_quality_changes["general"]["definition"]
# check renamed definition
if extruder_quality_changes_parser["general"]["definition"] in _RENAMED_DEFINITION_DICT:
extruder_quality_changes_parser["general"]["definition"] = _RENAMED_DEFINITION_DICT[extruder_quality_changes_parser["general"]["definition"]]
extruder_quality_changes_parser.add_section("metadata")
extruder_quality_changes_parser["metadata"]["quality_type"] = global_quality_changes["metadata"]["quality_type"]
extruder_quality_changes_parser["metadata"]["type"] = global_quality_changes["metadata"]["type"]
@ -231,5 +238,5 @@ class VersionUpgrade30to31(VersionUpgrade):
quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w") as f:
with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w", encoding = "utf-8") as f:
f.write(extruder_quality_changes_output.getvalue())

View file

@ -29,7 +29,11 @@ Menu
onObjectRemoved: menu.removeItem(object);
}
MenuSeparator { id: customSeparator }
MenuSeparator
{
id: customSeparator
visible: Cura.UserProfilesModel.rowCount > 0
}
Instantiator
{