Merge branch '4.0'

This commit is contained in:
Ghostkeeper 2018-12-21 11:51:04 +01:00
commit 8308e48c2d
No known key found for this signature in database
GPG key ID: 86BEF881AE2CF276
16 changed files with 153 additions and 88 deletions

View file

@ -36,12 +36,12 @@ class CuraActions(QObject):
# Starting a web browser from a signal handler connected to a menu will crash on windows.
# So instead, defer the call to the next run of the event loop, since that does work.
# Note that weirdly enough, only signal handlers that open a web browser fail like that.
event = CallFunctionEvent(self._openUrl, [QUrl("http://ultimaker.com/en/support/software")], {})
event = CallFunctionEvent(self._openUrl, [QUrl("https://ultimaker.com/en/support/software")], {})
cura.CuraApplication.CuraApplication.getInstance().functionEvent(event)
@pyqtSlot()
def openBugReportPage(self) -> None:
event = CallFunctionEvent(self._openUrl, [QUrl("http://github.com/Ultimaker/Cura/issues")], {})
event = CallFunctionEvent(self._openUrl, [QUrl("https://github.com/Ultimaker/Cura/issues")], {})
cura.CuraApplication.CuraApplication.getInstance().functionEvent(event)
## Reset camera position and direction to default

View file

@ -6,6 +6,7 @@ from typing import Optional, List
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
from UM.Logger import Logger
from UM.Preferences import Preferences
from UM.Resources import Resources
from UM.i18n import i18nCatalog
@ -18,14 +19,20 @@ class SettingVisibilityPresetsModel(QObject):
onItemsChanged = pyqtSignal()
activePresetChanged = pyqtSignal()
def __init__(self, preferences, parent = None):
def __init__(self, preferences: Preferences, parent = None) -> None:
super().__init__(parent)
self._items = [] # type: List[SettingVisibilityPreset]
self._custom_preset = SettingVisibilityPreset(preset_id = "custom", name = "Custom selection", weight = -100)
self._populate()
basic_item = self.getVisibilityPresetById("basic")
basic_visibile_settings = ";".join(basic_item.settings)
if basic_item is not None:
basic_visibile_settings = ";".join(basic_item.settings)
else:
Logger.log("w", "Unable to find the basic visiblity preset.")
basic_visibile_settings = ""
self._preferences = preferences
@ -42,7 +49,8 @@ class SettingVisibilityPresetsModel(QObject):
visible_settings = self._preferences.getValue("general/visible_settings")
if not visible_settings:
self._preferences.setValue("general/visible_settings", ";".join(self._active_preset_item.settings))
new_visible_settings = self._active_preset_item.settings if self._active_preset_item is not None else []
self._preferences.setValue("general/visible_settings", ";".join(new_visible_settings))
else:
self._onPreferencesChanged("general/visible_settings")
@ -59,9 +67,7 @@ class SettingVisibilityPresetsModel(QObject):
def _populate(self) -> None:
from cura.CuraApplication import CuraApplication
items = [] # type: List[SettingVisibilityPreset]
custom_preset = SettingVisibilityPreset(preset_id="custom", name ="Custom selection", weight = -100)
items.append(custom_preset)
items.append(self._custom_preset)
for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset):
setting_visibility_preset = SettingVisibilityPreset()
try:
@ -77,7 +83,7 @@ class SettingVisibilityPresetsModel(QObject):
self.setItems(items)
@pyqtProperty("QVariantList", notify = onItemsChanged)
def items(self):
def items(self) -> List[SettingVisibilityPreset]:
return self._items
def setItems(self, items: List[SettingVisibilityPreset]) -> None:
@ -87,7 +93,7 @@ class SettingVisibilityPresetsModel(QObject):
@pyqtSlot(str)
def setActivePreset(self, preset_id: str) -> None:
if preset_id == self._active_preset_item.presetId:
if self._active_preset_item is not None and preset_id == self._active_preset_item.presetId:
Logger.log("d", "Same setting visibility preset [%s] selected, do nothing.", preset_id)
return
@ -96,7 +102,7 @@ class SettingVisibilityPresetsModel(QObject):
Logger.log("w", "Tried to set active preset to unknown id [%s]", preset_id)
return
need_to_save_to_custom = self._active_preset_item.presetId == "custom" and preset_id != "custom"
need_to_save_to_custom = self._active_preset_item is None or (self._active_preset_item.presetId == "custom" and preset_id != "custom")
if need_to_save_to_custom:
# Save the current visibility settings to custom
current_visibility_string = self._preferences.getValue("general/visible_settings")
@ -117,7 +123,9 @@ class SettingVisibilityPresetsModel(QObject):
@pyqtProperty(str, notify = activePresetChanged)
def activePreset(self) -> str:
return self._active_preset_item.presetId
if self._active_preset_item is not None:
return self._active_preset_item.presetId
return ""
def _onPreferencesChanged(self, name: str) -> None:
if name != "general/visible_settings":
@ -149,7 +157,12 @@ class SettingVisibilityPresetsModel(QObject):
else:
item_to_set = matching_preset_item
# If we didn't find a matching preset, fallback to custom.
if item_to_set is None:
item_to_set = self._custom_preset
if self._active_preset_item is None or self._active_preset_item.presetId != item_to_set.presetId:
self._active_preset_item = item_to_set
self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item.presetId)
if self._active_preset_item is not None:
self._preferences.setValue("cura/active_setting_visibility_preset", self._active_preset_item.presetId)
self.activePresetChanged.emit()

View file

@ -83,9 +83,11 @@ class AuthorizationService:
if not self.getUserProfile():
# We check if we can get the user profile.
# If we can't get it, that means the access token (JWT) was invalid or expired.
Logger.log("w", "Unable to get the user profile.")
return None
if self._auth_data is None:
Logger.log("d", "No auth data to retrieve the access_token from")
return None
return self._auth_data.access_token

View file

@ -230,7 +230,7 @@ class PrinterOutputDevice(QObject, OutputDevice):
# Returns the unique configurations of the printers within this output device
@pyqtProperty("QStringList", notify = uniqueConfigurationsChanged)
def uniquePrinterTypes(self) -> List[str]:
return list(set([configuration.printerType for configuration in self._unique_configurations]))
return list(sorted(set([configuration.printerType for configuration in self._unique_configurations])))
def _onPrintersChanged(self) -> None:
for printer in self._printers:

View file

@ -299,6 +299,7 @@ class MachineManager(QObject):
self.activeMaterialChanged.emit()
self.rootMaterialChanged.emit()
self.numberExtrudersEnabledChanged.emit()
def _onContainersChanged(self, container: ContainerInterface) -> None:
self._instance_container_timer.start()

View file

@ -229,6 +229,7 @@ class CuraEngineBackend(QObject, Backend):
if not self._build_plates_to_be_sliced:
self.processingProgress.emit(1.0)
Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.")
self.setState(BackendState.Done)
return
if self._process_layers_job:
@ -410,7 +411,7 @@ class CuraEngineBackend(QObject, Backend):
if job.getResult() == StartJobResult.NothingToSlice:
if self._application.platformActivity:
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 = Message(catalog.i18nc("@info:status", "Nothing to slice because none of the models fit the build volume or are assigned to a disabled extruder. Please scale or rotate models to fit, or enable an extruder."),
title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.setState(BackendState.Error)

View file

@ -16,12 +16,20 @@ Item
color: UM.Theme.getColor("viewport_overlay")
anchors.fill: parent
// This mouse area is to prevent mouse clicks to be passed onto the scene.
MouseArea
{
anchors.fill: parent
acceptedButtons: Qt.AllButtons
onWheel: wheel.accepted = true
}
// Disable dropping files into Cura when the monitor page is active
DropArea
{
anchors.fill: parent
}
}
Loader

View file

@ -25,7 +25,7 @@ UM.Dialog
{
if(!visible) //Whenever the window is closed (either via the "Close" button or the X on the window frame), we want to update it in the stack.
{
manager.writeScriptsToStack();
manager.writeScriptsToStack()
}
}
@ -67,12 +67,17 @@ UM.Dialog
ListView
{
id: activeScriptsList
anchors.top: activeScriptsHeader.bottom
anchors.topMargin: base.textMargin
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
anchors.rightMargin: base.textMargin
anchors
{
top: activeScriptsHeader.bottom
left: parent.left
right: parent.right
rightMargin: base.textMargin
topMargin: base.textMargin
leftMargin: UM.Theme.getSize("default_margin").width
}
height: childrenRect.height
model: manager.scriptList
delegate: Item
@ -84,8 +89,12 @@ UM.Dialog
id: activeScriptButton
text: manager.getScriptLabelByKey(modelData.toString())
exclusiveGroup: selectedScriptGroup
width: parent.width
height: UM.Theme.getSize("setting").height
checkable: true
checked: {
checked:
{
if (manager.selectedScriptIndex == index)
{
base.activeScriptName = manager.getScriptLabelByKey(modelData.toString())
@ -102,8 +111,7 @@ UM.Dialog
manager.setSelectedScriptIndex(index)
base.activeScriptName = manager.getScriptLabelByKey(modelData.toString())
}
width: parent.width
height: UM.Theme.getSize("setting").height
style: ButtonStyle
{
background: Rectangle
@ -121,6 +129,7 @@ UM.Dialog
}
}
}
Button
{
id: removeButton
@ -249,8 +258,8 @@ UM.Dialog
onTriggered: manager.addScriptToList(modelData.toString())
}
onObjectAdded: scriptsMenu.insertItem(index, object);
onObjectRemoved: scriptsMenu.removeItem(object);
onObjectAdded: scriptsMenu.insertItem(index, object)
onObjectRemoved: scriptsMenu.removeItem(object)
}
}
}
@ -268,12 +277,16 @@ UM.Dialog
{
id: scriptSpecsHeader
text: manager.selectedScriptIndex == -1 ? catalog.i18nc("@label", "Settings") : base.activeScriptName
anchors.top: parent.top
anchors.topMargin: base.textMargin
anchors.left: parent.left
anchors.leftMargin: base.textMargin
anchors.right: parent.right
anchors.rightMargin: base.textMargin
anchors
{
top: parent.top
topMargin: base.textMargin
left: parent.left
leftMargin: base.textMargin
right: parent.right
rightMargin: base.textMargin
}
elide: Text.ElideRight
height: 20 * screenScaleFactor
font: UM.Theme.getFont("large")
@ -283,11 +296,16 @@ UM.Dialog
ScrollView
{
id: scrollView
anchors.top: scriptSpecsHeader.bottom
anchors.topMargin: settingsPanel.textMargin
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors
{
top: scriptSpecsHeader.bottom
topMargin: settingsPanel.textMargin
left: parent.left
leftMargin: UM.Theme.getSize("default_margin").width
right: parent.right
bottom: parent.bottom
}
visible: manager.selectedScriptDefinitionId != ""
style: UM.Theme.styles.scrollview;
@ -297,11 +315,12 @@ UM.Dialog
spacing: UM.Theme.getSize("default_lining").height
model: UM.SettingDefinitionsModel
{
id: definitionsModel;
id: definitionsModel
containerId: manager.selectedScriptDefinitionId
showAll: true
}
delegate:Loader
delegate: Loader
{
id: settingLoader
@ -312,23 +331,24 @@ UM.Dialog
{
if(model.type != undefined)
{
return UM.Theme.getSize("section").height;
return UM.Theme.getSize("section").height
}
else
{
return 0;
return 0
}
}
else
{
return 0;
return 0
}
}
Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled == "True" ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
enabled: opacity > 0
property var definition: model
property var settingDefinitionsModel: definitionsModel
property var propertyProvider: provider
@ -339,11 +359,12 @@ UM.Dialog
//causing nasty issues when selecting different options. So disable asynchronous loading of enum type completely.
asynchronous: model.type != "enum" && model.type != "extruder"
onLoaded: {
onLoaded:
{
settingLoader.item.showRevertButton = false
settingLoader.item.showInheritButton = false
settingLoader.item.showLinkedSettingIcon = false
settingLoader.item.doDepthIndentation = true
settingLoader.item.doDepthIndentation = false
settingLoader.item.doQualityUserSettingEmphasis = false
}
@ -395,18 +416,14 @@ UM.Dialog
onShowTooltip:
{
tooltip.text = text;
var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0);
tooltip.show(position);
tooltip.text = text
var position = settingLoader.mapToItem(settingsPanel, settingsPanel.x, 0)
tooltip.show(position)
tooltip.target.x = position.x + 1
}
onHideTooltip:
{
tooltip.hide();
}
onHideTooltip: tooltip.hide()
}
}
}
}
@ -459,6 +476,7 @@ UM.Dialog
Cura.SettingUnknown { }
}
}
rightButtons: Button
{
text: catalog.i18nc("@action:button", "Close")
@ -466,7 +484,8 @@ UM.Dialog
onClicked: dialog.accept()
}
Button {
Button
{
objectName: "postProcessingSaveAreaButton"
visible: activeScriptsList.count > 0
height: UM.Theme.getSize("save_button_save_to_button").height
@ -474,8 +493,10 @@ UM.Dialog
tooltip: catalog.i18nc("@info:tooltip", "Change active post-processing scripts")
onClicked: dialog.show()
style: ButtonStyle {
background: Rectangle {
style: ButtonStyle
{
background: Rectangle
{
id: deviceSelectionIcon
border.width: UM.Theme.getSize("default_lining").width
border.color: !control.enabled ? UM.Theme.getColor("action_button_disabled_border") :
@ -485,12 +506,15 @@ UM.Dialog
control.pressed ? UM.Theme.getColor("action_button_active") :
control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
Behavior on color { ColorAnimation { duration: 50; } }
anchors.left: parent.left
anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2);
anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2)
width: parent.height
height: parent.height
UM.RecolorImage {
UM.RecolorImage
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: Math.round(parent.width / 2)
@ -498,11 +522,11 @@ UM.Dialog
sourceSize.height: height
color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") :
control.pressed ? UM.Theme.getColor("action_button_active_text") :
control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text");
control.hovered ? UM.Theme.getColor("action_button_hovered_text") : UM.Theme.getColor("action_button_text")
source: "postprocessing.svg"
}
}
label: Label{ }
label: Label { }
}
}
}

View file

@ -18,6 +18,10 @@ Item
height: centerSection.height
width: maximumWidth
// Enable keyboard navigation
Keys.onLeftPressed: navigateTo(currentIndex - 1)
Keys.onRightPressed: navigateTo(currentIndex + 1)
Item
{

View file

@ -24,6 +24,11 @@ Component
}
}
width: maximumWidth
// Enable keyboard navigation. NOTE: This is done here so that we can also potentially
// forward to the queue items in the future. (Deleting selected print job, etc.)
Keys.forwardTo: carousel
Component.onCompleted: forceActiveFocus()
UM.I18nCatalog
{
@ -59,7 +64,9 @@ Component
}
width: parent.width
height: 264 * screenScaleFactor // TODO: Theme!
MonitorCarousel {}
MonitorCarousel {
id: carousel
}
}
MonitorQueue

View file

@ -47,7 +47,7 @@ def getMetaData() -> Dict[str, Any]:
},
"user": {
"get_version": upgrade.getCfgVersion,
"location": {"./user"}
"location": {"./user", "./materials/*"}
},
"variant": {
"get_version": upgrade.getCfgVersion,

View file

@ -134,10 +134,13 @@ Column
onPreferenceChanged:
{
var autoSlice = UM.Preferences.getValue("general/auto_slice")
prepareButtons.autoSlice = autoSlice
if(autoSlice)
if(prepareButtons.autoSlice != autoSlice)
{
CuraApplication.backend.forceSlice()
prepareButtons.autoSlice = autoSlice
if(autoSlice)
{
CuraApplication.backend.forceSlice()
}
}
}
}

View file

@ -29,6 +29,9 @@ Item
source: UM.Theme.getImage("logo")
width: UM.Theme.getSize("logo").width
height: UM.Theme.getSize("logo").height
sourceSize.width: width
sourceSize.height: height
}
Row

View file

@ -7,16 +7,18 @@ import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Instantiator {
model: UM.ContainerStacksModel {
filter: {"type": "machine", "um_network_key": null}
}
MenuItem {
text: model.name;
checkable: true;
Instantiator
{
model: Cura.PrintersModel {}
MenuItem
{
text: model.name
checkable: true
checked: Cura.MachineManager.activeMachineId == model.id
exclusiveGroup: group;
onTriggered: Cura.MachineManager.setActiveMachine(model.id);
exclusiveGroup: group
visible: !model.hasRemoteConnection
onTriggered: Cura.MachineManager.setActiveMachine(model.id)
}
onObjectAdded: menu.insertItem(index, object)
onObjectRemoved: menu.removeItem(object)

View file

@ -7,18 +7,17 @@ import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
Instantiator {
model: UM.ContainerStacksModel {
filter: {"type": "machine", "um_network_key": "*", "hidden": "False"}
}
MenuItem {
// TODO: Use printer_group icon when it's a cluster. Not use it for now since it doesn't look as expected
// iconSource: UM.Theme.getIcon("printer_single")
Instantiator
{
model: Cura.PrintersModel {}
MenuItem
{
text: model.metadata["connect_group_name"]
checkable: true;
checkable: true
visible: model.hasRemoteConnection
checked: Cura.MachineManager.activeMachineNetworkGroupName == model.metadata["connect_group_name"]
exclusiveGroup: group;
onTriggered: Cura.MachineManager.setActiveMachine(model.id);
exclusiveGroup: group
onTriggered: Cura.MachineManager.setActiveMachine(model.id)
}
onObjectAdded: menu.insertItem(index, object)
onObjectRemoved: menu.removeItem(object)

View file

@ -15,7 +15,7 @@ Rectangle
id: materialSlot
property var material: null
property var hovered: false
property var is_favorite: material != null ? material.is_favorite : false
property var is_favorite: material != null && material.is_favorite
height: UM.Theme.getSize("favorites_row").height
width: parent.width
@ -73,11 +73,9 @@ Rectangle
if (materialSlot.is_favorite)
{
base.materialManager.removeFavorite(material.root_material_id)
materialSlot.is_favorite = false
return
}
base.materialManager.addFavorite(material.root_material_id)
materialSlot.is_favorite = true
return
}
style: ButtonStyle