Merge branch 'master' into CURA-4333_Notification_icon_for_recommended_mode

This commit is contained in:
Lipu Fei 2017-10-16 11:37:55 +02:00
commit 94a624e105
20 changed files with 293 additions and 46 deletions

View file

@ -16,6 +16,7 @@ from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.SettingFunction import SettingFunction from UM.Settings.SettingFunction import SettingFunction
from UM.Settings.ContainerStack import ContainerStack from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.Interfaces import DefinitionContainerInterface
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
from typing import Optional, List, TYPE_CHECKING, Union from typing import Optional, List, TYPE_CHECKING, Union
if TYPE_CHECKING: if TYPE_CHECKING:
@ -587,6 +588,46 @@ class ExtruderManager(QObject):
return result return result
## Get all extruder values for a certain setting. This function will skip the user settings container.
#
# This is exposed to SettingFunction so it can be used in value functions.
#
# \param key The key of the setting to retrieve values for.
#
# \return A list of values for all extruders. If an extruder does not have a value, it will not be in the list.
# If no extruder has the value, the list will contain the global value.
@staticmethod
def getDefaultExtruderValues(key):
global_stack = Application.getInstance().getGlobalContainerStack()
context = PropertyEvaluationContext(global_stack)
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
context.context["override_operators"] = {
"extruderValue": ExtruderManager.getDefaultExtruderValue,
"extruderValues": ExtruderManager.getDefaultExtruderValues,
"resolveOrValue": ExtruderManager.getDefaultResolveOrValue
}
result = []
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
# only include values from extruders that are "active" for the current machine instance
if int(extruder.getMetaDataEntry("position")) >= global_stack.getProperty("machine_extruder_count", "value", context = context):
continue
value = extruder.getRawProperty(key, "value", context = context)
if value is None:
continue
if isinstance(value, SettingFunction):
value = value(extruder, context = context)
result.append(value)
if not result:
result.append(global_stack.getProperty(key, "value", context = context))
return result
## Get all extruder values for a certain setting. ## Get all extruder values for a certain setting.
# #
# This is exposed to qml for display purposes # This is exposed to qml for display purposes
@ -620,6 +661,35 @@ class ExtruderManager(QObject):
return value return value
## Get the default value from the given extruder. This function will skip the user settings container.
#
# This is exposed to SettingFunction to use in value functions.
#
# \param extruder_index The index of the extruder to get the value from.
# \param key The key of the setting to get the value of.
#
# \return The value of the setting for the specified extruder or for the
# global stack if not found.
@staticmethod
def getDefaultExtruderValue(extruder_index, key):
extruder = ExtruderManager.getInstance().getExtruderStack(extruder_index)
context = PropertyEvaluationContext(extruder)
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
context.context["override_operators"] = {
"extruderValue": ExtruderManager.getDefaultExtruderValue,
"extruderValues": ExtruderManager.getDefaultExtruderValues,
"resolveOrValue": ExtruderManager.getDefaultResolveOrValue
}
if extruder:
value = extruder.getRawProperty(key, "value", context = context)
if isinstance(value, SettingFunction):
value = value(extruder, context = context)
else: # Just a value from global.
value = Application.getInstance().getGlobalContainerStack().getProperty(key, "value", context = context)
return value
## Get the resolve value or value for a given key ## Get the resolve value or value for a given key
# #
# This is the effective value for a given key, it is used for values in the global stack. # This is the effective value for a given key, it is used for values in the global stack.
@ -633,3 +703,25 @@ class ExtruderManager(QObject):
resolved_value = global_stack.getProperty(key, "value") resolved_value = global_stack.getProperty(key, "value")
return resolved_value return resolved_value
## Get the resolve value or value for a given key without looking the first container (user container)
#
# This is the effective value for a given key, it is used for values in the global stack.
# This is exposed to SettingFunction to use in value functions.
# \param key The key of the setting to get the value of.
#
# \return The effective value
@staticmethod
def getDefaultResolveOrValue(key):
global_stack = Application.getInstance().getGlobalContainerStack()
context = PropertyEvaluationContext(global_stack)
context.context["evaluate_from_container_index"] = 1 # skip the user settings container
context.context["override_operators"] = {
"extruderValue": ExtruderManager.getDefaultExtruderValue,
"extruderValues": ExtruderManager.getDefaultExtruderValues,
"resolveOrValue": ExtruderManager.getDefaultResolveOrValue
}
resolved_value = global_stack.getProperty(key, "value", context = context)
return resolved_value

View file

@ -4,6 +4,7 @@
from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
from typing import Iterable from typing import Iterable
from UM.i18n import i18nCatalog
import UM.Qt.ListModel import UM.Qt.ListModel
from UM.Application import Application from UM.Application import Application
import UM.FlameProfiler import UM.FlameProfiler
@ -11,6 +12,8 @@ from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ExtruderStack import ExtruderStack #To listen to changes on the extruders. from cura.Settings.ExtruderStack import ExtruderStack #To listen to changes on the extruders.
from cura.Settings.MachineManager import MachineManager #To listen to changes on the extruders of the currently active machine. from cura.Settings.MachineManager import MachineManager #To listen to changes on the extruders of the currently active machine.
catalog = i18nCatalog("cura")
## Model that holds extruders. ## Model that holds extruders.
# #
# This model is designed for use by any list of extruders, but specifically # This model is designed for use by any list of extruders, but specifically
@ -172,7 +175,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
color = material.getMetaDataEntry("color_code", default = self.defaultColors[0]) if material else self.defaultColors[0] color = material.getMetaDataEntry("color_code", default = self.defaultColors[0]) if material else self.defaultColors[0]
item = { item = {
"id": global_container_stack.getId(), "id": global_container_stack.getId(),
"name": "Global", "name": catalog.i18nc("@menuitem", "Global"),
"color": color, "color": color,
"index": -1, "index": -1,
"definition": "" "definition": ""
@ -215,7 +218,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
if self._add_optional_extruder: if self._add_optional_extruder:
item = { item = {
"id": "", "id": "",
"name": "Not overridden", "name": catalog.i18nc("@menuitem", "Not overridden"),
"color": "#ffffff", "color": "#ffffff",
"index": -1, "index": -1,
"definition": "" "definition": ""

View file

@ -96,18 +96,18 @@ class GlobalStack(CuraContainerStack):
if not self.definition.findDefinitions(key = key): if not self.definition.findDefinitions(key = key):
return None return None
if context is None:
context = PropertyEvaluationContext()
context.pushContainer(self)
# Handle the "resolve" property. # Handle the "resolve" property.
if self._shouldResolve(key, property_name): if self._shouldResolve(key, property_name, context):
self._resolving_settings.add(key) self._resolving_settings.add(key)
resolve = super().getProperty(key, "resolve", context) resolve = super().getProperty(key, "resolve", context)
self._resolving_settings.remove(key) self._resolving_settings.remove(key)
if resolve is not None: if resolve is not None:
return resolve return resolve
if context is None:
context = PropertyEvaluationContext()
context.pushContainer(self)
# Handle the "limit_to_extruder" property. # Handle the "limit_to_extruder" property.
limit_to_extruder = super().getProperty(key, "limit_to_extruder", context) limit_to_extruder = super().getProperty(key, "limit_to_extruder", context)
if limit_to_extruder is not None: if limit_to_extruder is not None:
@ -151,7 +151,7 @@ class GlobalStack(CuraContainerStack):
# Determine whether or not we should try to get the "resolve" property instead of the # Determine whether or not we should try to get the "resolve" property instead of the
# requested property. # requested property.
def _shouldResolve(self, key: str, property_name: str) -> bool: def _shouldResolve(self, key: str, property_name: str, context: Optional[PropertyEvaluationContext] = None) -> bool:
if property_name is not "value": if property_name is not "value":
# Do not try to resolve anything but the "value" property # Do not try to resolve anything but the "value" property
return False return False
@ -163,7 +163,7 @@ class GlobalStack(CuraContainerStack):
# track all settings that are being resolved. # track all settings that are being resolved.
return False return False
setting_state = super().getProperty(key, "state") setting_state = super().getProperty(key, "state", context = context)
if setting_state is not None and setting_state != InstanceState.Default: if setting_state is not None and setting_state != InstanceState.Default:
# When the user has explicitly set a value, we should ignore any resolve and # When the user has explicitly set a value, we should ignore any resolve and
# just return that value. # just return that value.

View file

@ -1135,7 +1135,7 @@ class MachineManager(QObject):
machine_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine") machine_stacks = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
other_machine_stacks = [s for s in machine_stacks if s.getId() != machine_id] other_machine_stacks = [s for s in machine_stacks if s.getId() != machine_id]
if other_machine_stacks: if other_machine_stacks:
Application.getInstance().setGlobalContainerStack(other_machine_stacks[0]) self.setActiveMachine(other_machine_stacks[0].getId())
ExtruderManager.getInstance().removeMachineExtruders(machine_id) ExtruderManager.getInstance().removeMachineExtruders(machine_id)
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", machine = machine_id) containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", machine = machine_id)

View file

@ -6,6 +6,7 @@ from cura.Settings.ExtruderManager import ExtruderManager
from UM.Settings.ContainerRegistry import ContainerRegistry from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Settings.SettingFunction import SettingFunction from UM.Settings.SettingFunction import SettingFunction
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
from collections import OrderedDict from collections import OrderedDict
import os import os
@ -66,8 +67,15 @@ class UserChangesModel(ListModel):
containers.extend(latest_stack.getContainers()) containers.extend(latest_stack.getContainers())
latest_stack = latest_stack.getNextStack() latest_stack = latest_stack.getNextStack()
# Drop the user container. # Override "getExtruderValue" with "getDefaultExtruderValue" so we can get the default values
user_changes = containers.pop(0) user_changes = containers.pop(0)
default_value_resolve_context = PropertyEvaluationContext(stack)
default_value_resolve_context.context["evaluate_from_container_index"] = 1 # skip the user settings container
default_value_resolve_context.context["override_operators"] = {
"extruderValue": ExtruderManager.getDefaultExtruderValue,
"extruderValues": ExtruderManager.getDefaultExtruderValues,
"resolveOrValue": ExtruderManager.getDefaultResolveOrValue
}
for setting_key in user_changes.getAllKeys(): for setting_key in user_changes.getAllKeys():
original_value = None original_value = None
@ -90,16 +98,16 @@ class UserChangesModel(ListModel):
for container in containers: for container in containers:
if stack == global_stack: if stack == global_stack:
resolve = global_stack.getProperty(setting_key, "resolve") resolve = global_stack.getProperty(setting_key, "resolve", default_value_resolve_context)
if resolve is not None: if resolve is not None:
original_value = resolve original_value = resolve
break break
original_value = container.getProperty(setting_key, "value") original_value = container.getProperty(setting_key, "value", default_value_resolve_context)
# If a value is a function, ensure it's called with the stack it's in. # If a value is a function, ensure it's called with the stack it's in.
if isinstance(original_value, SettingFunction): if isinstance(original_value, SettingFunction):
original_value = original_value(stack) original_value = original_value(stack, default_value_resolve_context)
if original_value is not None: if original_value is not None:
break break

View file

@ -1,5 +1,82 @@
[3.0.0] [3.0.0]
*Will be updated soon! *Faster start-up
Start-up speed has been cut in half compared to the previous version.
*New color scheme
Color scheme has been updated to reflect Ultimaker Cura rebrand.
*Updated UX design
The Ultimaker Cura logo has moved from the bottom to the top of the interface. Print status icons have been updated and repositioned.
*Redesigned splash screen
A new splash screen on Ultimaker Cura startup has been added.
*Top navigation bar improvements
The width of tab functionality changes accordingly to the word space (multilingual).
*Print quality slider
A slider can now be used to control the quality profile in recommended mode.
*Infill slider
Model infill can now be changed using a slider in recommended mode.
*Changed layer view
Layer view icon, panel and slider have moved to top-right of interface.
*Rasterized build plate
The build plate now shows graduations of 10 mm and 1 mm for easy model positioning.
*Changed row of extruder buttons
Extruder tabs have become buttons and icons have been updated.
*Add an "Export to Cura" button in SOLIDWORKS
SOLIDWORKS plugin can now be installed using an automatic installer.
*Siemens NX macro
When a user updates models in Siemens NX and clicks the button, the updated models replace the models opened in Ultimaker Cura.
*Skin removal width
Remove thin strips of skin from a model to prevent print head zigzagging, in turn preventing vibrations.
*Skin expand distance
Cutting away skins on steep overhangs makes prints less sturdy. By expanding skins with the thickness of walls, features will be better supported. In addition, features such as towers on top of infill will be stronger.
*Extra skin wall count
Printing extra skin directly on top of infill can lead to gaps, curling and pillowing. This is reduced by printing a wall around the skin first, and also improves the printing speed.
*Minimum extrusion for skin
Will prevent filling small gaps that are probably filled already, resulting in less strings, better top details and faster prints.
*PVA retractions
PVA (switch) retraction length is increased, minimum travel distance for retraction is decreased and max count is slightly increased, this reduces stringing by a lot at the cost of slightly increased print time.
*Z seam options
Gives the user control over where to place the seam - hide it in convex corners or in easy to remove locations such as concave corners. Dont let corner angles influence the seam position.
*Quarter cubic infill
Similar to tetrahedral (octet) infill, but half of the lines are shifted half of the period up. This pattern sacrifices some rigidity of octet infill for greater toughness.
*Cross infill
A fractal pattern infill that requires fewer retractions than other infill types. This is useful for flexible materials as it causes less material elongation. The internal structure given by this infill also assists flexible models having more resistance, while retaining soft properties in all directions.
*Layer start negative position
Layer start X/Y values can be less than 0 when the machine centre is zero.
*PostProcessing stretch script
This new script performs "post stretch" algorithm to fix the problem of insufficient inner and outer diameters. Thanks to electrocbd for contributing.
*Ironing speed settings
Ironing speed settings have been moved to experimental category.
*Doodle3D plugin
Update Doodle3D plugin to connect with printers. Thanks to mith for contributing.
*Bug fixes
- Customized profiles are not sent when connecting to a printer
- Sync z-hop with layer changes, thanks to smartavionics for contributing
- Memory leaks on MacOS
- Printer name not loaded when project file is opened
- Doodle3D Wifi box was selected by default on non-UM3 printers
[2.7.0] [2.7.0]
*Top surface skin *Top surface skin

View file

@ -278,6 +278,10 @@ Cura.MachineAction
width: parent.width width: parent.width
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text:{ text:{
if (base.selectedPrinter == undefined)
{
return "";
}
// The property cluster size does not exist for older UM3 devices. // The property cluster size does not exist for older UM3 devices.
if(base.selectedPrinter != undefined && base.selectedPrinter.clusterSize == null || base.selectedPrinter.clusterSize == 1) if(base.selectedPrinter != undefined && base.selectedPrinter.clusterSize == null || base.selectedPrinter.clusterSize == 1)
{ {

View file

@ -154,7 +154,18 @@ class NetworkPrinterOutputDevicePlugin(QObject, OutputDevicePlugin):
if status_code == 200: if status_code == 200:
# We know it's a cluster printer # We know it's a cluster printer
Logger.log("d", "Cluster printer detected: [%s]", reply.url()) Logger.log("d", "Cluster printer detected: [%s]", reply.url())
try:
cluster_printers_list = json.loads(bytes(reply.readAll()).decode("utf-8"))
except json.JSONDecodeError:
Logger.log("e", "Printer returned invalid JSON.")
return
except UnicodeDecodeError:
Logger.log("e", "Printer returned incorrect UTF-8.")
return
self._network_requests_buffer[address]["cluster"] = True self._network_requests_buffer[address]["cluster"] = True
self._network_requests_buffer[address]["cluster_size"] = len(cluster_printers_list)
else: else:
Logger.log("d", "This url is not from a cluster printer: [%s]", reply.url()) Logger.log("d", "This url is not from a cluster printer: [%s]", reply.url())
self._network_requests_buffer[address]["cluster"] = False self._network_requests_buffer[address]["cluster"] = False
@ -166,7 +177,6 @@ class NetworkPrinterOutputDevicePlugin(QObject, OutputDevicePlugin):
instance_name = "manual:%s" % address instance_name = "manual:%s" % address
system_info = self._network_requests_buffer[address]["system"] system_info = self._network_requests_buffer[address]["system"]
is_cluster = self._network_requests_buffer[address]["cluster"]
machine = "unknown" machine = "unknown"
if "variant" in system_info: if "variant" in system_info:
variant = system_info["variant"] variant = system_info["variant"]
@ -182,10 +192,14 @@ class NetworkPrinterOutputDevicePlugin(QObject, OutputDevicePlugin):
b"manual": b"true", b"manual": b"true",
b"machine": machine.encode("utf-8") b"machine": machine.encode("utf-8")
} }
if self._network_requests_buffer[address]["cluster"]:
properties[b"cluster_size"] = self._network_requests_buffer[address]["cluster_size"]
if instance_name in self._printers: if instance_name in self._printers:
# Only replace the printer if it is still in the list of (manual) printers # Only replace the printer if it is still in the list of (manual) printers
self.removePrinter(instance_name) self.removePrinter(instance_name)
self.addPrinter(instance_name, address, properties, force_cluster=is_cluster) self.addPrinter(instance_name, address, properties)
del self._network_requests_buffer[address] del self._network_requests_buffer[address]
@ -216,12 +230,9 @@ class NetworkPrinterOutputDevicePlugin(QObject, OutputDevicePlugin):
self._printers[key].connectionStateChanged.disconnect(self._onPrinterConnectionStateChanged) self._printers[key].connectionStateChanged.disconnect(self._onPrinterConnectionStateChanged)
## Because the model needs to be created in the same thread as the QMLEngine, we use a signal. ## Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
def addPrinter(self, name, address, properties, force_cluster=False): def addPrinter(self, name, address, properties):
cluster_size = int(properties.get(b"cluster_size", -1)) cluster_size = int(properties.get(b"cluster_size", -1))
was_cluster_before = name in self._cluster_printers_seen if cluster_size >= 0:
if was_cluster_before:
Logger.log("d", "Printer [%s] had Cura Connect before, so assume it's still equipped with Cura Connect.", name)
if force_cluster or cluster_size >= 0 or was_cluster_before:
printer = NetworkClusterPrinterOutputDevice.NetworkClusterPrinterOutputDevice( printer = NetworkClusterPrinterOutputDevice.NetworkClusterPrinterOutputDevice(
name, address, properties, self._api_prefix) name, address, properties, self._api_prefix)
else: else:

View file

@ -73,7 +73,7 @@ Rectangle
hoverEnabled: true; hoverEnabled: true;
// Only clickable if no printer is selected // Only clickable if no printer is selected
enabled: OutputDevice.selectedPrinterName == "" enabled: OutputDevice.selectedPrinterName == "" && printer.status !== "unreachable"
} }
Row Row
@ -257,6 +257,11 @@ Rectangle
return catalog.i18nc("@label:status", "Disabled"); return catalog.i18nc("@label:status", "Disabled");
} }
if (printer.status === "unreachable")
{
return printerStatusText(printer);
}
if (printJob != null) if (printJob != null)
{ {
switch (printJob.status) switch (printJob.status)
@ -327,6 +332,12 @@ Rectangle
{ {
return "blocked-icon.svg"; return "blocked-icon.svg";
} }
if (printer.status === "unreachable")
{
return "";
}
if (printJob != null) if (printJob != null)
{ {
if(printJob.status === "queued") if(printJob.status === "queued")
@ -378,6 +389,11 @@ Rectangle
return catalog.i18nc("@label", "Not accepting print jobs"); return catalog.i18nc("@label", "Not accepting print jobs");
} }
if (printer.status === "unreachable")
{
return "";
}
if(printJob != null) if(printJob != null)
{ {
switch (printJob.status) switch (printJob.status)

View file

@ -1,3 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" width="25" height="24" viewBox="0 0 25 24">
<path fill="#000" fill-rule="evenodd" d="M6 10h12v4H6v-4zm6 14c6.627 0 12-5.373 12-12S18.627 0 12 0 0 5.373 0 12s5.373 12 12 12z"/> <g fill="none" fill-rule="evenodd" stroke="#000" stroke-width="2.4" transform="translate(.567)">
<circle cx="12" cy="12" r="10.8"/>
<path stroke-linecap="square" d="M5.5 18.5L18.935 5.065"/>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 227 B

After

Width:  |  Height:  |  Size: 311 B

Before After
Before After

View file

@ -220,10 +220,15 @@ class XmlMaterialProfile(InstanceContainer):
machine_container_map[definition_id] = container machine_container_map[definition_id] = container
# Map machine human-readable names to IDs
product_id_map = {}
for container in registry.findDefinitionContainers(type = "machine"):
product_id_map[container.getName()] = container.getId()
for definition_id, container in machine_container_map.items(): for definition_id, container in machine_container_map.items():
definition = container.getDefinition() definition = container.getDefinition()
try: try:
product = UM.Dictionary.findKey(self.__product_id_map, definition_id) product = UM.Dictionary.findKey(product_id_map, definition_id)
except ValueError: except ValueError:
# An unknown product id; export it anyway # An unknown product id; export it anyway
product = definition_id product = definition_id
@ -512,6 +517,11 @@ class XmlMaterialProfile(InstanceContainer):
self.setMetaData(meta_data) self.setMetaData(meta_data)
self._dirty = False self._dirty = False
# Map machine human-readable names to IDs
product_id_map = {}
for container in ContainerRegistry.getInstance().findDefinitionContainers(type = "machine"):
product_id_map[container.getName()] = container.getId()
machines = data.iterfind("./um:settings/um:machine", self.__namespaces) machines = data.iterfind("./um:settings/um:machine", self.__namespaces)
for machine in machines: for machine in machines:
machine_compatibility = common_compatibility machine_compatibility = common_compatibility
@ -532,7 +542,7 @@ class XmlMaterialProfile(InstanceContainer):
identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces) identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces)
for identifier in identifiers: for identifier in identifiers:
machine_id = self.__product_id_map.get(identifier.get("product"), None) machine_id = product_id_map.get(identifier.get("product"), None)
if machine_id is None: if machine_id is None:
# Lets try again with some naive heuristics. # Lets try again with some naive heuristics.
machine_id = identifier.get("product").replace(" ", "").lower() machine_id = identifier.get("product").replace(" ", "").lower()
@ -678,21 +688,6 @@ class XmlMaterialProfile(InstanceContainer):
"GUID": "material_guid" "GUID": "material_guid"
} }
# Map XML file product names to internal ids
# TODO: Move this to definition's metadata
__product_id_map = {
"Ultimaker 3": "ultimaker3",
"Ultimaker 3 Extended": "ultimaker3_extended",
"Ultimaker 2": "ultimaker2",
"Ultimaker 2+": "ultimaker2_plus",
"Ultimaker 2 Go": "ultimaker2_go",
"Ultimaker 2 Extended": "ultimaker2_extended",
"Ultimaker 2 Extended+": "ultimaker2_extended_plus",
"Ultimaker Original": "ultimaker_original",
"Ultimaker Original+": "ultimaker_original_plus",
"IMADE3D JellyBOX": "imade3d_jellybox"
}
# Map of recognised namespaces with a proper prefix. # Map of recognised namespaces with a proper prefix.
__namespaces = { __namespaces = {
"um": "http://www.ultimaker.com/material" "um": "http://www.ultimaker.com/material"

View file

@ -36,6 +36,31 @@ msgctxt "@label:status"
msgid "Can't start print" msgid "Can't start print"
msgstr "Druck startet nicht" msgstr "Druck startet nicht"
#: Manually added for plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
msgctxt "@label"
msgid "This printer is not set up to host a group of Ultimaker 3 printers."
msgstr "Dieser Drucker ist nicht eingerichtet um eine Gruppe von Ultimaker 3 Druckern anzusteuern."
#: Manually added for plugins/UM3NetworkPrinting/PrinterInfoBlock.qml
msgctxt "@label"
msgid "Finishes at: "
msgstr "Endet um: "
#: Manually added for plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
msgctxt "@label"
msgid "This printer is the host for a group of %1 Ultimaker 3 printers."
msgstr "Dieser Drucker steuert eine Gruppe von %1 Ultimaker 3 Druckern an."
#: Manually added for plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py
msgctxt "@info:status"
msgid "Printer '{printer_name}' has finished printing '{job_name}'."
msgstr "Drucker '{printer_name}' hat '{job_name}' vollständig gedrückt."
#: Manually added for plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py
msgctxt "@info:status"
msgid "Print finished"
msgstr "Druck vollendet"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:29 #: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:29
msgctxt "@action" msgctxt "@action"
msgid "Machine Settings" msgid "Machine Settings"

View file

@ -16,7 +16,7 @@ UM.MainWindow
{ {
id: base id: base
//: Cura application window title //: Cura application window title
title: catalog.i18nc("@title:window","Cura"); title: catalog.i18nc("@title:window","Ultimaker Cura");
viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0) viewportRect: Qt.rect(0, 0, (base.width - sidebar.width) / base.width, 1.0)
property bool showPrintMonitor: false property bool showPrintMonitor: false

View file

@ -18,6 +18,7 @@ Item {
UM.I18nCatalog { id: catalog; name:"cura"} UM.I18nCatalog { id: catalog; name:"cura"}
height: childrenRect.height height: childrenRect.height
width: childrenRect.width
Connections Connections
{ {

View file

@ -442,6 +442,7 @@ Column
anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
renderType: Text.NativeRendering
Component.onCompleted: Component.onCompleted:
{ {

View file

@ -102,6 +102,7 @@ SettingItem
right: parent.right right: parent.right
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
} }
renderType: Text.NativeRendering
Keys.onTabPressed: Keys.onTabPressed:
{ {

View file

@ -152,7 +152,7 @@ Rectangle
Button { Button {
height: settingsModeSelection.height height: settingsModeSelection.height
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: model.index * (settingsModeSelection.width / 2) anchors.leftMargin: model.index * Math.floor(settingsModeSelection.width / 2)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: Math.floor(0.5 * parent.width) width: Math.floor(0.5 * parent.width)
text: model.text text: model.text

View file

@ -687,11 +687,14 @@ Item
anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height * 1.5) anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height * 1.5)
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.right: infillCellLeft.right
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
anchors.verticalCenter: enableSupportCheckBox.verticalCenter anchors.verticalCenter: enableSupportCheckBox.verticalCenter
text: catalog.i18nc("@label", "Generate Support"); text: catalog.i18nc("@label", "Generate Support");
font: UM.Theme.getFont("default"); font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text"); color: UM.Theme.getColor("text");
elide: Text.ElideRight
} }
CheckBox CheckBox
@ -737,10 +740,13 @@ Item
visible: supportExtruderCombobox.visible visible: supportExtruderCombobox.visible
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.right: infillCellLeft.right
anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
anchors.verticalCenter: supportExtruderCombobox.verticalCenter anchors.verticalCenter: supportExtruderCombobox.verticalCenter
text: catalog.i18nc("@label", "Support Extruder"); text: catalog.i18nc("@label", "Support Extruder");
font: UM.Theme.getFont("default"); font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text"); color: UM.Theme.getColor("text");
elide: Text.ElideRight
} }
ComboBox ComboBox

View file

@ -30,7 +30,8 @@ Item
id: repeat id: repeat
model: UM.ToolModel { } model: UM.ToolModel { }
width: childrenRect.width
height: childrenRect.height
Button Button
{ {
text: model.name text: model.name
@ -72,6 +73,8 @@ Item
Repeater Repeater
{ {
id: extruders id: extruders
width: childrenRect.width
height: childrenRect.height
property var _model: Cura.ExtrudersModel { id: extrudersModel } property var _model: Cura.ExtrudersModel { id: extrudersModel }
model: _model.items.length > 1 ? _model : 0 model: _model.items.length > 1 ? _model : 0
ExtruderButton { extruder: model } ExtruderButton { extruder: model }

View file

@ -279,7 +279,8 @@ Rectangle
property var buttonTarget: Qt.point(viewModeButton.x + viewModeButton.width / 2, viewModeButton.y + viewModeButton.height / 2) property var buttonTarget: Qt.point(viewModeButton.x + viewModeButton.width / 2, viewModeButton.y + viewModeButton.height / 2)
height: childrenRect.height; height: childrenRect.height
width: childrenRect.width
source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : ""; source: UM.ActiveView.valid ? UM.ActiveView.activeViewPanel : "";
} }