Merge branch '3.0'

This commit is contained in:
Ghostkeeper 2017-09-22 12:58:40 +02:00
commit c02c2201e2
No known key found for this signature in database
GPG Key ID: C5F96EE2BC0F7E75
3 changed files with 176 additions and 184 deletions

View File

@ -1,6 +1,9 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from typing import Union
#Type hinting.
from typing import Union, List, Dict
from UM.Signal import Signal
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
from UM.FlameProfiler import pyqtSlot
@ -366,7 +369,7 @@ class MachineManager(QObject):
def _createUniqueName(self, container_type: str, current_name: str, new_name: str, fallback_name: str) -> str:
return ContainerRegistry.getInstance().createUniqueName(container_type, current_name, new_name, fallback_name)
def _checkStacksHaveErrors(self):
def _checkStacksHaveErrors(self) -> bool:
if self._global_container_stack is None: #No active machine.
return False
@ -390,7 +393,7 @@ class MachineManager(QObject):
## Check if the global_container has instances in the user container
@pyqtProperty(bool, notify = activeStackValueChanged)
def hasUserSettings(self):
def hasUserSettings(self) -> bool:
if not self._global_container_stack:
return False
@ -405,7 +408,7 @@ class MachineManager(QObject):
return False
@pyqtProperty(int, notify = activeStackValueChanged)
def numUserSettings(self):
def numUserSettings(self) -> int:
if not self._global_container_stack:
return 0
num_user_settings = 0
@ -450,7 +453,7 @@ class MachineManager(QObject):
# Note that the _stacks_have_errors is cached due to performance issues
# Calling _checkStack(s)ForErrors on every change is simply too expensive
@pyqtProperty(bool, notify = stacksValidationChanged)
def stacksHaveErrors(self):
def stacksHaveErrors(self) -> bool:
return bool(self._stacks_have_errors)
@pyqtProperty(str, notify = activeStackChanged)
@ -475,7 +478,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(QObject, notify = globalContainerChanged)
def activeMachine(self) -> "GlobalStack":
def activeMachine(self) -> Optional["GlobalStack"]:
return self._global_container_stack
@pyqtProperty(str, notify = activeStackChanged)
@ -495,10 +498,11 @@ class MachineManager(QObject):
return ""
@pyqtProperty("QVariantList", notify=activeVariantChanged)
def activeVariantNames(self):
def activeVariantNames(self) -> List[str]:
result = []
if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None:
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
if active_stacks is not None:
for stack in active_stacks:
variant_container = stack.variant
if variant_container and variant_container != self._empty_variant_container:
result.append(variant_container.getName())
@ -506,10 +510,11 @@ class MachineManager(QObject):
return result
@pyqtProperty("QVariantList", notify = activeMaterialChanged)
def activeMaterialNames(self):
def activeMaterialNames(self) -> List[str]:
result = []
if ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() is not None:
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
if active_stacks is not None:
for stack in active_stacks:
material_container = stack.material
if material_container and material_container != self._empty_material_container:
result.append(material_container.getName())
@ -525,34 +530,30 @@ class MachineManager(QObject):
return ""
@pyqtProperty("QVariantMap", notify = activeVariantChanged)
def allActiveVariantIds(self):
if not self._global_container_stack:
return {}
def allActiveVariantIds(self) -> Dict[str, str]:
result = {}
active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
if active_stacks is not None: #If we have a global stack.
for stack in active_stacks:
variant_container = stack.variant
if not variant_container:
continue
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
variant_container = stack.variant
if not variant_container:
continue
result[stack.getId()] = variant_container.getId()
result[stack.getId()] = variant_container.getId()
return result
@pyqtProperty("QVariantMap", notify = activeMaterialChanged)
def allActiveMaterialIds(self):
if not self._global_container_stack:
return {}
def allActiveMaterialIds(self) -> Dict[str, str]:
result = {}
active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
if active_stacks is not None: #If we have a global stack.
for stack in active_stacks:
material_container = stack.material
if not material_container:
continue
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
material_container = stack.material
if not material_container:
continue
result[stack.getId()] = material_container.getId()
result[stack.getId()] = material_container.getId()
return result
@ -862,7 +863,7 @@ class MachineManager(QObject):
# \param quality_name \type{str} the name of the quality.
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
@UM.FlameProfiler.profile
def determineQualityAndQualityChangesForQualityType(self, quality_type: str):
def determineQualityAndQualityChangesForQualityType(self, quality_type: str) -> List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]:
quality_manager = QualityManager.getInstance()
result = []
empty_quality_changes = self._empty_quality_changes_container
@ -899,7 +900,7 @@ class MachineManager(QObject):
#
# \param quality_changes_name \type{str} the name of the quality changes.
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str):
def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str) -> Optional[List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]]:
result = []
quality_manager = QualityManager.getInstance()
@ -1136,7 +1137,7 @@ class MachineManager(QObject):
return MachineManager()
@deprecated("Use ExtruderStack.material = ... and it won't be necessary", "2.7")
def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None):
def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None) -> InstanceContainer:
if not definition.getMetaDataEntry("has_materials"):
return self._empty_material_container
@ -1182,7 +1183,7 @@ class MachineManager(QObject):
def _onQualityNameChanged(self):
self.activeQualityChanged.emit()
def _getContainerChangedSignals(self):
def _getContainerChangedSignals(self) -> List[Signal]:
stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
stacks.append(self._global_container_stack)
return [ s.containersChanged for s in stacks ]

View File

@ -110,12 +110,11 @@ class ProfilesModel(InstanceContainersModel):
# active machine and material, and later yield the right ones.
tmp_all_quality_items = OrderedDict()
for item in super()._recomputeItems():
profile = container_registry.findContainers(id = item["id"])
profile = container_registry.findContainers(id=item["id"])
quality_type = profile[0].getMetaDataEntry("quality_type") if profile else ""
if quality_type not in tmp_all_quality_items:
tmp_all_quality_items[quality_type] = {"suitable_container": None,
"all_containers": []}
tmp_all_quality_items[quality_type] = {"suitable_container": None, "all_containers": []}
tmp_all_quality_items[quality_type]["all_containers"].append(item)
if tmp_all_quality_items[quality_type]["suitable_container"] is None and profile[0] in qualities:
@ -126,25 +125,14 @@ class ProfilesModel(InstanceContainersModel):
for key in reversed(tmp_all_quality_items.keys()):
all_quality_items[key] = tmp_all_quality_items[key]
# First the suitable containers are set in the model
containers = []
for data_item in all_quality_items.values():
suitable_item = data_item["suitable_container"]
if suitable_item is None:
suitable_item = data_item["all_containers"][0]
containers.append(suitable_item)
item = data_item["suitable_container"]
if item is None:
item = data_item["all_containers"][0]
# Once the suitable containers are collected, the rest of the containers are appended
for data_item in all_quality_items.values():
for item in data_item["all_containers"]:
if item not in containers:
containers.append(item)
# Now all the containers are set
for item in containers:
profile = container_registry.findContainers(id = item["id"])
if not profile:
item["layer_height"] = "" #Can't update a profile that is unknown.
item["layer_height"] = "" # Can't update a profile that is unknown.
item["available"] = False
yield item
continue
@ -152,13 +140,13 @@ class ProfilesModel(InstanceContainersModel):
profile = profile[0]
item["available"] = profile in qualities
#Easy case: This profile defines its own layer height.
# Easy case: This profile defines its own layer height.
if profile.hasProperty("layer_height", "value"):
self._setItemLayerHeight(item, profile.getProperty("layer_height", "value"), unit)
yield item
continue
#Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
# Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
quality_type = profile.getMetaDataEntry("quality_type", None)
if quality_type:
quality_results = machine_manager.determineQualityAndQualityChangesForQualityType(quality_type)

View File

@ -40,110 +40,108 @@ Item
//
// Quality profile
//
Rectangle
Item
{
Timer {
id: qualitySliderChangeTimer
interval: 50
running: false
repeat: false
onTriggered: Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(qualityRowSlider.value).id)
}
Component.onCompleted:
{
qualityRow.updateQualitySliderProperties()
}
Connections
{
target: Cura.MachineManager
onActiveQualityChanged:
{
qualityRow.updateQualitySliderProperties()
}
}
id: qualityRow
property var totalTicks: 0
property var availableTotalTicks: 0
property var qualitySliderStep: qualityRow.totalTicks != 0 ? (base.width * 0.55) / (qualityRow.totalTicks) : 0
property var qualitySliderSelectedValue: 0
property var sliderAvailableMin : 0
property var sliderAvailableMax : 0
property var sliderMarginRight : 0
function updateQualitySliderProperties()
{
qualityRow.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0
var availableMin = -1
var availableMax = -1
for (var i = 0; i <= Cura.ProfilesModel.rowCount(); i++)
{
//Find slider range, min and max value
if (availableMin == -1 && Cura.ProfilesModel.getItem(i).available)
{
availableMin = i
availableMax = i
}
else if(Cura.ProfilesModel.getItem(i).available)
{
availableMax = i
}
//Find selected value
if(Cura.MachineManager.activeQualityId == Cura.ProfilesModel.getItem(i).id)
{
qualitySliderSelectedValue = i
}
}
if(availableMin !=-1)
{
availableTotalTicks = availableMax - availableMin
}
else
{
availableTotalTicks = -1
}
qualitySliderStep = qualityRow.totalTicks != 0 ? (base.width * 0.55) / (qualityRow.totalTicks) : 0
if(availableMin == -1)
{
sliderMarginRight = base.width * 0.55
}
else if (availableMin == 0 && availableMax == 0)
{
sliderMarginRight = base.width * 0.55
}
else if(availableMin == availableMax)
{
sliderMarginRight = (qualityRow.totalTicks - availableMin) * qualitySliderStep
}
else if(availableMin != availableMax)
{
sliderMarginRight = (qualityRow.totalTicks - availableMax) * qualitySliderStep
}
qualityRow.sliderAvailableMin = availableMin
qualityRow.sliderAvailableMax = availableMax
}
height: UM.Theme.getSize("sidebar_margin").height
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.right: parent.right
Timer
{
id: qualitySliderChangeTimer
interval: 50
running: false
repeat: false
onTriggered: Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(qualitySlider.value).id)
}
Component.onCompleted: qualityModel.update()
Connections
{
target: Cura.MachineManager
onActiveQualityChanged: qualityModel.update()
}
ListModel
{
id: qualityModel
property var totalTicks: 0
property var availableTotalTicks: 0
property var activeQualityId: 0
property var qualitySliderStepWidth: 0
property var qualitySliderAvailableMin : 0
property var qualitySliderAvailableMax : 0
property var qualitySliderMarginRight : 0
function update () {
reset()
var availableMin = -1
var availableMax = -1
for (var i = 0; i <= Cura.ProfilesModel.rowCount(); i++) {
var qualityItem = Cura.ProfilesModel.getItem(i)
// Add each quality item to the UI quality model
qualityModel.append(qualityItem)
// Set selected value
if (Cura.MachineManager.activeQualityId == qualityItem.id) {
qualityModel.activeQualityId = i
}
// Set min available
if (qualityItem.available && availableMin == -1) {
availableMin = i
}
// Set max available
if (qualityItem.available) {
availableMax = i
}
}
// Set total available ticks for active slider part
if (availableMin != -1) {
qualityModel.availableTotalTicks = availableMax - availableMin
}
// Calculate slider values
calculateSliderStepWidth(qualityModel.totalTicks)
calculateSliderMargins(availableMin, availableMax, qualityModel.totalTicks)
qualityModel.qualitySliderAvailableMin = availableMin
qualityModel.qualitySliderAvailableMax = availableMax
}
function calculateSliderStepWidth (totalTicks) {
qualityModel.qualitySliderStepWidth = totalTicks != 0 ? (base.width * 0.55) / (totalTicks) : 0
}
function calculateSliderMargins (availableMin, availableMax, totalTicks) {
if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) {
qualityModel.qualitySliderMarginRight = base.width * 0.55
} else if (availableMin == availableMax) {
qualityModel.qualitySliderMarginRight = (totalTicks - availableMin) * qualitySliderStepWidth
} else {
qualityModel.qualitySliderMarginRight = (totalTicks - availableMax) * qualitySliderStepWidth
}
}
function reset () {
qualityModel.clear()
qualityModel.totalTicks = Cura.ProfilesModel.rowCount() - 1 // minus one, because slider starts from 0
qualityModel.availableTotalTicks = -1
}
}
Text
{
id: qualityRowTitle
@ -152,29 +150,32 @@ Item
color: UM.Theme.getColor("text")
}
//Show titles for the each quality slider ticks
// Show titles for the each quality slider ticks
Item
{
y: -5;
anchors.left: speedSlider.left
Repeater
{
model: qualityRow.totalTicks + 1
model: qualityModel
Text
{
anchors.verticalCenter: parent.verticalCenter
anchors.top: parent.top
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2
color: UM.Theme.getColor("text")
text: Cura.ProfilesModel.getItem(index).layer_height_without_unit
color: (Cura.MachineManager.activeMachine != null && Cura.ProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
text: Cura.MachineManager.activeMachine != null ? Cura.ProfilesModel.getItem(index).layer_height_without_unit : ""
width: 1
x:
{
if(index != qualityRow.totalTicks)
return (base.width * 0.55 / qualityRow.totalTicks) * index;
else
return (base.width * 0.55 / qualityRow.totalTicks) * index - 15;
x: {
// Make sure the text aligns correctly with each tick
if (index == 0) {
return (base.width * 0.55 / qualityModel.totalTicks) * index
} else if (index == qualityModel.totalTicks) {
return (base.width * 0.55 / qualityModel.totalTicks) * index - width
} else {
return (base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2)
}
}
}
}
@ -197,8 +198,7 @@ Item
width: base.width * 0.55
height: 2
color: UM.Theme.getColor("quality_slider_unavailable")
//radius: parent.radius
anchors.verticalCenter: qualityRowSlider.verticalCenter
anchors.verticalCenter: qualitySlider.verticalCenter
x: 0
}
@ -206,51 +206,52 @@ Item
Repeater
{
id: qualityRepeater
model: qualityRow.totalTicks + 1
Rectangle {
model: qualityModel
Rectangle
{
anchors.verticalCenter: parent.verticalCenter
color: qualityRow.availableTotalTicks != 0 ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
width: 1
height: 6
y: 0
x: qualityRow.qualitySliderStep * index
x: qualityModel.qualitySliderStepWidth * index
}
}
Slider
{
id: qualityRowSlider
id: qualitySlider
height: UM.Theme.getSize("sidebar_margin").height
anchors.bottom: speedSlider.bottom
enabled: qualityRow.availableTotalTicks != 0
enabled: qualityModel.availableTotalTicks > 0
updateValueWhileDragging : false
minimumValue: qualityRow.sliderAvailableMin
maximumValue: qualityRow.sliderAvailableMax
minimumValue: qualityModel.qualitySliderAvailableMin
maximumValue: qualityModel.qualitySliderAvailableMax
stepSize: 1
value: qualityRow.qualitySliderSelectedValue
value: qualityModel.activeQualityId
width: qualityRow.qualitySliderStep * (qualityRow.availableTotalTicks)
width: qualityModel.qualitySliderStepWidth * qualityModel.availableTotalTicks
anchors.right: parent.right
anchors.rightMargin: qualityRow.sliderMarginRight
anchors.rightMargin: qualityModel.qualitySliderMarginRight
style: SliderStyle
{
//Draw Available line
groove: Rectangle {
implicitHeight: 2
anchors.verticalCenter: qualityRowSlider.verticalCenter
anchors.verticalCenter: qualitySlider.verticalCenter
color: UM.Theme.getColor("quality_slider_available")
radius: 1
}
handle: Item {
Rectangle {
id: qualityhandleButton
anchors.verticalCenter: qualityRowSlider.verticalCenter
anchors.verticalCenter: qualitySlider.verticalCenter
anchors.centerIn: parent
color: control.enabled ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
implicitWidth: 10
@ -261,12 +262,14 @@ Item
}
onValueChanged: {
//Prevent updating during view initializing. Trigger only if the value changed by user
if(qualityRowSlider.value != qualityRow.qualitySliderSelectedValue)
if(Cura.MachineManager.activeMachine != null)
{
//start updating with short delay
qualitySliderChangeTimer.start();
//Prevent updating during view initializing. Trigger only if the value changed by user
if(qualitySlider.value != qualityModel.activeQualityId)
{
//start updating with short delay
qualitySliderChangeTimer.start();
}
}
}
}
@ -519,7 +522,7 @@ Item
Text {
id: gradualInfillLabel
anchors.left: enableGradualInfillCheckBox.right
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width / 2 // FIXME better margin value
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width / 2
text: catalog.i18nc("@label", "Enable gradual")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")