Merge branch '2.3'

Conflicts:
	resources/qml/MonitorButton.qml
This commit is contained in:
Ghostkeeper 2016-09-06 10:43:54 +02:00
commit fcbf4a93f3
No known key found for this signature in database
GPG key ID: 701948C5954A7385
15 changed files with 140 additions and 77 deletions

View file

@ -180,6 +180,8 @@ class CuraApplication(QtApplication):
ContainerRegistry.getInstance().addContainer(empty_material_container) ContainerRegistry.getInstance().addContainer(empty_material_container)
empty_quality_container = copy.deepcopy(empty_container) empty_quality_container = copy.deepcopy(empty_container)
empty_quality_container._id = "empty_quality" 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") empty_quality_container.addMetaDataEntry("type", "quality")
ContainerRegistry.getInstance().addContainer(empty_quality_container) ContainerRegistry.getInstance().addContainer(empty_quality_container)
empty_quality_changes_container = copy.deepcopy(empty_container) empty_quality_changes_container = copy.deepcopy(empty_container)
@ -509,8 +511,6 @@ class CuraApplication(QtApplication):
if self.getController().getActiveTool(): if self.getController().getActiveTool():
self._previous_active_tool = self.getController().getActiveTool().getPluginId() self._previous_active_tool = self.getController().getActiveTool().getPluginId()
self.getController().setActiveTool(None) self.getController().setActiveTool(None)
else:
self._previous_active_tool = None
def _onToolOperationStopped(self, event): def _onToolOperationStopped(self, event):
if self._center_after_select: if self._center_after_select:

View file

@ -14,8 +14,9 @@ class LayerPolygon:
SupportInfillType = 7 SupportInfillType = 7
MoveCombingType = 8 MoveCombingType = 8
MoveRetractionType = 9 MoveRetractionType = 9
SupportInterfaceType = 10
__jump_map = numpy.logical_or( numpy.arange(10) == NoneType, numpy.arange(10) >= MoveCombingType ) __jump_map = numpy.logical_or( numpy.arange(11) == NoneType, numpy.arange(11) >= MoveRetractionType )
def __init__(self, mesh, extruder, line_types, data, line_widths): def __init__(self, mesh, extruder, line_types, data, line_widths):
self._mesh = mesh self._mesh = mesh
@ -178,10 +179,11 @@ class LayerPolygon:
SkinType: Color(1.0, 1.0, 0.0, 1.0), SkinType: Color(1.0, 1.0, 0.0, 1.0),
SupportType: Color(0.0, 1.0, 1.0, 1.0), SupportType: Color(0.0, 1.0, 1.0, 1.0),
SkirtType: Color(0.0, 1.0, 1.0, 1.0), SkirtType: Color(0.0, 1.0, 1.0, 1.0),
InfillType: Color(1.0, 0.74, 0.0, 1.0), InfillType: Color(1.0, 0.75, 0.0, 1.0),
SupportInfillType: Color(0.0, 1.0, 1.0, 1.0), SupportInfillType: Color(0.0, 1.0, 1.0, 1.0),
MoveCombingType: Color(0.0, 0.0, 1.0, 1.0), MoveCombingType: Color(0.0, 0.0, 1.0, 1.0),
MoveRetractionType: Color(0.5, 0.5, 1.0, 1.0), MoveRetractionType: Color(0.5, 0.5, 1.0, 1.0),
SupportInterfaceType: Color(0.25, 0.75, 1.0, 1.0),
} }
# Should be generated in better way, not hardcoded. # Should be generated in better way, not hardcoded.
@ -192,8 +194,9 @@ class LayerPolygon:
[1.0, 1.0, 0.0, 1.0], [1.0, 1.0, 0.0, 1.0],
[0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 1.0, 1.0],
[0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 1.0, 1.0],
[1.0, 0.74, 0.0, 1.0], [1.0, 0.75, 0.0, 1.0],
[0.0, 1.0, 1.0, 1.0], [0.0, 1.0, 1.0, 1.0],
[0.0, 0.0, 1.0, 1.0], [0.0, 0.0, 1.0, 1.0],
[0.5, 0.5, 1.0, 1.0] [0.5, 0.5, 1.0, 1.0],
[0.25, 0.75, 1.0, 1.0]
]) ])

View file

@ -29,6 +29,8 @@ class PlatformPhysics:
self._change_timer.setInterval(100) self._change_timer.setInterval(100)
self._change_timer.setSingleShot(True) self._change_timer.setSingleShot(True)
self._change_timer.timeout.connect(self._onChangeTimerFinished) self._change_timer.timeout.connect(self._onChangeTimerFinished)
self._move_factor = 1.1 # By how much should we multiply overlap to calculate a new spot?
self._max_overlap_checks = 10 # How many times should we try to find a new spot per tick?
Preferences.getInstance().addPreference("physics/automatic_push_free", True) Preferences.getInstance().addPreference("physics/automatic_push_free", True)
Preferences.getInstance().addPreference("physics/automatic_drop_down", True) Preferences.getInstance().addPreference("physics/automatic_drop_down", True)
@ -99,27 +101,40 @@ class PlatformPhysics:
if other_node in transformed_nodes: if other_node in transformed_nodes:
continue # Other node is already moving, wait for next pass. continue # Other node is already moving, wait for next pass.
# Get the overlap distance for both convex hulls. If this returns None, there is no intersection. overlap = (0, 0) # Start loop with no overlap
move_vector = move_vector.set(x=overlap[0] * self._move_factor, z=overlap[1] * self._move_factor)
current_overlap_checks = 0
# Continue to check the overlap until we no longer find one.
while overlap and current_overlap_checks < self._max_overlap_checks:
current_overlap_checks += 1
head_hull = node.callDecoration("getConvexHullHead") head_hull = node.callDecoration("getConvexHullHead")
if head_hull: if head_hull: # One at a time intersection.
overlap = head_hull.intersectsPolygon(other_node.callDecoration("getConvexHull")) overlap = head_hull.translate(move_vector.x, move_vector.z).intersectsPolygon(other_node.callDecoration("getConvexHull"))
if not overlap: if not overlap:
other_head_hull = other_node.callDecoration("getConvexHullHead") other_head_hull = other_node.callDecoration("getConvexHullHead")
if other_head_hull: if other_head_hull:
overlap = node.callDecoration("getConvexHull").intersectsPolygon(other_head_hull) overlap = node.callDecoration("getConvexHull").translate(move_vector.x, move_vector.z).intersectsPolygon(other_head_hull)
if overlap:
# Moving ensured that overlap was still there. Try anew!
move_vector = move_vector.set(x=move_vector.x + overlap[0] * self._move_factor,
z=move_vector.z + overlap[1] * self._move_factor)
else:
# Moving ensured that overlap was still there. Try anew!
move_vector = move_vector.set(x=move_vector.x + overlap[0] * self._move_factor,
z=move_vector.z + overlap[1] * self._move_factor)
else: else:
own_convex_hull = node.callDecoration("getConvexHull") own_convex_hull = node.callDecoration("getConvexHull")
other_convex_hull = other_node.callDecoration("getConvexHull") other_convex_hull = other_node.callDecoration("getConvexHull")
if own_convex_hull and other_convex_hull: if own_convex_hull and other_convex_hull:
overlap = own_convex_hull.intersectsPolygon(other_convex_hull) overlap = own_convex_hull.translate(move_vector.x, move_vector.z).intersectsPolygon(other_convex_hull)
if overlap: # Moving ensured that overlap was still there. Try anew!
move_vector = move_vector.set(x=move_vector.x + overlap[0] * self._move_factor,
z=move_vector.z + overlap[1] * self._move_factor)
else: else:
# This can happen in some cases if the object is not yet done with being loaded. # This can happen in some cases if the object is not yet done with being loaded.
# Simply waiting for the next tick seems to resolve this correctly. # Simply waiting for the next tick seems to resolve this correctly.
overlap = None overlap = None
if overlap is None:
continue
move_vector = move_vector.set(x=overlap[0] * 1.1, z=overlap[1] * 1.1)
convex_hull = node.callDecoration("getConvexHull") convex_hull = node.callDecoration("getConvexHull")
if convex_hull: if convex_hull:
if not convex_hull.isValid(): if not convex_hull.isValid():

View file

@ -7,7 +7,7 @@ from PyQt5.QtWidgets import QMessageBox
from UM.Application import Application from UM.Application import Application
from UM.Preferences import Preferences from UM.Preferences import Preferences
from UM.Logger import Logger from UM.Logger import Logger
from UM.Message import Message
from UM.Settings.SettingRelation import RelationType from UM.Settings.SettingRelation import RelationType
import UM.Settings import UM.Settings
@ -547,6 +547,7 @@ class MachineManager(QObject):
preferred_material = None preferred_material = None
if old_material: if old_material:
preferred_material_name = old_material.getName() preferred_material_name = old_material.getName()
self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0], preferred_material_name).id) self.setActiveMaterial(self._updateMaterialContainer(self._global_container_stack.getBottom(), containers[0], preferred_material_name).id)
else: else:
Logger.log("w", "While trying to set the active variant, no variant was found to replace.") Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
@ -806,15 +807,15 @@ class MachineManager(QObject):
if containers: if containers:
return containers[0] 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 # 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) search_criteria.pop("id", None)
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria) containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
if containers: if containers:
return containers[0] 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 return self._empty_material_container
def _updateQualityContainer(self, definition, variant_container, material_container = None, preferred_quality_name = None): def _updateQualityContainer(self, definition, variant_container, material_container = None, preferred_quality_name = None):
@ -855,10 +856,9 @@ class MachineManager(QObject):
containers = container_registry.findInstanceContainers(**search_criteria) containers = container_registry.findInstanceContainers(**search_criteria)
if containers: if containers:
return containers[0] return containers[0]
# We still weren't able to find a quality for this specific material. # We still weren't able to find a quality for this specific material.
# Try to find qualities for a generic version of the 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 definition.getMetaDataEntry("has_machine_quality"):
if material_container: if material_container:
material_search_criteria["definition"] = material_container.getDefinition().id material_search_criteria["definition"] = material_container.getDefinition().id
@ -872,7 +872,6 @@ class MachineManager(QObject):
material_search_criteria["variant"] = variant_container.id material_search_criteria["variant"] = variant_container.id
else: else:
material_search_criteria["definition"] = "fdmprinter" material_search_criteria["definition"] = "fdmprinter"
material_containers = container_registry.findInstanceContainers(**material_search_criteria) material_containers = container_registry.findInstanceContainers(**material_search_criteria)
if material_containers: if material_containers:
search_criteria["material"] = material_containers[0].getId() search_criteria["material"] = material_containers[0].getId()
@ -890,6 +889,9 @@ class MachineManager(QObject):
if containers: if containers:
return containers[0] 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. Default settings will be used instead."))
message.show()
return self._empty_quality_container return self._empty_quality_container
## Finds a quality-changes container to use if any other container ## Finds a quality-changes container to use if any other container

View file

@ -56,6 +56,7 @@ message Polygon {
SupportInfillType = 7; SupportInfillType = 7;
MoveCombingType = 8; MoveCombingType = 8;
MoveRetractionType = 9; MoveRetractionType = 9;
SupportInterfaceType = 10;
} }
Type type = 1; // Type of move Type type = 1; // Type of move
bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used) bytes points = 2; // The points of the polygon, or two points if only a line segment (Currently only line segments are used)

View file

@ -229,7 +229,7 @@ class CuraEngineBackend(Backend):
if job.getResult() == StartSliceJob.StartJobResult.SettingError: if job.getResult() == StartSliceJob.StartJobResult.SettingError:
if Application.getInstance().getPlatformActivity: if Application.getInstance().getPlatformActivity:
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. Please check your setting values for errors.")) self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice with the current settings. Please check your settings for errors."))
self._error_message.show() self._error_message.show()
self.backendStateChange.emit(BackendState.Error) self.backendStateChange.emit(BackendState.Error)
else: else:
@ -238,7 +238,7 @@ class CuraEngineBackend(Backend):
if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice: if job.getResult() == StartSliceJob.StartJobResult.NothingToSlice:
if Application.getInstance().getPlatformActivity: if Application.getInstance().getPlatformActivity:
self._error_message = Message(catalog.i18nc("@info:status", "Unable to slice. No suitable models found.")) self._error_message = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume. Please scale or rotate models to fit."))
self._error_message.show() self._error_message.show()
self.backendStateChange.emit(BackendState.Error) self.backendStateChange.emit(BackendState.Error)
else: else:

View file

@ -103,10 +103,11 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
self._firmware_view.show() self._firmware_view.show()
@pyqtSlot() @pyqtSlot(str)
def updateAllFirmware(self): def updateAllFirmware(self, file_name):
file_name = file_name.replace("file://", "") # File dialogs prepend the path with file://, which we don't need / want
if not self._usb_output_devices: if not self._usb_output_devices:
Message(i18n_catalog.i18nc("@info","Cannot update firmware, there were no connected printers found.")).show() Message(i18n_catalog.i18nc("@info", "Cannot update firmware, there were no connected printers found.")).show()
return return
for printer_connection in self._usb_output_devices: for printer_connection in self._usb_output_devices:
@ -114,26 +115,26 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
self.spawnFirmwareInterface("") self.spawnFirmwareInterface("")
for printer_connection in self._usb_output_devices: for printer_connection in self._usb_output_devices:
try: try:
self._usb_output_devices[printer_connection].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName())) self._usb_output_devices[printer_connection].updateFirmware(file_name)
except FileNotFoundError: except FileNotFoundError:
# Should only happen in dev environments where the resources/firmware folder is absent. # Should only happen in dev environments where the resources/firmware folder is absent.
self._usb_output_devices[printer_connection].setProgress(100, 100) self._usb_output_devices[printer_connection].setProgress(100, 100)
Logger.log("w", "No firmware found for printer %s called '%s'" %(printer_connection, self._getDefaultFirmwareName())) Logger.log("w", "No firmware found for printer %s called '%s'", printer_connection, file_name)
Message(i18n_catalog.i18nc("@info", Message(i18n_catalog.i18nc("@info",
"Could not find firmware required for the printer at %s.") % printer_connection).show() "Could not find firmware required for the printer at %s.") % printer_connection).show()
self._firmware_view.close() self._firmware_view.close()
continue continue
@pyqtSlot(str, result = bool) @pyqtSlot(str, str, result = bool)
def updateFirmwareBySerial(self, serial_port): def updateFirmwareBySerial(self, serial_port, file_name):
if serial_port in self._usb_output_devices: if serial_port in self._usb_output_devices:
self.spawnFirmwareInterface(self._usb_output_devices[serial_port].getSerialPort()) self.spawnFirmwareInterface(self._usb_output_devices[serial_port].getSerialPort())
try: try:
self._usb_output_devices[serial_port].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName())) self._usb_output_devices[serial_port].updateFirmware(file_name)
except FileNotFoundError: except FileNotFoundError:
self._firmware_view.close() self._firmware_view.close()
Logger.log("e", "Could not find firmware required for this machine called '%s'" %(self._getDefaultFirmwareName())) Logger.log("e", "Could not find firmware required for this machine called '%s'", file_name)
return False return False
return True return True
return False return False
@ -147,7 +148,8 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
return USBPrinterOutputDeviceManager._instance return USBPrinterOutputDeviceManager._instance
def _getDefaultFirmwareName(self): @pyqtSlot(result = str)
def getDefaultFirmwareName(self):
# Check if there is a valid global container stack # Check if there is a valid global container stack
global_container_stack = Application.getInstance().getGlobalContainerStack() global_container_stack = Application.getInstance().getGlobalContainerStack()
if not global_container_stack: if not global_container_stack:
@ -193,13 +195,13 @@ class USBPrinterOutputDeviceManager(QObject, OutputDevicePlugin, Extension):
Logger.log("d", "Choosing basic firmware for machine %s.", machine_id) Logger.log("d", "Choosing basic firmware for machine %s.", machine_id)
hex_file = machine_without_extras[machine_id] # Return "basic" firmware hex_file = machine_without_extras[machine_id] # Return "basic" firmware
else: else:
Logger.log("e", "There is no firmware for machine %s.", machine_id) Logger.log("w", "There is no firmware for machine %s.", machine_id)
if hex_file: if hex_file:
return hex_file.format(baudrate=baudrate) return Resources.getPath(CuraApplication.ResourceTypes.Firmware, hex_file.format(baudrate=baudrate))
else: else:
Logger.log("e", "Could not find any firmware for machine %s.", machine_id) Logger.log("w", "Could not find any firmware for machine %s.", machine_id)
raise FileNotFoundError() return ""
## Helper to identify serial ports (and scan for them) ## Helper to identify serial ports (and scan for them)
def _addRemovePorts(self, serial_ports): def _addRemovePorts(self, serial_ports):

View file

@ -1,5 +1,7 @@
from cura.MachineAction import MachineAction from cura.MachineAction import MachineAction
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
import cura.Settings.CuraContainerRegistry
import UM.Settings.DefinitionContainer
catalog = i18nCatalog("cura") catalog = i18nCatalog("cura")
@ -7,3 +9,9 @@ class UpgradeFirmwareMachineAction(MachineAction):
def __init__(self): def __init__(self):
super().__init__("UpgradeFirmware", catalog.i18nc("@action", "Upgrade Firmware")) super().__init__("UpgradeFirmware", catalog.i18nc("@action", "Upgrade Firmware"))
self._qml_url = "UpgradeFirmwareMachineAction.qml" self._qml_url = "UpgradeFirmwareMachineAction.qml"
cura.Settings.CuraContainerRegistry.getInstance().containerAdded.connect(self._onContainerAdded)
def _onContainerAdded(self, container):
# Add this action as a supported action to all machine definitions
if isinstance(container, UM.Settings.DefinitionContainer) and container.getMetaDataEntry("type") == "machine" and container.getMetaDataEntry("supports_usb_connection"):
UM.Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey())

View file

@ -5,6 +5,7 @@ import QtQuick 2.2
import QtQuick.Controls 1.1 import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import QtQuick.Window 2.1 import QtQuick.Window 2.1
import QtQuick.Dialogs 1.2 // For filedialog
import UM 1.2 as UM import UM 1.2 as UM
import Cura 1.0 as Cura import Cura 1.0 as Cura
@ -44,34 +45,45 @@ Cura.MachineAction
anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width width: parent.width
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "The firmware shipping with new Ultimakers works, but upgrades have been made to make better prints, and make calibration easier."); text: catalog.i18nc("@label", "The firmware shipping with new printers works, but new versions tend to have more features and improvements.");
} }
Label
{
id: upgradeText2
anchors.top: upgradeText1.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Cura requires these new features and thus your firmware will most likely need to be upgraded. You can do so now.");
}
Row Row
{ {
anchors.top: upgradeText2.bottom anchors.top: upgradeText1.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
width: childrenRect.width width: childrenRect.width
spacing: UM.Theme.getSize("default_margin").width spacing: UM.Theme.getSize("default_margin").width
property var firmwareName: Cura.USBPrinterManager.getDefaultFirmwareName()
Button Button
{ {
id: upgradeButton id: autoUpgradeButton
text: catalog.i18nc("@action:button","Upgrade to Marlin Firmware"); text: catalog.i18nc("@action:button", "Automatically upgrade Firmware");
enabled: parent.firmwareName != ""
onClicked: onClicked:
{ {
Cura.USBPrinterManager.updateAllFirmware() Cura.USBPrinterManager.updateAllFirmware(parent.firmwareName)
} }
} }
Button
{
id: manualUpgradeButton
text: catalog.i18nc("@action:button", "Upload custom Firmware");
onClicked:
{
customFirmwareDialog.open()
}
}
}
FileDialog
{
id: customFirmwareDialog
title: catalog.i18nc("@title:window", "Select custom firmware")
nameFilters: "Firmware image files (*.hex)"
selectExisting: true
onAccepted: Cura.USBPrinterManager.updateAllFirmware(fileUrl)
} }
} }
} }

View file

@ -15,7 +15,8 @@
"machine_extruder_trains": "machine_extruder_trains":
{ {
"0": "fdmextruder" "0": "fdmextruder"
} },
"supports_usb_connection": true
}, },
"settings": "settings":
{ {
@ -402,7 +403,7 @@
"description": "The maximum speed of the filament.", "description": "The maximum speed of the filament.",
"unit": "mm/s", "unit": "mm/s",
"type": "float", "type": "float",
"default_value": 25, "default_value": 299792458000,
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": false, "settable_per_extruder": false,
"settable_per_meshgroup": false "settable_per_meshgroup": false
@ -1160,7 +1161,7 @@
"default_value": 25, "default_value": 25,
"minimum_value": "0", "minimum_value": "0",
"maximum_value": "machine_max_feedrate_e", "maximum_value": "machine_max_feedrate_e",
"maximum_value_warning": "100", "maximum_value_warning": "25",
"enabled": "retraction_enable", "enabled": "retraction_enable",
"settable_per_mesh": false, "settable_per_mesh": false,
"settable_per_extruder": true, "settable_per_extruder": true,
@ -1173,7 +1174,7 @@
"default_value": 25, "default_value": 25,
"minimum_value": "0", "minimum_value": "0",
"maximum_value": "machine_max_feedrate_e", "maximum_value": "machine_max_feedrate_e",
"maximum_value_warning": "100", "maximum_value_warning": "25",
"enabled": "retraction_enable", "enabled": "retraction_enable",
"value": "retraction_speed", "value": "retraction_speed",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -1187,7 +1188,7 @@
"default_value": 25, "default_value": 25,
"minimum_value": "0", "minimum_value": "0",
"maximum_value": "machine_max_feedrate_e", "maximum_value": "machine_max_feedrate_e",
"maximum_value_warning": "100", "maximum_value_warning": "25",
"enabled": "retraction_enable", "enabled": "retraction_enable",
"value": "retraction_speed", "value": "retraction_speed",
"settable_per_mesh": false, "settable_per_mesh": false,
@ -3518,7 +3519,7 @@
}, },
"experimental": "experimental":
{ {
"label": "Experimental Modes", "label": "Experimental",
"type": "category", "type": "category",
"icon": "category_experimental", "icon": "category_experimental",
"description": "experimental!", "description": "experimental!",
@ -3763,6 +3764,7 @@
"type": "float", "type": "float",
"unit": "mm", "unit": "mm",
"default_value": 3, "default_value": 3,
"value": "machine_nozzle_head_distance",
"minimum_value": "0.0001", "minimum_value": "0.0001",
"maximum_value_warning": "20", "maximum_value_warning": "20",
"enabled": "wireframe_enabled", "enabled": "wireframe_enabled",

View file

@ -9,6 +9,9 @@
"visible": false "visible": false
}, },
"overrides": { "overrides": {
"machine_max_feedrate_e": {
"default_value": 45
},
"material_print_temperature": { "material_print_temperature": {
"minimum_value": "0" "minimum_value": "0"
}, },

View file

@ -346,6 +346,7 @@ UM.MainWindow
bottom: parent.bottom; bottom: parent.bottom;
right: parent.right; right: parent.right;
} }
z: 1
onMonitoringPrintChanged: base.monitoringPrint = monitoringPrint onMonitoringPrintChanged: base.monitoringPrint = monitoringPrint
width: UM.Theme.getSize("sidebar").width; width: UM.Theme.getSize("sidebar").width;
} }

View file

@ -4,7 +4,6 @@
import QtQuick 2.2 import QtQuick 2.2
import QtQuick.Controls 1.1 import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Layouts 1.1 import QtQuick.Layouts 1.1
import UM 1.1 as UM import UM 1.1 as UM
@ -161,7 +160,7 @@ Rectangle
anchors.rightMargin: UM.Theme.getSize("default_margin").width anchors.rightMargin: UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@label:", "Abort Print") text: catalog.i18nc("@label:", "Abort Print")
onClicked: confirmationDialog.visible = true onClicked: Cura.MachineManager.printerOutputDevices[0].setJobState("abort")
style: ButtonStyle style: ButtonStyle
{ {
@ -221,9 +220,9 @@ Rectangle
{ {
id: confirmationDialog id: confirmationDialog
title: catalog.i18nc("@text:MessageDialog", "Abort print") title: catalog.i18nc("@window:title", "Abort print")
icon: StandardIcon.Warning icon: StandardIcon.Warning
text: catalog.i18nc("@text:MessageDialog", "Do you really want to abort the print?") text: catalog.i18nc("@label", "Are you sure you want to abort the print?")
standardButtons: StandardButton.Yes | StandardButton.No standardButtons: StandardButton.Yes | StandardButton.No
Component.onCompleted: visible = false Component.onCompleted: visible = false
onYes: Cura.MachineManager.printerOutputDevices[0].setJobState("abort") onYes: Cura.MachineManager.printerOutputDevices[0].setJobState("abort")

View file

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

View file

@ -11,7 +11,22 @@ QtObject {
property Component sidebar_header_button: Component { property Component sidebar_header_button: Component {
ButtonStyle { ButtonStyle {
background: Rectangle { 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.width: Theme.getSize("default_lining").width
border.color: !control.enabled ? Theme.getColor("setting_control_disabled_border") : border.color: !control.enabled ? Theme.getColor("setting_control_disabled_border") :
control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border") control.hovered ? Theme.getColor("setting_control_border_highlight") : Theme.getColor("setting_control_border")