mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-15 22:45:53 +08:00
Merge branch 'master' of github.com:Ultimaker/Cura
This commit is contained in:
commit
ea39cd4615
@ -220,7 +220,8 @@ class CuraApplication(QtApplication):
|
||||
"LocalFileOutputDevice",
|
||||
"TranslateTool",
|
||||
"FileLogger",
|
||||
"XmlMaterialProfile"
|
||||
"XmlMaterialProfile",
|
||||
"PluginBrowser"
|
||||
])
|
||||
self._physics = None
|
||||
self._volume = None
|
||||
|
@ -29,7 +29,8 @@ class CuraStackBuilder:
|
||||
return None
|
||||
|
||||
machine_definition = definitions[0]
|
||||
generated_name = registry.createUniqueName("machine", "", machine_definition.name, machine_definition.name)
|
||||
|
||||
generated_name = registry.createUniqueName("machine", "", name, machine_definition.name)
|
||||
# Make sure the new name does not collide with any definition or (quality) profile
|
||||
# createUniqueName() only looks at other stacks, but not at definitions or quality profiles
|
||||
# Note that we don't go for uniqueName() immediately because that function matches with ignore_case set to true
|
||||
@ -44,13 +45,7 @@ class CuraStackBuilder:
|
||||
variant = "default",
|
||||
)
|
||||
|
||||
# after creating a global stack can be set custom defined name
|
||||
if name != generated_name:
|
||||
name = registry.createUniqueName("machine", "", name, machine_definition.name)
|
||||
if registry.findContainers(id = name):
|
||||
name = registry.uniqueName(name)
|
||||
|
||||
new_global_stack.setName(name)
|
||||
new_global_stack.setName(generated_name)
|
||||
|
||||
for extruder_definition in registry.findDefinitionContainers(machine = machine_definition.id):
|
||||
position = extruder_definition.getMetaDataEntry("position", None)
|
||||
|
@ -222,10 +222,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
elif container_type == "definition_changes":
|
||||
definition_name = instance_container.getName()
|
||||
num_settings_overriden_by_definition_changes += len(instance_container._instances)
|
||||
# Check if definition changes already exists.
|
||||
definition_changes = self._container_registry.findInstanceContainers(id = container_id)
|
||||
containers_found_dict["definition_changes"] = True
|
||||
# Check if there is any difference the loaded settings from the project file and the settings in Cura.
|
||||
if definition_changes:
|
||||
containers_found_dict["definition_changes"] = True
|
||||
# Check if there really is a conflict by comparing the values
|
||||
if definition_changes[0] != instance_container:
|
||||
definition_changes_conflict = True
|
||||
elif container_type == "quality":
|
||||
@ -357,7 +359,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
# - new: create a new container
|
||||
# - override: override the existing container
|
||||
# - None: There is no conflict, which means containers with the same IDs may or may not be there already.
|
||||
# If there is an existing container, there is no conflict between the them, and default to "override"
|
||||
# If there is an existing container, there is no conflict between them, and default to "override"
|
||||
# If there is no existing container, default to "new"
|
||||
#
|
||||
# Default values
|
||||
@ -600,7 +602,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
||||
if self._resolve_strategies["machine"] == "new":
|
||||
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
|
||||
old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
|
||||
if old_extruder_id:
|
||||
# Note that in case of a quality_changes extruder means the definition id of the extruder stack
|
||||
# For the user settings, it means the actual extruder stack id it's assigned to.
|
||||
if old_extruder_id and old_extruder_id in extruder_stack_id_map:
|
||||
new_extruder_id = extruder_stack_id_map[old_extruder_id]
|
||||
instance_container.setMetaDataEntry("extruder", new_extruder_id)
|
||||
|
||||
|
@ -233,13 +233,15 @@ class WorkspaceDialog(QObject):
|
||||
self._result["quality_changes"] = None
|
||||
if "definition_changes" in self._result and not self._has_definition_changes_conflict:
|
||||
self._result["definition_changes"] = None
|
||||
|
||||
# If the machine needs to be re-created, the definition_changes should also be re-created.
|
||||
if "machine" in self._result and self._result["machine"] == "new" and self._result["definition_changes"] is None:
|
||||
self._result["definition_changes"] = "new"
|
||||
|
||||
if "material" in self._result and not self._has_material_conflict:
|
||||
self._result["material"] = None
|
||||
|
||||
# If the machine needs to be re-created, the definition_changes should also be re-created.
|
||||
# If the machine strategy is None, it means that there is no name conflict with existing ones. In this case
|
||||
# new definitions changes are created
|
||||
if "machine" in self._result and self._result["machine"] == "new" or self._result["machine"] is None and self._result["definition_changes"] is None:
|
||||
self._result["definition_changes"] = "new"
|
||||
|
||||
return self._result
|
||||
|
||||
def _createViewFromQML(self):
|
||||
|
@ -23,9 +23,9 @@ i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
class PluginBrowser(QObject, Extension):
|
||||
def __init__(self, parent = None):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent)
|
||||
self.addMenuItem(i18n_catalog.i18nc("@menuitem", "Browse plugins"), self.browsePlugins)
|
||||
|
||||
self._api_version = 1
|
||||
self._api_url = "http://software.ultimaker.com/cura/v%s/" % self._api_version
|
||||
|
||||
@ -92,6 +92,7 @@ class PluginBrowser(QObject, Extension):
|
||||
def isDownloading(self):
|
||||
return self._is_downloading
|
||||
|
||||
@pyqtSlot()
|
||||
def browsePlugins(self):
|
||||
self._createNetworkManager()
|
||||
self.requestPluginList()
|
||||
|
@ -50,7 +50,8 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
||||
self._api_prefix = api_prefix
|
||||
|
||||
self._gcode = None
|
||||
self._print_finished = True # _print_finsihed == False means we're halfway in a print
|
||||
self._print_finished = True # _print_finished == False means we're halfway in a print
|
||||
self._write_finished = True # _write_finished == False means we're currently sending a G-code file
|
||||
|
||||
self._use_gzip = True # Should we use g-zip compression before sending the data?
|
||||
|
||||
@ -650,7 +651,16 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
||||
# \param filter_by_machine Whether to filter MIME types by machine. This
|
||||
# is ignored.
|
||||
# \param kwargs Keyword arguments.
|
||||
def requestWrite(self, nodes, file_name = None, filter_by_machine = False, file_handler = None, **kwargs):
|
||||
def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs):
|
||||
|
||||
# Check if we're already writing
|
||||
if not self._write_finished:
|
||||
self._error_message = Message(
|
||||
i18n_catalog.i18nc("@info:status",
|
||||
"Sending new jobs (temporarily) blocked, still sending the previous print job."))
|
||||
self._error_message.show()
|
||||
return
|
||||
|
||||
if self._printer_state not in ["idle", ""]:
|
||||
self._error_message = Message(
|
||||
i18n_catalog.i18nc("@info:status", "Unable to start a new print job, printer is busy. Current printer status is %s.") % self._printer_state,
|
||||
@ -750,6 +760,9 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
||||
)
|
||||
return
|
||||
|
||||
# Indicate we're starting a new write action, is set back to True in the startPrint() method
|
||||
self._write_finished = False
|
||||
|
||||
self.startPrint()
|
||||
|
||||
def _configurationMismatchMessageCallback(self, button):
|
||||
@ -909,6 +922,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
||||
## Post request + data
|
||||
self._post_reply = self._manager.post(self._post_request, self._post_multi_part)
|
||||
self._post_reply.uploadProgress.connect(self._onUploadProgress)
|
||||
self._post_reply.finished.connect(self._onUploadFinished) # used to unblock new write actions
|
||||
|
||||
except IOError:
|
||||
self._progress_message.hide()
|
||||
@ -1245,6 +1259,10 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
|
||||
self._progress_message.setProgress(0)
|
||||
self._progress_message.hide()
|
||||
|
||||
## Allow new write actions (uploads) again when uploading is finished.
|
||||
def _onUploadFinished(self):
|
||||
self._write_finished = True
|
||||
|
||||
## Let the user decide if the hotends and/or material should be synced with the printer
|
||||
def materialHotendChangedMessage(self, callback):
|
||||
Application.getInstance().messageBox(i18n_catalog.i18nc("@window:title", "Sync with your printer"),
|
||||
|
@ -61,6 +61,9 @@ Item
|
||||
|
||||
property alias configureSettingVisibility: configureSettingVisibilityAction
|
||||
|
||||
property alias browsePlugins: browsePluginsAction
|
||||
property alias configurePlugins: configurePluginsAction
|
||||
|
||||
UM.I18nCatalog{id: catalog; name:"cura"}
|
||||
|
||||
Action
|
||||
@ -362,4 +365,18 @@ Item
|
||||
text: catalog.i18nc("@action:menu", "Configure setting visibility...");
|
||||
iconName: "configure"
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: browsePluginsAction
|
||||
text: catalog.i18nc("@action:menu", "Browse plugins...")
|
||||
iconName: "plugins_browse"
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: configurePluginsAction
|
||||
text: catalog.i18nc("@action:menu", "Installed plugins...");
|
||||
iconName: "plugins_configure"
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ UM.MainWindow
|
||||
id: sub_menu
|
||||
title: model.name;
|
||||
visible: actions != null
|
||||
enabled:actions != null
|
||||
enabled: actions != null
|
||||
Instantiator
|
||||
{
|
||||
model: actions
|
||||
@ -226,6 +226,15 @@ UM.MainWindow
|
||||
}
|
||||
}
|
||||
|
||||
Menu
|
||||
{
|
||||
id: plugin_menu
|
||||
title: catalog.i18nc("@title:menu menubar:toplevel", "P&lugins")
|
||||
|
||||
MenuItem { action: Cura.Actions.browsePlugins }
|
||||
MenuItem { action: Cura.Actions.configurePlugins }
|
||||
}
|
||||
|
||||
Menu
|
||||
{
|
||||
title: catalog.i18nc("@title:menu menubar:toplevel","P&references");
|
||||
@ -543,6 +552,30 @@ UM.MainWindow
|
||||
}
|
||||
}
|
||||
|
||||
// show the installed plugins page in the preferences dialog
|
||||
Connections
|
||||
{
|
||||
target: Cura.Actions.configurePlugins
|
||||
onTriggered:
|
||||
{
|
||||
preferences.visible = true
|
||||
preferences.setPage(5)
|
||||
}
|
||||
}
|
||||
|
||||
UM.ExtensionModel {
|
||||
id: curaExtensions
|
||||
}
|
||||
|
||||
// show the plugin browser dialog
|
||||
Connections
|
||||
{
|
||||
target: Cura.Actions.browsePlugins
|
||||
onTriggered: {
|
||||
curaExtensions.callExtensionMethod("Plugin Browser", "browsePlugins")
|
||||
}
|
||||
}
|
||||
|
||||
Timer
|
||||
{
|
||||
id: createProfileTimer
|
||||
|
@ -43,7 +43,7 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
Label {
|
||||
id: statusLabel
|
||||
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
|
||||
anchors.top: parent.top
|
||||
|
@ -114,7 +114,7 @@ Rectangle
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
Label {
|
||||
id: settingsModeLabel
|
||||
text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox","Print Setup disabled\nG-code files cannot be modified");
|
||||
anchors.left: parent.left
|
||||
|
@ -363,7 +363,7 @@ Column
|
||||
visible: !Cura.MachineManager.isCurrentSetupSupported
|
||||
}
|
||||
|
||||
Text {
|
||||
Label {
|
||||
id: materialInfoLabel
|
||||
wrapMode: Text.WordWrap
|
||||
text: catalog.i18nc("@label", "<a href='%1'>Check material compatibility</a>")
|
||||
|
@ -154,7 +154,7 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
id: qualityRowTitle
|
||||
text: catalog.i18nc("@label", "Layer Height")
|
||||
@ -171,11 +171,11 @@ Item
|
||||
{
|
||||
model: qualityModel
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2
|
||||
anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height / 2)
|
||||
color: (Cura.MachineManager.activeMachine != null && Cura.ProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
|
||||
text:
|
||||
{
|
||||
@ -194,13 +194,13 @@ Item
|
||||
// Make sure the text aligns correctly with each tick
|
||||
if (qualityModel.totalTicks == 0) {
|
||||
// If there is only one tick, align it centrally
|
||||
return ((base.width * 0.55) - width) / 2
|
||||
return parseInt(((base.width * 0.55) - width) / 2)
|
||||
} else 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)
|
||||
return parseInt((base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -310,7 +310,7 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
id: speedLabel
|
||||
anchors.top: speedSlider.bottom
|
||||
@ -322,7 +322,7 @@ Item
|
||||
color: UM.Theme.getColor("text")
|
||||
}
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
anchors.bottom: speedLabel.bottom
|
||||
anchors.left: speedSlider.left
|
||||
@ -333,7 +333,7 @@ Item
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
anchors.bottom: speedLabel.bottom
|
||||
anchors.right: speedSlider.right
|
||||
@ -360,7 +360,7 @@ Item
|
||||
|
||||
width: UM.Theme.getSize("sidebar").width * .45 - UM.Theme.getSize("sidebar_margin").width
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
id: infillLabel
|
||||
text: catalog.i18nc("@label", "Infill")
|
||||
@ -385,7 +385,7 @@ Item
|
||||
anchors.top: infillCellLeft.top
|
||||
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
|
||||
|
||||
Text {
|
||||
Label {
|
||||
id: selectedInfillRateText
|
||||
|
||||
//anchors.top: parent.top
|
||||
@ -482,7 +482,7 @@ Item
|
||||
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2
|
||||
anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height / 2)
|
||||
|
||||
// we loop over all density icons and only show the one that has the current density and steps
|
||||
Repeater
|
||||
@ -533,7 +533,7 @@ Item
|
||||
property alias _hovered: enableGradualInfillMouseArea.containsMouse
|
||||
|
||||
anchors.top: infillSlider.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 2 // closer to slider since it belongs to the same category
|
||||
anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height / 2) // closer to slider since it belongs to the same category
|
||||
anchors.left: infillCellRight.left
|
||||
|
||||
style: UM.Theme.styles.checkbox
|
||||
@ -563,10 +563,10 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
Label {
|
||||
id: gradualInfillLabel
|
||||
anchors.left: enableGradualInfillCheckBox.right
|
||||
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width / 2
|
||||
anchors.leftMargin: parseInt(UM.Theme.getSize("sidebar_margin").width / 2)
|
||||
text: catalog.i18nc("@label", "Enable gradual")
|
||||
font: UM.Theme.getFont("default")
|
||||
color: UM.Theme.getColor("text")
|
||||
@ -621,13 +621,13 @@ Item
|
||||
//
|
||||
// Enable support
|
||||
//
|
||||
Text
|
||||
Label
|
||||
{
|
||||
id: enableSupportLabel
|
||||
visible: enableSupportCheckBox.visible
|
||||
|
||||
anchors.top: infillCellRight.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 1.5
|
||||
anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height * 1.5)
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
|
||||
anchors.verticalCenter: enableSupportCheckBox.verticalCenter
|
||||
@ -674,7 +674,7 @@ Item
|
||||
}
|
||||
}
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
id: supportExtruderLabel
|
||||
visible: supportExtruderCombobox.visible
|
||||
@ -750,7 +750,7 @@ Item
|
||||
|
||||
}
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
id: adhesionHelperLabel
|
||||
visible: adhesionCheckBox.visible
|
||||
@ -836,12 +836,12 @@ Item
|
||||
{
|
||||
id: tipsCell
|
||||
anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom)
|
||||
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
|
||||
anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height * 2)
|
||||
anchors.left: parent.left
|
||||
width: parent.width
|
||||
height: tipsText.contentHeight * tipsText.lineCount
|
||||
|
||||
Text
|
||||
Label
|
||||
{
|
||||
id: tipsText
|
||||
anchors.left: parent.left
|
||||
|
@ -43,7 +43,7 @@ UM.PointingRectangle {
|
||||
base.opacity = 0;
|
||||
}
|
||||
|
||||
Text {
|
||||
Label {
|
||||
id: label;
|
||||
anchors {
|
||||
top: parent.top;
|
||||
|
@ -17,10 +17,6 @@
|
||||
"size": 1.15,
|
||||
"family": "Open Sans"
|
||||
},
|
||||
"default_little_big": {
|
||||
"size": 1.17,
|
||||
"family": "Open Sans"
|
||||
},
|
||||
"default_bold": {
|
||||
"size": 1.15,
|
||||
"bold": true,
|
||||
|
Loading…
x
Reference in New Issue
Block a user