mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-14 18:28:03 +08:00
Merge branch 'master' into top_most_skin_feature
This commit is contained in:
commit
d25e227707
22
README.md
22
README.md
@ -68,3 +68,25 @@ There are two ways of doing it. You can either use the generator [here](http://q
|
||||
* If your printer has a heated bed, set visible to true under material_bed_temperature
|
||||
|
||||
Once you are done, put the profile you have made into resources/definitions, or in definitions in your cura profile folder.
|
||||
|
||||
Translating Cura
|
||||
----------------
|
||||
If you'd like to contribute a translation of Cura, please first look for [any existing translation](https://github.com/Ultimaker/Cura/tree/master/resources/i18n). If your language is already there in the source code but not in Cura's interface, it may be partially translated.
|
||||
|
||||
There are four files that need to be translated for Cura:
|
||||
1. https://github.com/Ultimaker/Cura/blob/master/resources/i18n/cura.pot
|
||||
2. https://github.com/Ultimaker/Cura/blob/master/resources/i18n/fdmextruder.def.json.pot
|
||||
3. https://github.com/Ultimaker/Cura/blob/master/resources/i18n/fdmprinter.def.json.pot (This one is the most work.)
|
||||
4. https://github.com/Ultimaker/Uranium/blob/master/resources/i18n/uranium.pot
|
||||
|
||||
Copy these files and rename them to `*.po` (remove the `t`). Then create the actual translations by filling in the empty `msgstr` entries. These are gettext files, which are plain text so you can open them with any text editor such as Notepad or GEdit, but it is probably easier with a specialised tool such as [POEdit](https://poedit.net/) or [Virtaal](http://virtaal.translatehouse.org/).
|
||||
|
||||
Do not hestiate to ask us about a translation or the meaning of some text via Github Issues.
|
||||
|
||||
Once the translation is complete, it's probably best to test them in Cura. Use your favourite software to convert the .po file to a .mo file (such as [GetText](https://www.gnu.org/software/gettext/)). Then put the .mo files in the `.../resources/i18n/<language code>/LC_MESSAGES` folder in your Cura installation. Then find your Cura configuration file (next to the log as described above, except on Linux where it is located in `~/.config/cura`) and change the language preference to the name of the folder you just created. Then start Cura. If working correctly, your Cura should now be translated.
|
||||
|
||||
To submit your translation, ideally you would make two pull requests where all `*.po` files are located in that same `<language code>` folder in the resources of both the Cura and Uranium repositories. Put `cura.po`, `fdmprinter.def.json.po` and `fdmextruder.def.json.po` in the Cura repository, and put `uranium.po` in the Uranium repository. Then submit the pull requests to Github. For people with less experience with Git, you can also e-mail the translations to the e-mail address listed at the top of the [cura.pot](https://github.com/Ultimaker/Cura/blob/master/resources/i18n/cura.pot) file as the `Report-Msgid-Bugs-To` entry and we'll make sure it gets checked and included.
|
||||
|
||||
After the translation is submitted, the Cura maintainers will check for its completeness and check whether it is consistent. We will take special care to look for common mistakes, such as translating mark-up `<message>` code and such. We are often not fluent in every language, so we expect the translator and the international users to make corrections where necessary. Of course, there will always be some mistakes in every translation.
|
||||
|
||||
When the next Cura release comes around, some of the texts will have changed and some new texts will have been added. Around the time when the beta is released we will invoke a string freeze, meaning that no developer is allowed to make changes to the texts. Then we will update the translation template `.pot` files and ask all our translators to update their translations. If you are unable to update the translation in time for the actual release, we will remove the language from the drop-down menu in the Preferences window. The translation stays in Cura however, so that someone might pick it up again later and update it with the newest texts. Also, users who had previously selected the language can still continue Cura in their language but English text will appear among the original text.
|
@ -806,7 +806,7 @@ class CuraApplication(QtApplication):
|
||||
|
||||
@pyqtProperty(str, notify = sceneBoundingBoxChanged)
|
||||
def getSceneBoundingBoxString(self):
|
||||
return self._i18n_catalog.i18nc("@info", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()}
|
||||
return self._i18n_catalog.i18nc("@info 'width', 'depth' and 'height' are variable names that must NOT be translated; just translate the format of ##x##x## mm.", "%(width).1f x %(depth).1f x %(height).1f mm") % {'width' : self._scene_bounding_box.width.item(), 'depth': self._scene_bounding_box.depth.item(), 'height' : self._scene_bounding_box.height.item()}
|
||||
|
||||
def updatePlatformActivity(self, node = None):
|
||||
count = 0
|
||||
|
@ -282,7 +282,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
||||
profile.setDefinition(self._activeQualityDefinition())
|
||||
if self._machineHasOwnMaterials():
|
||||
active_material_id = self._activeMaterialId()
|
||||
if active_material_id: # only update if there is an active material
|
||||
if active_material_id and active_material_id != "empty": # only update if there is an active material
|
||||
profile.addMetaDataEntry("material", active_material_id)
|
||||
quality_type_criteria["material"] = active_material_id
|
||||
|
||||
|
@ -20,7 +20,7 @@ if TYPE_CHECKING:
|
||||
#
|
||||
#
|
||||
class ExtruderStack(CuraContainerStack):
|
||||
def __init__(self, container_id, *args, **kwargs):
|
||||
def __init__(self, container_id: str, *args, **kwargs):
|
||||
super().__init__(container_id, *args, **kwargs)
|
||||
|
||||
self.addMetaDataEntry("type", "extruder_train") # For backward compatibility
|
||||
|
@ -26,8 +26,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||
super().__init__()
|
||||
self._stack = ContainerStack(stack_id = id(self))
|
||||
self._stack.setDirty(False) # This stack does not need to be saved.
|
||||
self._instance = InstanceContainer(container_id = "SettingOverrideInstanceContainer")
|
||||
self._stack.addContainer(self._instance)
|
||||
self._stack.addContainer(InstanceContainer(container_id = "SettingOverrideInstanceContainer"))
|
||||
|
||||
if ExtruderManager.getInstance().extruderCount > 1:
|
||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||
@ -46,13 +45,14 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
||||
## Create a fresh decorator object
|
||||
deep_copy = SettingOverrideDecorator()
|
||||
## Copy the instance
|
||||
deep_copy._instance = copy.deepcopy(self._instance, memo)
|
||||
instance_container = copy.deepcopy(self._stack.getContainer(0), memo)
|
||||
|
||||
## Set the copied instance as the first (and only) instance container of the stack.
|
||||
deep_copy._stack.replaceContainer(0, instance_container)
|
||||
|
||||
# Properly set the right extruder on the copy
|
||||
deep_copy.setActiveExtruder(self._extruder_stack)
|
||||
|
||||
## Set the copied instance as the first (and only) instance container of the stack.
|
||||
deep_copy._stack.replaceContainer(0, deep_copy._instance)
|
||||
return deep_copy
|
||||
|
||||
## Gets the currently active extruder to print this object with.
|
||||
|
@ -56,6 +56,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
|
||||
self._id_mapping = {}
|
||||
|
||||
# In Cura 2.5 and 2.6, the empty profiles used to have those long names
|
||||
self._old_empty_profile_id_dict = {"empty_%s" % k: "empty" for k in ["material", "variant"]}
|
||||
|
||||
## Get a unique name based on the old_id. This is different from directly calling the registry in that it caches results.
|
||||
# This has nothing to do with speed, but with getting consistent new naming for instances & objects.
|
||||
def getNewId(self, old_id):
|
||||
@ -129,6 +132,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
instance_container_list = []
|
||||
material_container_list = []
|
||||
|
||||
resolve_strategy_keys = ["machine", "material", "quality_changes"]
|
||||
self._resolve_strategies = {k: None for k in resolve_strategy_keys}
|
||||
containers_found_dict = {k: False for k in resolve_strategy_keys}
|
||||
|
||||
#
|
||||
# Read definition containers
|
||||
#
|
||||
@ -176,8 +183,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
container_id = self._stripFileToId(material_container_file)
|
||||
materials = self._container_registry.findInstanceContainers(id=container_id)
|
||||
material_labels.append(self._getMaterialLabelFromSerialized(archive.open(material_container_file).read().decode("utf-8")))
|
||||
if materials and not materials[0].isReadOnly(): # Only non readonly materials can be in conflict
|
||||
material_conflict = True
|
||||
if materials:
|
||||
containers_found_dict["material"] = True
|
||||
if not materials[0].isReadOnly(): # Only non readonly materials can be in conflict
|
||||
material_conflict = True
|
||||
Job.yieldThread()
|
||||
|
||||
# Check if any quality_changes instance container is in conflict.
|
||||
@ -205,6 +214,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# Check if quality changes already exists.
|
||||
quality_changes = self._container_registry.findInstanceContainers(id = container_id)
|
||||
if quality_changes:
|
||||
containers_found_dict["quality_changes"] = True
|
||||
# Check if there really is a conflict by comparing the values
|
||||
if quality_changes[0] != instance_container:
|
||||
quality_changes_conflict = True
|
||||
@ -227,21 +237,73 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# Load ContainerStack files and ExtruderStack files
|
||||
global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(
|
||||
file_name, cura_file_names)
|
||||
self._resolve_strategies = {"machine": None, "quality_changes": None, "material": None}
|
||||
machine_conflict = False
|
||||
for container_stack_file in [global_stack_file] + extruder_stack_files:
|
||||
container_id = self._stripFileToId(container_stack_file)
|
||||
serialized = archive.open(container_stack_file).read().decode("utf-8")
|
||||
if machine_name == "":
|
||||
machine_name = self._getMachineNameFromSerializedStack(serialized)
|
||||
stacks = self._container_registry.findContainerStacks(id = container_id)
|
||||
if stacks:
|
||||
# Check if there are any changes at all in any of the container stacks.
|
||||
# Because there can be cases as follows:
|
||||
# - the global stack exists but some/all of the extruder stacks DON'T exist
|
||||
# - the global stack DOESN'T exist but some/all of the extruder stacks exist
|
||||
# To simplify this, only check if the global stack exists or not
|
||||
container_id = self._stripFileToId(global_stack_file)
|
||||
serialized = archive.open(global_stack_file).read().decode("utf-8")
|
||||
machine_name = self._getMachineNameFromSerializedStack(serialized)
|
||||
stacks = self._container_registry.findContainerStacks(id = container_id)
|
||||
if stacks:
|
||||
global_stack = stacks[0]
|
||||
containers_found_dict["machine"] = True
|
||||
# Check if there are any changes at all in any of the container stacks.
|
||||
id_list = self._getContainerIdListFromSerialized(serialized)
|
||||
for index, container_id in enumerate(id_list):
|
||||
# take into account the old empty container IDs
|
||||
container_id = self._old_empty_profile_id_dict.get(container_id, container_id)
|
||||
# HACK: there used to be 5, now we have one more 5 - definition changes
|
||||
if len(id_list) == 6 and index == 5:
|
||||
if global_stack.getContainer(5).getId() != "empty":
|
||||
machine_conflict = True
|
||||
break
|
||||
index = 6
|
||||
if global_stack.getContainer(index).getId() != container_id:
|
||||
machine_conflict = True
|
||||
break
|
||||
Job.yieldThread()
|
||||
|
||||
# if the global stack is found, we check if there are conflicts in the extruder stacks
|
||||
if containers_found_dict["machine"] and not machine_conflict:
|
||||
for extruder_stack_file in extruder_stack_files:
|
||||
container_id = self._stripFileToId(extruder_stack_file)
|
||||
serialized = archive.open(extruder_stack_file).read().decode("utf-8")
|
||||
parser = configparser.ConfigParser()
|
||||
parser.read_string(serialized)
|
||||
|
||||
# The check should be done for the extruder stack that's associated with the existing global stack,
|
||||
# and those extruder stacks may have different IDs.
|
||||
# So we check according to the positions
|
||||
|
||||
position = str(parser["metadata"]["position"])
|
||||
if position not in global_stack.extruders:
|
||||
# The extruder position defined in the project doesn't exist in this global stack.
|
||||
# We can say that it is a machine conflict, but it is very hard to override the machine in this
|
||||
# case because we need to override the existing extruders and add the non-existing extruders.
|
||||
#
|
||||
# HACK:
|
||||
# To make this simple, we simply say that there is no machine conflict and create a new machine
|
||||
# by default.
|
||||
machine_conflict = False
|
||||
break
|
||||
|
||||
existing_extruder_stack = global_stack.extruders[position]
|
||||
# check if there are any changes at all in any of the container stacks.
|
||||
id_list = self._getContainerIdListFromSerialized(serialized)
|
||||
for index, container_id in enumerate(id_list):
|
||||
if stacks[0].getContainer(index).getId() != container_id:
|
||||
# take into account the old empty container IDs
|
||||
container_id = self._old_empty_profile_id_dict.get(container_id, container_id)
|
||||
# HACK: there used to be 5, now we have one more 5 - definition changes
|
||||
if len(id_list) == 6 and index == 5:
|
||||
if existing_extruder_stack.getContainer(5).getId() != "empty":
|
||||
machine_conflict = True
|
||||
break
|
||||
index = 6
|
||||
if existing_extruder_stack.getContainer(index).getId() != container_id:
|
||||
machine_conflict = True
|
||||
Job.yieldThread()
|
||||
break
|
||||
|
||||
num_visible_settings = 0
|
||||
try:
|
||||
@ -301,10 +363,14 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# - new: create a new container
|
||||
# - override: override the existing container
|
||||
# - None: There is no conflict, which means containers with the same IDs may or may not be there already.
|
||||
# If they are there, there is no conflict between the them.
|
||||
# In this case, you can either create a new one, or safely override the existing one.
|
||||
# If there is an existing container, there is no conflict between the them, and default to "override"
|
||||
# If there is no existing container, default to "new"
|
||||
#
|
||||
# Default values
|
||||
for key, strategy in self._resolve_strategies.items():
|
||||
if key not in containers_found_dict or strategy is not None:
|
||||
continue
|
||||
self._resolve_strategies[key] = "override" if containers_found_dict[key] else "new"
|
||||
|
||||
return WorkspaceReader.PreReadResult.accepted
|
||||
|
||||
@ -568,47 +634,43 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# --
|
||||
# load global stack file
|
||||
try:
|
||||
# Check if a stack by this ID already exists;
|
||||
container_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
|
||||
if container_stacks:
|
||||
if self._resolve_strategies["machine"] == "override":
|
||||
container_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
|
||||
stack = container_stacks[0]
|
||||
|
||||
if self._resolve_strategies["machine"] == "override":
|
||||
# TODO: HACK
|
||||
# There is a machine, check if it has authentication data. If so, keep that data.
|
||||
network_authentication_id = container_stacks[0].getMetaDataEntry("network_authentication_id")
|
||||
network_authentication_key = container_stacks[0].getMetaDataEntry("network_authentication_key")
|
||||
container_stacks[0].deserialize(archive.open(global_stack_file).read().decode("utf-8"))
|
||||
if network_authentication_id:
|
||||
container_stacks[0].addMetaDataEntry("network_authentication_id", network_authentication_id)
|
||||
if network_authentication_key:
|
||||
container_stacks[0].addMetaDataEntry("network_authentication_key", network_authentication_key)
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
stack = GlobalStack(global_stack_id_new)
|
||||
stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"))
|
||||
# HACK
|
||||
# There is a machine, check if it has authentication data. If so, keep that data.
|
||||
network_authentication_id = container_stacks[0].getMetaDataEntry("network_authentication_id")
|
||||
network_authentication_key = container_stacks[0].getMetaDataEntry("network_authentication_key")
|
||||
container_stacks[0].deserialize(archive.open(global_stack_file).read().decode("utf-8"))
|
||||
if network_authentication_id:
|
||||
container_stacks[0].addMetaDataEntry("network_authentication_id", network_authentication_id)
|
||||
if network_authentication_key:
|
||||
container_stacks[0].addMetaDataEntry("network_authentication_key", network_authentication_key)
|
||||
|
||||
# Ensure a unique ID and name
|
||||
stack._id = global_stack_id_new
|
||||
|
||||
# Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
|
||||
# bound machine also needs to change.
|
||||
if stack.getMetaDataEntry("machine", None):
|
||||
stack.setMetaDataEntry("machine", global_stack_id_new)
|
||||
|
||||
# Only machines need a new name, stacks may be non-unique
|
||||
stack.setName(self._container_registry.uniqueName(stack.getName()))
|
||||
container_stacks_added.append(stack)
|
||||
self._container_registry.addContainer(stack)
|
||||
else:
|
||||
Logger.log("w", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
|
||||
else:
|
||||
# no existing container stack, so we create a new one
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
# create a new global stack
|
||||
stack = GlobalStack(global_stack_id_new)
|
||||
# Deserialize stack by converting read data from bytes to string
|
||||
stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"))
|
||||
|
||||
# Ensure a unique ID and name
|
||||
stack._id = global_stack_id_new
|
||||
|
||||
# Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
|
||||
# bound machine also needs to change.
|
||||
if stack.getMetaDataEntry("machine", None):
|
||||
stack.setMetaDataEntry("machine", global_stack_id_new)
|
||||
|
||||
# Only machines need a new name, stacks may be non-unique
|
||||
stack.setName(self._container_registry.uniqueName(stack.getName()))
|
||||
|
||||
container_stacks_added.append(stack)
|
||||
self._container_registry.addContainer(stack)
|
||||
containers_added.append(stack)
|
||||
else:
|
||||
Logger.log("e", "Resolve strategy of %s for machine is not supported",
|
||||
self._resolve_strategies["machine"])
|
||||
|
||||
global_stack = stack
|
||||
Job.yieldThread()
|
||||
@ -622,73 +684,40 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# --
|
||||
# load extruder stack files
|
||||
try:
|
||||
for index, extruder_stack_file in enumerate(extruder_stack_files):
|
||||
for extruder_stack_file in extruder_stack_files:
|
||||
container_id = self._stripFileToId(extruder_stack_file)
|
||||
extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8")
|
||||
|
||||
container_stacks = self._container_registry.findContainerStacks(id = container_id)
|
||||
if container_stacks:
|
||||
# this container stack already exists, try to resolve
|
||||
stack = container_stacks[0]
|
||||
if self._resolve_strategies["machine"] == "override":
|
||||
# deserialize new extruder stack over the current ones
|
||||
stack = self._overrideExtruderStack(global_stack, extruder_file_content)
|
||||
|
||||
if self._resolve_strategies["machine"] == "override":
|
||||
# NOTE: This is the same code as those in the lower part
|
||||
# deserialize new extruder stack over the current ones
|
||||
stack = self._overrideExtruderStack(global_stack, extruder_file_content)
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
new_id = extruder_stack_id_map[container_id]
|
||||
stack = ExtruderStack(new_id)
|
||||
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
# create a new extruder stack from this one
|
||||
new_id = extruder_stack_id_map[container_id]
|
||||
stack = ExtruderStack(new_id)
|
||||
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
|
||||
# references to the new name instead of the old one. Normally, this can be done after
|
||||
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
|
||||
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
|
||||
# to the right machine BEFORE deserialization.
|
||||
extruder_config = configparser.ConfigParser()
|
||||
extruder_config.read_string(extruder_file_content)
|
||||
extruder_config.set("metadata", "machine", global_stack_id_new)
|
||||
tmp_string_io = io.StringIO()
|
||||
extruder_config.write(tmp_string_io)
|
||||
extruder_file_content = tmp_string_io.getvalue()
|
||||
|
||||
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
|
||||
# references to the new name instead of the old one. Normally, this can be done after
|
||||
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
|
||||
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
|
||||
# to the right machine BEFORE deserialization.
|
||||
extruder_config = configparser.ConfigParser()
|
||||
extruder_config.read_string(extruder_file_content)
|
||||
extruder_config.set("metadata", "machine", global_stack_id_new)
|
||||
tmp_string_io = io.StringIO()
|
||||
extruder_config.write(tmp_string_io)
|
||||
extruder_file_content = tmp_string_io.getvalue()
|
||||
stack.deserialize(extruder_file_content)
|
||||
|
||||
stack.deserialize(extruder_file_content)
|
||||
# Ensure a unique ID and name
|
||||
stack._id = new_id
|
||||
|
||||
# Ensure a unique ID and name
|
||||
stack._id = new_id
|
||||
|
||||
self._container_registry.addContainer(stack)
|
||||
extruder_stacks_added.append(stack)
|
||||
containers_added.append(stack)
|
||||
self._container_registry.addContainer(stack)
|
||||
extruder_stacks_added.append(stack)
|
||||
containers_added.append(stack)
|
||||
else:
|
||||
# No extruder stack with the same ID can be found
|
||||
if self._resolve_strategies["machine"] == "override":
|
||||
# deserialize new extruder stack over the current ones
|
||||
stack = self._overrideExtruderStack(global_stack, extruder_file_content)
|
||||
|
||||
elif self._resolve_strategies["machine"] == "new":
|
||||
# container not found, create a new one
|
||||
stack = ExtruderStack(container_id)
|
||||
|
||||
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
|
||||
# references to the new name instead of the old one. Normally, this can be done after
|
||||
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
|
||||
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
|
||||
# to the right machine BEFORE deserialization.
|
||||
extruder_config = configparser.ConfigParser()
|
||||
extruder_config.read_string(extruder_file_content)
|
||||
extruder_config.set("metadata", "machine", global_stack_id_new)
|
||||
tmp_string_io = io.StringIO()
|
||||
extruder_config.write(tmp_string_io)
|
||||
extruder_file_content = tmp_string_io.getvalue()
|
||||
|
||||
stack.deserialize(extruder_file_content)
|
||||
self._container_registry.addContainer(stack)
|
||||
extruder_stacks_added.append(stack)
|
||||
containers_added.append(stack)
|
||||
else:
|
||||
Logger.log("w", "Unknown resolve strategy: %s" % str(self._resolve_strategies["machine"]))
|
||||
Logger.log("w", "Unknown resolve strategy: %s", self._resolve_strategies["machine"])
|
||||
|
||||
extruder_stacks.append(stack)
|
||||
except:
|
||||
|
@ -90,6 +90,6 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
|
||||
|
||||
# Do not include the network authentication keys
|
||||
ignore_keys = ["network_authentication_id", "network_authentication_key"]
|
||||
serialized_data = container.serialize(ignore_metadata_keys = ignore_keys)
|
||||
serialized_data = container.serialize(ignored_metadata_keys = ignore_keys)
|
||||
|
||||
archive.writestr(file_in_archive, serialized_data)
|
||||
|
@ -755,7 +755,7 @@ Cura.MachineAction
|
||||
{
|
||||
if(!activeFocus)
|
||||
{
|
||||
propertyProvider.setPropertyValue("value", gcodeField.text)
|
||||
propertyProvider.setPropertyValue("value", gcodeArea.text)
|
||||
}
|
||||
}
|
||||
Component.onCompleted:
|
||||
|
@ -40,7 +40,7 @@ class SliceInfo(Extension):
|
||||
Preferences.getInstance().addPreference("info/asked_send_slice_info", False)
|
||||
|
||||
if not Preferences.getInstance().getValue("info/asked_send_slice_info"):
|
||||
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymised slicing statistics. You can disable this in preferences"), lifetime = 0, dismissable = False)
|
||||
self.send_slice_info_message = Message(catalog.i18nc("@info", "Cura collects anonymised slicing statistics. You can disable this in the preferences."), lifetime = 0, dismissable = False)
|
||||
self.send_slice_info_message.addAction("Dismiss", catalog.i18nc("@action:button", "Dismiss"), None, "")
|
||||
self.send_slice_info_message.actionTriggered.connect(self.messageActionTriggered)
|
||||
self.send_slice_info_message.show()
|
||||
|
@ -193,7 +193,7 @@ Cura.MachineAction
|
||||
wrapMode: Text.WordWrap
|
||||
//: Tips label
|
||||
//TODO: get actual link from webteam
|
||||
text: catalog.i18nc("@label", "If your printer is not listed, read the <a href='%1'>network-printing troubleshooting guide</a>").arg("https://ultimaker.com/en/troubleshooting");
|
||||
text: catalog.i18nc("@label", "If your printer is not listed, read the <a href='%1'>network printing troubleshooting guide</a>").arg("https://ultimaker.com/en/troubleshooting");
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
import copy
|
||||
import io
|
||||
from typing import Optional
|
||||
from typing import List, Optional
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from UM.Resources import Resources
|
||||
@ -109,7 +109,7 @@ class XmlMaterialProfile(InstanceContainer):
|
||||
## Overridden from InstanceContainer
|
||||
# base file: common settings + supported machines
|
||||
# machine / variant combination: only changes for itself.
|
||||
def serialize(self, ignore_metadata_keys=[]):
|
||||
def serialize(self, ignored_metadata_keys: Optional[List] = None):
|
||||
registry = ContainerRegistry.getInstance()
|
||||
|
||||
base_file = self.getMetaDataEntry("base_file", "")
|
||||
@ -130,9 +130,11 @@ class XmlMaterialProfile(InstanceContainer):
|
||||
|
||||
metadata = copy.deepcopy(self.getMetaData())
|
||||
# setting_version is derived from the "version" tag in the schema, so don't serialize it into a file
|
||||
ignore_metadata_keys = ignore_metadata_keys + ["setting_version"]
|
||||
if ignored_metadata_keys is None:
|
||||
ignored_metadata_keys = []
|
||||
ignored_metadata_keys = ignored_metadata_keys + ["setting_version"]
|
||||
# remove the keys that we want to ignore in the metadata
|
||||
for key in ignore_metadata_keys:
|
||||
for key in ignored_metadata_keys:
|
||||
if key in metadata:
|
||||
del metadata[key]
|
||||
properties = metadata.pop("properties", {})
|
||||
|
@ -304,7 +304,7 @@
|
||||
"options":
|
||||
{
|
||||
"RepRap (Marlin/Sprinter)": "Marlin",
|
||||
"RepRap (Volumatric)": "Marlin (Volumetric)",
|
||||
"RepRap (Volumetric)": "Marlin (Volumetric)",
|
||||
"RepRap (RepRap)": "RepRap",
|
||||
"UltiGCode": "Ultimaker 2",
|
||||
"Griffin": "Griffin",
|
||||
|
3543
resources/i18n/pl/cura.po
Normal file
3543
resources/i18n/pl/cura.po
Normal file
File diff suppressed because it is too large
Load Diff
180
resources/i18n/pl/fdmextruder.def.json.po
Normal file
180
resources/i18n/pl/fdmextruder.def.json.po
Normal file
@ -0,0 +1,180 @@
|
||||
# Cura JSON setting files
|
||||
# Copyright (C) 2017 Ultimaker
|
||||
# This file is distributed under the same license as the Cura package.
|
||||
# Ruben Dulek <r.dulek@ultimaker.com>, 2017.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Cura 2.6\n"
|
||||
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
|
||||
"POT-Creation-Date: 2017-05-30 15:32+0000\n"
|
||||
"PO-Revision-Date: 2017-07-13 16:08+0200\n"
|
||||
"Last-Translator: jagus85\n"
|
||||
"Language-Team: reprapy.pl\n"
|
||||
"Language: Polish\n"
|
||||
"Lang-Code: pl\n"
|
||||
"Country-Code: PL\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 2.0.2\n"
|
||||
|
||||
msgctxt "extruder_nr description"
|
||||
msgid "The extruder train used for printing. This is used in multi-extrusion."
|
||||
msgstr ""
|
||||
"Urządzenie do drukowania stosuje się głowicę drukującą. Służy do multi-"
|
||||
"ekstruzji."
|
||||
|
||||
msgctxt "extruder_nr label"
|
||||
msgid "Extruder"
|
||||
msgstr "Extruder"
|
||||
|
||||
msgctxt "extruder_prime_pos_x description"
|
||||
msgid ""
|
||||
"The X coordinate of the position where the nozzle primes at the start of "
|
||||
"printing."
|
||||
msgstr ""
|
||||
"Die X-Koordinate der Position, an der die Düse am Druckbeginn einzieht."
|
||||
|
||||
msgctxt "extruder_prime_pos_x label"
|
||||
msgid "Extruder Prime X Position"
|
||||
msgstr "X-Position Extruder-Einzug"
|
||||
|
||||
msgctxt "extruder_prime_pos_y description"
|
||||
msgid ""
|
||||
"The Y coordinate of the position where the nozzle primes at the start of "
|
||||
"printing."
|
||||
msgstr ""
|
||||
"Die Y-Koordinate der Position, an der die Düse am Druckbeginn einzieht."
|
||||
|
||||
msgctxt "extruder_prime_pos_y label"
|
||||
msgid "Extruder Prime Y Position"
|
||||
msgstr "Y-Position Extruder-Einzug"
|
||||
|
||||
msgctxt "extruder_prime_pos_z description"
|
||||
msgid ""
|
||||
"The Z coordinate of the position where the nozzle primes at the start of "
|
||||
"printing."
|
||||
msgstr ""
|
||||
"Die Z-Koordinate der Position, an der die Düse am Druckbeginn einzieht."
|
||||
|
||||
msgctxt "extruder_prime_pos_z label"
|
||||
msgid "Extruder Prime Z Position"
|
||||
msgstr "Z-Position Extruder-Einzug"
|
||||
|
||||
msgctxt "machine_extruder_end_code description"
|
||||
msgid "End g-code to execute whenever turning the extruder off."
|
||||
msgstr "Beenden Sie den G-Code jedes Mal, wenn Sie den Extruder ausschalten."
|
||||
|
||||
msgctxt "machine_extruder_end_code label"
|
||||
msgid "Extruder End G-Code"
|
||||
msgstr "G-Code Extruder-Ende"
|
||||
|
||||
msgctxt "machine_extruder_end_pos_abs description"
|
||||
msgid ""
|
||||
"Make the extruder ending position absolute rather than relative to the last-"
|
||||
"known location of the head."
|
||||
msgstr ""
|
||||
"Bevorzugen Sie eine absolute Endposition des Extruders anstelle einer "
|
||||
"relativen Position zur zuletzt bekannten Kopfposition."
|
||||
|
||||
msgctxt "machine_extruder_end_pos_abs label"
|
||||
msgid "Extruder End Position Absolute"
|
||||
msgstr "Pozycja końca absolutnym głowicy drukującej"
|
||||
|
||||
msgctxt "machine_extruder_end_pos_x description"
|
||||
msgid "The x-coordinate of the ending position when turning the extruder off."
|
||||
msgstr "Die X-Koordinate der Endposition beim Ausschalten des Extruders."
|
||||
|
||||
msgctxt "machine_extruder_end_pos_x label"
|
||||
msgid "Extruder End Position X"
|
||||
msgstr "Extruder-Endposition X"
|
||||
|
||||
msgctxt "machine_extruder_end_pos_y description"
|
||||
msgid "The y-coordinate of the ending position when turning the extruder off."
|
||||
msgstr "Die Y-Koordinate der Endposition beim Ausschalten des Extruders."
|
||||
|
||||
msgctxt "machine_extruder_end_pos_y label"
|
||||
msgid "Extruder End Position Y"
|
||||
msgstr "Extruder-Endposition Y"
|
||||
|
||||
msgctxt "machine_extruder_start_code description"
|
||||
msgid "Start g-code to execute whenever turning the extruder on."
|
||||
msgstr "Zacznij każdym razem, gdy G-kod po włączeniu wytłaczarki."
|
||||
|
||||
msgctxt "machine_extruder_start_code label"
|
||||
msgid "Extruder Start G-Code"
|
||||
msgstr "G-kodu startowego głowicy drukującej"
|
||||
|
||||
msgctxt "machine_extruder_start_pos_abs description"
|
||||
msgid ""
|
||||
"Make the extruder starting position absolute rather than relative to the "
|
||||
"last-known location of the head."
|
||||
msgstr ""
|
||||
"Bevorzugen Sie eine absolute Startposition des Extruders anstelle einer "
|
||||
"relativen Position zur zuletzt bekannten Kopfposition."
|
||||
|
||||
msgctxt "machine_extruder_start_pos_abs label"
|
||||
msgid "Extruder Start Position Absolute"
|
||||
msgstr "Absolutną pozycję wyjściową wytłaczarki"
|
||||
|
||||
msgctxt "machine_extruder_start_pos_x description"
|
||||
msgid "The x-coordinate of the starting position when turning the extruder on."
|
||||
msgstr "Die X-Koordinate der Startposition beim Einschalten des Extruders."
|
||||
|
||||
msgctxt "machine_extruder_start_pos_x label"
|
||||
msgid "Extruder Start Position X"
|
||||
msgstr "X-Position Extruder-Start"
|
||||
|
||||
msgctxt "machine_extruder_start_pos_y description"
|
||||
msgid "The y-coordinate of the starting position when turning the extruder on."
|
||||
msgstr "Die Y-Koordinate der Startposition beim Einschalten des Extruders."
|
||||
|
||||
msgctxt "machine_extruder_start_pos_y label"
|
||||
msgid "Extruder Start Position Y"
|
||||
msgstr "Y-Position Extruder-Start"
|
||||
|
||||
msgctxt "machine_nozzle_offset_x description"
|
||||
msgid "The x-coordinate of the offset of the nozzle."
|
||||
msgstr "Współrzędnej X podziałki dysz."
|
||||
|
||||
msgctxt "machine_nozzle_offset_x label"
|
||||
msgid "Nozzle X Offset"
|
||||
msgstr "X przesunięcie dyszy"
|
||||
|
||||
msgctxt "machine_nozzle_offset_y description"
|
||||
msgid "The y-coordinate of the offset of the nozzle."
|
||||
msgstr "Współrzędnej Y podziałki dysz."
|
||||
|
||||
msgctxt "machine_nozzle_offset_y label"
|
||||
msgid "Nozzle Y Offset"
|
||||
msgstr "Y przesunięcie dyszę"
|
||||
|
||||
msgctxt "machine_nozzle_size description"
|
||||
msgid ""
|
||||
"The inner diameter of the nozzle. Change this setting when using a non-"
|
||||
"standard nozzle size."
|
||||
msgstr ""
|
||||
"Wewnętrzna średnica dyszy. Użyj tego ustawienia, jeśli używasz dyszę o "
|
||||
"niestandardowym rozmiarze."
|
||||
|
||||
msgctxt "machine_nozzle_size label"
|
||||
msgid "Nozzle Diameter"
|
||||
msgstr "średnica dyszy"
|
||||
|
||||
msgctxt "machine_settings description"
|
||||
msgid "Machine specific settings"
|
||||
msgstr "Ustawienia specyficzne dla urządzenia"
|
||||
|
||||
msgctxt "machine_settings label"
|
||||
msgid "Machine"
|
||||
msgstr "urządzenie"
|
||||
|
||||
msgctxt "platform_adhesion description"
|
||||
msgid "Adhesion"
|
||||
msgstr "odpowiedzialność"
|
||||
|
||||
msgctxt "platform_adhesion label"
|
||||
msgid "Build Plate Adhesion"
|
||||
msgstr "Druckplattenhaftung"
|
4923
resources/i18n/pl/fdmprinter.def.json.po
Normal file
4923
resources/i18n/pl/fdmprinter.def.json.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -125,7 +125,7 @@ UM.Dialog
|
||||
projectsModel.append({ name:"PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" });
|
||||
projectsModel.append({ name:"SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" });
|
||||
projectsModel.append({ name:"Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
|
||||
projectsModel.append({ name:"SciPy", description: catalog.i18nc("@label", "Support library for scientific computing "), license: "BSD-new", url: "https://www.scipy.org/" });
|
||||
projectsModel.append({ name:"SciPy", description: catalog.i18nc("@label", "Support library for scientific computing"), license: "BSD-new", url: "https://www.scipy.org/" });
|
||||
projectsModel.append({ name:"NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
|
||||
projectsModel.append({ name:"NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" });
|
||||
projectsModel.append({ name:"libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "AGPLv3", url: "https://github.com/ultimaker/libsavitar" });
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2016 Ultimaker B.V.
|
||||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
// Cura is released under the terms of the AGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
@ -23,7 +23,7 @@ Menu
|
||||
if(printerConnected && Cura.MachineManager.printerOutputDevices[0].hotendIds.length > extruderIndex)
|
||||
{
|
||||
var nozzleName = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex];
|
||||
return catalog.i18nc("@title:menuitem %1 is the value from the printer", "Automatic: %1").arg(nozzleName);
|
||||
return catalog.i18nc("@title:menuitem %1 is the nozzle currently loaded in the printer", "Automatic: %1").arg(nozzleName);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
@ -157,6 +157,7 @@ UM.PreferencesPage
|
||||
append({ text: "日本語", code: "jp" })
|
||||
append({ text: "한국어", code: "ko" })
|
||||
append({ text: "Nederlands", code: "nl" })
|
||||
append({ text: "Polski", code: "pl" })
|
||||
append({ text: "Português do Brasil", code: "ptbr" })
|
||||
append({ text: "Русский", code: "ru" })
|
||||
append({ text: "Türkçe", code: "tr" })
|
||||
|
Loading…
x
Reference in New Issue
Block a user