Merge branch '2.3' of github.com:Ultimaker/Cura into 2.3

This commit is contained in:
Tim Kuipers 2016-09-05 14:39:11 +02:00
commit 99a44fa1d2
22 changed files with 164 additions and 91 deletions

View File

@ -280,7 +280,7 @@ class BuildVolume(SceneNode):
self._height = self._global_container_stack.getProperty("machine_height", "value")
rebuild_me = True
if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings:
if setting_key in self._skirt_settings or setting_key in self._prime_settings or setting_key in self._tower_settings or setting_key == "print_sequence":
self._updateDisallowedAreas()
rebuild_me = True
@ -383,6 +383,10 @@ class BuildVolume(SceneNode):
def _getBedAdhesionSize(self, container_stack):
skirt_size = 0.0
# If we are printing one at a time, we need to add the bed adhesion size to the disallowed areas of the objects
if container_stack.getProperty("print_sequence", "value") == "one_at_a_time":
return 0.1 # Return a very small value, so we do draw disallowed area's near the edges.
adhesion_type = container_stack.getProperty("adhesion_type", "value")
if adhesion_type == "skirt":
skirt_distance = container_stack.getProperty("skirt_gap", "value")

View File

@ -56,6 +56,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
if self._global_stack and self._node:
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self._node.getParent().callDecoration("isGroup"):
hull = hull.getMinkowskiHull(Polygon(numpy.array(self._global_stack.getProperty("machine_head_polygon", "value"), numpy.float32)))
hull = self._add2DAdhesionMargin(hull)
return hull
## Get the convex hull of the node with the full head size
@ -229,17 +230,16 @@ class ConvexHullDecorator(SceneNodeDecorator):
machine_head_coords = numpy.array(
self._global_stack.getProperty("machine_head_with_fans_polygon", "value"),
numpy.float32)
head_y_size = abs(machine_head_coords).min() # safe margin to take off in all directions
if adhesion_type == "raft":
extra_margin = max(0, self._global_stack.getProperty("raft_margin", "value") - head_y_size)
extra_margin = max(0, self._global_stack.getProperty("raft_margin", "value"))
elif adhesion_type == "brim":
extra_margin = max(0, self._global_stack.getProperty("brim_width", "value") - head_y_size)
extra_margin = max(0, self._global_stack.getProperty("brim_line_count", "value") * self._global_stack.getProperty("skirt_brim_line_width", "value"))
elif adhesion_type == "skirt":
extra_margin = max(
0, self._global_stack.getProperty("skirt_gap", "value") +
self._global_stack.getProperty("skirt_line_count", "value") * self._global_stack.getProperty("skirt_brim_line_width", "value") -
head_y_size)
self._global_stack.getProperty("skirt_line_count", "value") * self._global_stack.getProperty("skirt_brim_line_width", "value"))
# adjust head_and_fans with extra margin
if extra_margin > 0:
# In Cura 2.2+, there is a function to create this circle-like polygon.
@ -288,4 +288,4 @@ class ConvexHullDecorator(SceneNodeDecorator):
_affected_settings = [
"adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers",
"raft_surface_thickness", "raft_airgap", "raft_margin", "print_sequence",
"skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance"]
"skirt_gap", "skirt_line_count", "skirt_brim_line_width", "skirt_distance", "brim_line_count"]

View File

@ -23,6 +23,7 @@ from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
from UM.Operations.GroupedOperation import GroupedOperation
from UM.Operations.SetTransformOperation import SetTransformOperation
from UM.Operations.TranslateOperation import TranslateOperation
from cura.SetParentOperation import SetParentOperation
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
@ -36,7 +37,6 @@ from . import BuildVolume
from . import CameraAnimation
from . import PrintInformation
from . import CuraActions
from . import MultiMaterialDecorator
from . import ZOffsetDecorator
from . import CuraSplashScreen
from . import CameraImageProvider
@ -180,6 +180,8 @@ class CuraApplication(QtApplication):
ContainerRegistry.getInstance().addContainer(empty_material_container)
empty_quality_container = copy.deepcopy(empty_container)
empty_quality_container._id = "empty_quality"
empty_quality_container.setName("Not supported")
empty_quality_container.addMetaDataEntry("quality_type", "normal")
empty_quality_container.addMetaDataEntry("type", "quality")
ContainerRegistry.getInstance().addContainer(empty_quality_container)
empty_quality_changes_container = copy.deepcopy(empty_container)
@ -700,8 +702,7 @@ class CuraApplication(QtApplication):
op = GroupedOperation()
for node in nodes:
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
op.addOperation(SetTransformOperation(node, Vector(0,0,0)))
op.addOperation(SetTransformOperation(node, Vector(0, node.getWorldPosition().y - node.getBoundingBox().bottom, 0)))
op.push()
## Reset all transformations on nodes with mesh data.
@ -724,7 +725,8 @@ class CuraApplication(QtApplication):
for node in nodes:
# Ensure that the object is above the build platform
node.removeDecorator(ZOffsetDecorator.ZOffsetDecorator)
op.addOperation(SetTransformOperation(node, Vector(0,0,0), Quaternion(), Vector(1, 1, 1)))
op.addOperation(SetTransformOperation(node, Vector(0, node.getMeshData().getCenterPosition().y, 0), Quaternion(), Vector(1, 1, 1)))
op.push()
@ -792,8 +794,6 @@ class CuraApplication(QtApplication):
except Exception as e:
Logger.log("d", "mergeSelected: Exception:", e)
return
multi_material_decorator = MultiMaterialDecorator.MultiMaterialDecorator()
group_node.addDecorator(multi_material_decorator)
# Compute the center of the objects when their origins are aligned.
object_centers = [node.getMeshData().getCenterPosition().scale(node.getScale()) for node in group_node.getChildren()]

View File

@ -1,11 +0,0 @@
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
class MultiMaterialDecorator(SceneNodeDecorator):
def __init__(self):
super().__init__()
def isMultiMaterial(self):
return True
def __deepcopy__(self, memo):
return MultiMaterialDecorator()

View File

@ -102,11 +102,11 @@ class PlatformPhysics:
# Get the overlap distance for both convex hulls. If this returns None, there is no intersection.
head_hull = node.callDecoration("getConvexHullHead")
if head_hull:
overlap = head_hull.intersectsPolygon(other_node.callDecoration("getConvexHullHead"))
overlap = head_hull.intersectsPolygon(other_node.callDecoration("getConvexHull"))
if not overlap:
other_head_hull = other_node.callDecoration("getConvexHullHead")
if other_head_hull:
overlap = node.callDecoration("getConvexHullHead").intersectsPolygon(other_head_hull)
overlap = node.callDecoration("getConvexHull").intersectsPolygon(other_head_hull)
else:
own_convex_hull = node.callDecoration("getConvexHull")
other_convex_hull = other_node.callDecoration("getConvexHull")

View File

@ -423,8 +423,8 @@ class ContainerManager(QObject):
# stack and clear the user settings.
#
# \return \type{bool} True if the operation was successfully, False if not.
@pyqtSlot(result = bool)
def createQualityChanges(self):
@pyqtSlot(str, result = bool)
def createQualityChanges(self, base_name):
global_stack = UM.Application.getInstance().getGlobalContainerStack()
if not global_stack:
return False
@ -435,8 +435,9 @@ class ContainerManager(QObject):
return False
self._machine_manager.blurSettings.emit()
unique_name = self._container_registry.uniqueName(active_quality_name)
if base_name is None or base_name == "":
base_name = active_quality_name
unique_name = self._container_registry.uniqueName(base_name)
# Go through the active stacks and create quality_changes containers from the user containers.
for stack in cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
@ -540,8 +541,8 @@ class ContainerManager(QObject):
# \param quality_name The name of the quality to duplicate.
#
# \return A string containing the name of the duplicated containers, or an empty string if it failed.
@pyqtSlot(str, result = str)
def duplicateQualityOrQualityChanges(self, quality_name):
@pyqtSlot(str, str, result = str)
def duplicateQualityOrQualityChanges(self, quality_name, base_name):
global_stack = UM.Application.getInstance().getGlobalContainerStack()
if not global_stack or not quality_name:
return ""
@ -551,7 +552,10 @@ class ContainerManager(QObject):
UM.Logger.log("d", "Unable to duplicate the quality %s, because it doesn't exist.", quality_name)
return ""
new_name = self._container_registry.uniqueName(quality_name)
if base_name is None:
base_name = quality_name
new_name = self._container_registry.uniqueName(base_name)
container_type = containers[0].getMetaDataEntry("type")
if container_type == "quality":

View File

@ -7,7 +7,7 @@ from PyQt5.QtWidgets import QMessageBox
from UM.Application import Application
from UM.Preferences import Preferences
from UM.Logger import Logger
from UM.Message import Message
from UM.Settings.SettingRelation import RelationType
import UM.Settings
@ -547,6 +547,7 @@ class MachineManager(QObject):
preferred_material = None
if old_material:
preferred_material_name = old_material.getName()
self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0], preferred_material_name).id)
else:
Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
@ -614,9 +615,16 @@ class MachineManager(QObject):
stack_quality_changes = self._empty_quality_changes_container
old_quality = stack.findContainer(type = "quality")
old_quality.nameChanged.disconnect(self._onQualityNameChanged)
if old_quality:
old_quality.nameChanged.disconnect(self._onQualityNameChanged)
else:
Logger.log("w", "Could not find old quality while changing active quality.")
old_changes = stack.findContainer(type = "quality_changes")
old_changes.nameChanged.disconnect(self._onQualityNameChanged)
if old_changes:
old_changes.nameChanged.disconnect(self._onQualityNameChanged)
else:
Logger.log("w", "Could not find old quality_changes while changing active quality.")
stack.replaceContainer(stack.getContainerIndex(old_quality), stack_quality)
stack.replaceContainer(stack.getContainerIndex(old_changes), stack_quality_changes)
@ -799,15 +807,15 @@ class MachineManager(QObject):
if containers:
return containers[0]
if "name" in search_criteria or "id" in search_criteria:
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
if "variant" in search_criteria or "id" in search_criteria:
# If a material by this name can not be found, try a wider set of search criteria
search_criteria.pop("name", None)
search_criteria.pop("variant", None)
search_criteria.pop("id", None)
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
if containers:
return containers[0]
Logger.log("w", "Unable to find a material container with provided criteria, returning an empty one instead.")
return self._empty_material_container
def _updateQualityContainer(self, definition, variant_container, material_container = None, preferred_quality_name = None):
@ -848,10 +856,9 @@ class MachineManager(QObject):
containers = container_registry.findInstanceContainers(**search_criteria)
if containers:
return containers[0]
# We still weren't able to find a quality for this specific material.
# Try to find qualities for a generic version of the material.
material_search_criteria = { "type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic" }
material_search_criteria = { "type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"}
if definition.getMetaDataEntry("has_machine_quality"):
if material_container:
material_search_criteria["definition"] = material_container.getDefinition().id
@ -865,7 +872,6 @@ class MachineManager(QObject):
material_search_criteria["variant"] = variant_container.id
else:
material_search_criteria["definition"] = "fdmprinter"
material_containers = container_registry.findInstanceContainers(**material_search_criteria)
if material_containers:
search_criteria["material"] = material_containers[0].getId()
@ -883,6 +889,9 @@ class MachineManager(QObject):
if containers:
return containers[0]
# Notify user that we were unable to find a matching quality
message = Message(catalog.i18nc("@info:status", "Unable to find a quality profile for this combination, using an empty one instead."))
message.show()
return self._empty_quality_container
## Finds a quality-changes container to use if any other container

View File

@ -1,7 +1,7 @@
[2.3.0]
*Speed improvements
The first thing you will notice is the speed. STL loading is now 10 to 20 times faster, layer time is significantly faster and slicing speed is slightly improved.
The first thing you will notice is the speed. STL loading is now 10 to 20 times faster, layerview is significantly faster and slicing speed is slightly improved.
*Multi Extrusion Support
Machines with multiple extruders are now supported. If youve got the Ultimaker Original with the dual extrusion upgrade kit, weve got you covered.
@ -59,9 +59,6 @@ Set the travel speed of the initial layer(s) to reduce risk of extruder pulling
*Support Bottoms
This new feature duplicates the Support Roofs feature in the places where the support rests on the model.
*Auto Temperature
Automatically change the temperature of a layer based on the average flow of material in the layer.
*Bug fixes & minor changes
Deleting grouped objects works as intended again.
Duplicating groups works as intended again.

View File

@ -206,7 +206,14 @@ class StartSliceJob(Job):
# Use resolvement value if available, or take the value
resolved_value = stack.getProperty(key, "resolve")
if resolved_value is not None:
settings[key] = resolved_value
# There is a resolvement value. Check if we need to use it.
user_container = stack.findContainer({"type": "user"})
quality_changes_container = stack.findContainer({"type": "quality_changes"})
if user_container.hasProperty(key,"value") or quality_changes_container.hasProperty(key,"value"):
# Normal case
settings[key] = stack.getProperty(key, "value")
else:
settings[key] = resolved_value
else:
# Normal case
settings[key] = stack.getProperty(key, "value")

View File

@ -26,7 +26,11 @@ class CuraProfileReader(ProfileReader):
# not be read or didn't contain a valid profile, \code None \endcode is
# returned.
def read(self, file_name):
archive = zipfile.ZipFile(file_name, "r")
try:
archive = zipfile.ZipFile(file_name, "r")
except Exception:
# zipfile doesn't give proper exceptions, so we can only catch broad ones
return []
results = []
for profile_id in archive.namelist():
# Create an empty profile.

View File

@ -89,17 +89,17 @@ class GCodeWriter(MeshWriter):
prefix = ";SETTING_" + str(GCodeWriter.version) + " " # The prefix to put before each line.
prefix_length = len(prefix)
container_with_profile = stack.findContainer({"type": "quality"})
container_with_profile = stack.findContainer({"type": "quality_changes"})
if not container_with_profile:
Logger.log("e", "No valid quality profile found, not writing settings to GCode!")
return ""
flat_global_container = self._createFlattenedContainerInstance(stack.getTop(),container_with_profile)
flat_global_container = self._createFlattenedContainerInstance(stack.getTop(), container_with_profile)
serialized = flat_global_container.serialize()
data = {"global_quality": serialized}
for extruder in ExtruderManager.getInstance().getMachineExtruders(stack.getId()):
extruder_quality = extruder.findContainer({"type": "quality"})
extruder_quality = extruder.findContainer({"type": "quality_changes"})
if not extruder_quality:
Logger.log("w", "No extruder quality profile found, not writing quality for extruder %s to file!", extruder.getId())
continue

View File

@ -86,7 +86,7 @@ class LayerView(View):
if not self._ghost_shader:
self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
self._ghost_shader.setUniformValue("u_color", Color(0, 0, 0, 72))
self._ghost_shader.setUniformValue("u_color", Color(0, 0, 0, 64))
for node in DepthFirstIterator(scene.getRoot()):
# We do not want to render ConvexHullNode as it conflicts with the bottom layers.
@ -98,10 +98,10 @@ class LayerView(View):
if node.getMeshData() and node.isVisible():
renderer.queueNode(node,
shader = self._ghost_shader,
state_setup_callback = lambda gl: gl.glDepthMask(gl.GL_FALSE),
state_teardown_callback = lambda gl: gl.glDepthMask(gl.GL_TRUE)
)
type = RenderBatch.RenderType.Transparent )
for node in DepthFirstIterator(scene.getRoot()):
if type(node) is SceneNode:
if node.getMeshData() and node.isVisible():
layer_data = node.callDecoration("getLayerData")
if not layer_data:

View File

@ -47,7 +47,9 @@ class SolidView(View):
if global_container_stack:
if Preferences.getInstance().getValue("view/show_overhang"):
angle = global_container_stack.getProperty("support_angle", "value")
if angle is not None and global_container_stack.getProperty("support_angle", "validationState") == ValidatorState.Valid:
# Make sure the overhang angle is valid before passing it to the shader
# Note: if the overhang angle is set to its default value, it does not need to get validated (validationState = None)
if angle is not None and global_container_stack.getProperty("support_angle", "validationState") in [None, ValidatorState.Valid]:
self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(90 - angle)))
else:
self._enabled_shader.setUniformValue("u_overhangAngle", math.cos(math.radians(0))) #Overhang angle of 0 causes no area at all to be marked as overhang.

View File

@ -87,7 +87,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
super().setName(new_name)
basefile = self.getMetaDataEntry("base_file", self._id) # if basefile is none, this is a basefile.
basefile = self.getMetaDataEntry("base_file", self._id) # if basefile is self.id, this is a basefile.
# Update the basefile as well, this is actually what we're trying to do
# Update all containers that share GUID and basefile
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(base_file = basefile)
@ -275,7 +275,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
# The XML material profile can have specific settings for machines.
# Some machines share profiles, so they are only created once.
# This function duplicates those elements so that each machine tag only has one identifier.
def _flattenMachinesXML(self, element):
def _expandMachinesXML(self, element):
settings_element = element.find("./um:settings", self.__namespaces)
machines = settings_element.iterfind("./um:machine", self.__namespaces)
machines_to_add = []
@ -309,7 +309,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
def _mergeXML(self, first, second):
result = copy.deepcopy(first)
self._combineElement(self._flattenMachinesXML(result), self._flattenMachinesXML(second))
self._combineElement(self._expandMachinesXML(result), self._expandMachinesXML(second))
return result
def _createKey(self, element):
@ -339,7 +339,7 @@ class XmlMaterialProfile(UM.Settings.InstanceContainer):
key = self._createKey(element)
if len(element): # Check if element has children.
try:
if "setting " in key:
if "setting" in element.tag and not "settings" in element.tag:
# Setting can have points in it. In that case, delete all values and override them.
for child in list(mapping[key]):
mapping[key].remove(child)

View File

@ -3310,6 +3310,8 @@
"default_value": 200,
"minimum_value_warning": "-1000",
"maximum_value_warning": "1000",
"maximum_value": "machine_width - 0.5 * prime_tower_size",
"minimum_value": "0.5 * prime_tower_size",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@ -3323,6 +3325,8 @@
"default_value": 200,
"minimum_value_warning": "-1000",
"maximum_value_warning": "1000",
"maximum_value": "machine_depth - 0.5 * prime_tower_size",
"minimum_value": "0.5 * prime_tower_size",
"settable_per_mesh": false,
"settable_per_extruder": false
},

View File

@ -28,7 +28,9 @@ Generic CPE+ profile. Serves as an example file, data in this file is not correc
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2 Extended+"/>
<setting key="hardware compatible">yes</setting>
<hotend id="0.25 mm" />
<hotend id="0.25 mm">
<setting key="hardware compatible">no</setting>
</hotend>
<hotend id="0.4 mm" />
<hotend id="0.6 mm" />
<hotend id="0.8 mm" />

View File

@ -31,7 +31,9 @@ Generic TPU 95A profile. Serves as an example file, data in this file is not cor
<hotend id="0.25 mm" />
<hotend id="0.4 mm" />
<hotend id="0.6 mm" />
<hotend id="0.8 mm" />
<hotend id="0.8 mm">
<setting key="hardware compatible">no</setting>
</hotend>
</machine>
</settings>
</fdmmaterial>

View File

@ -3,7 +3,6 @@
Automatically generated PLA profile. Data in this file may not be not correct.
-->
<fdmmaterial xmlns="http://www.ultimaker.com/material">
<inherits>generic_pla</inherits>
<metadata>
<name>
<brand>Ultimaker</brand>
@ -38,14 +37,14 @@ Automatically generated PLA profile. Data in this file may not be not correct.
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2 Go"/>
<machine_identifier manufacturer="Ultimaker" product="Ultimaker 2 Extended"/>
<setting key="processing temperature graph">
<point flow="2" temperature="20"/>
<point flow="10" temperature="20"/>
<point flow="2" temperature="180"/>
<point flow="10" temperature="230"/>
</setting>
</machine>
<machine>
<machine_identifier manufacturer="Ultimaker" product="Ultimaker Original"/>
<setting key="standby temperature">180</setting>
<setting key="standby temperature">150</setting>
</machine>
</settings>
</fdmmaterial>

View File

@ -463,7 +463,7 @@ UM.MainWindow
target: Cura.Actions.addProfile
onTriggered:
{
Cura.ContainerManager.createQualityChanges();
Cura.ContainerManager.createQualityChanges(null);
preferences.setPage(4);
preferences.show();

View File

@ -61,6 +61,10 @@ UM.ManagementPage
return -1;
}
function canCreateProfile() {
return base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) && Cura.MachineManager.hasUserSettings;
}
buttons: [
Button
{
@ -69,26 +73,39 @@ UM.ManagementPage
enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false;
onClicked: Cura.MachineManager.setActiveQuality(base.currentItem.id)
},
// Create button
Button
{
text: base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) && Cura.MachineManager.hasUserSettings ? catalog.i18nc("@label", "Create") : catalog.i18nc("@label", "Duplicate")
text: catalog.i18nc("@label", "Create")
enabled: base.canCreateProfile()
visible: base.canCreateProfile()
iconName: "list-add";
onClicked:
{
var selectedContainer;
if (base.currentItem.id == Cura.MachineManager.activeQualityId && Cura.MachineManager.hasUserSettings) {
selectedContainer = Cura.ContainerManager.createQualityChanges();
} else {
selectedContainer = Cura.ContainerManager.duplicateQualityOrQualityChanges(base.currentItem.name);
}
base.selectContainer(selectedContainer);
renameDialog.removeWhenRejected = true;
renameDialog.open();
renameDialog.selectText();
newNameDialog.object = base.currentItem != null ? base.currentItem.name : "";
newNameDialog.open();
newNameDialog.selectText();
}
},
// Duplicate button
Button
{
text: catalog.i18nc("@label", "Duplicate")
enabled: ! base.canCreateProfile()
visible: ! base.canCreateProfile()
iconName: "list-add";
onClicked:
{
newDuplicateNameDialog.object = base.currentItem.name;
newDuplicateNameDialog.open();
newDuplicateNameDialog.selectText();
}
},
Button
{
text: catalog.i18nc("@action:button", "Remove");
@ -103,7 +120,6 @@ UM.ManagementPage
enabled: base.currentItem != null ? !base.currentItem.readOnly : false;
onClicked:
{
renameDialog.removeWhenRejected = false;
renameDialog.open();
renameDialog.selectText();
}
@ -128,7 +144,6 @@ UM.ManagementPage
signal showProfileNameDialog()
onShowProfileNameDialog:
{
renameDialog.removeWhenRejected = true;
renameDialog.open();
renameDialog.selectText();
}
@ -145,7 +160,7 @@ UM.ManagementPage
Label {
id: profileName
text: base.currentItem ? base.currentItem.name : ""
text: base.currentItem ? base.currentItem.name: ""
font: UM.Theme.getFont("large")
width: parent.width
elide: Text.ElideRight
@ -249,24 +264,44 @@ UM.ManagementPage
objectList.currentIndex = -1 //Reset selection.
}
}
UM.RenameDialog
{
id: renameDialog;
object: base.currentItem != null ? base.currentItem.name : ""
property bool removeWhenRejected: false
onAccepted:
{
Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName)
objectList.currentIndex = -1 //Reset selection.
}
onRejected:
}
// Dialog to request a name when creating a new profile
UM.RenameDialog
{
id: newNameDialog;
object: "<new name>";
onAccepted:
{
if(removeWhenRejected)
{
Cura.ContainerManager.removeQualityChanges(base.currentItem.name)
}
var selectedContainer = Cura.ContainerManager.createQualityChanges(newName);
base.selectContainer(selectedContainer);
objectList.currentIndex = -1 //Reset selection.
}
}
// Dialog to request a name when duplicating a new profile
UM.RenameDialog
{
id: newDuplicateNameDialog;
object: "<new name>";
onAccepted:
{
var selectedContainer = Cura.ContainerManager.duplicateQualityOrQualityChanges(base.currentItem.name, newName);
base.selectContainer(selectedContainer);
objectList.currentIndex = -1 //Reset selection.
}
}
MessageDialog
{
id: messageDialog

View File

@ -277,7 +277,7 @@ Column
height: UM.Theme.getSize("setting_control").height
tooltip: Cura.MachineManager.activeQualityName
style: UM.Theme.styles.sidebar_header_button
property var valueWarning: Cura.MachineManager.activeQualityId == "empty_quality"
menu: ProfileMenu { }
UM.SimpleButton

View File

@ -11,7 +11,22 @@ QtObject {
property Component sidebar_header_button: Component {
ButtonStyle {
background: Rectangle {
color: control.enabled ? Theme.getColor("setting_control") : Theme.getColor("setting_control_disabled")
color:
{
if(control.enabled)
{
if(control.valueWarning)
{
return Theme.getColor("setting_validation_warning");
} else
{
return Theme.getColor("setting_control");
}
} else {
return Theme.getColor("setting_control_disabled");
}
}
border.width: Theme.getSize("default_lining").width
border.color: !control.enabled ? Theme.getColor("setting_control_disabled_border") :
control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border")