mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-06 13:34:01 -06:00
Merge remote-tracking branch 'origin/master' into add_42_43_version_upgrader
This commit is contained in:
commit
9f18ceda51
37 changed files with 380 additions and 249 deletions
|
@ -369,7 +369,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||
|
||||
elif job.getResult() == StartJobResult.ObjectSettingError:
|
||||
errors = {}
|
||||
for node in DepthFirstIterator(self._application.getController().getScene().getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for node in DepthFirstIterator(self._application.getController().getScene().getRoot()):
|
||||
stack = node.callDecoration("getStack")
|
||||
if not stack:
|
||||
continue
|
||||
|
@ -438,7 +438,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||
|
||||
if not self._application.getPreferences().getValue("general/auto_slice"):
|
||||
enable_timer = False
|
||||
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||
if node.callDecoration("isBlockSlicing"):
|
||||
enable_timer = False
|
||||
self.setState(BackendState.Disabled)
|
||||
|
@ -460,7 +460,7 @@ class CuraEngineBackend(QObject, Backend):
|
|||
## Return a dict with number of objects per build plate
|
||||
def _numObjectsPerBuildPlate(self) -> Dict[int, int]:
|
||||
num_objects = defaultdict(int) #type: Dict[int, int]
|
||||
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||
# Only count sliceable objects
|
||||
if node.callDecoration("isSliceable"):
|
||||
build_plate_number = node.callDecoration("getBuildPlateNumber")
|
||||
|
@ -548,10 +548,11 @@ class CuraEngineBackend(QObject, Backend):
|
|||
# Clear out any old gcode
|
||||
self._scene.gcode_dict = {} # type: ignore
|
||||
|
||||
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||
if node.callDecoration("getLayerData"):
|
||||
if not build_plate_numbers or node.callDecoration("getBuildPlateNumber") in build_plate_numbers:
|
||||
node.getParent().removeChild(node)
|
||||
# We can asume that all nodes have a parent as we're looping through the scene (and filter out root)
|
||||
cast(SceneNode, node.getParent()).removeChild(node)
|
||||
|
||||
def markSliceAll(self) -> None:
|
||||
for build_plate_number in range(self._application.getMultiBuildPlateModel().maxBuildPlate + 1):
|
||||
|
|
|
@ -11,6 +11,7 @@ import Arcus #For typing.
|
|||
|
||||
from UM.Job import Job
|
||||
from UM.Logger import Logger
|
||||
from UM.Scene.SceneNode import SceneNode
|
||||
from UM.Settings.ContainerStack import ContainerStack #For typing.
|
||||
from UM.Settings.SettingRelation import SettingRelation #For typing.
|
||||
|
||||
|
@ -150,7 +151,7 @@ class StartSliceJob(Job):
|
|||
|
||||
|
||||
# Don't slice if there is a per object setting with an error value.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||
if not isinstance(node, CuraSceneNode) or not node.isSelectable():
|
||||
continue
|
||||
|
||||
|
@ -160,15 +161,16 @@ class StartSliceJob(Job):
|
|||
|
||||
with self._scene.getSceneLock():
|
||||
# Remove old layer data.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||
if node.callDecoration("getLayerData") and node.callDecoration("getBuildPlateNumber") == self._build_plate_number:
|
||||
node.getParent().removeChild(node)
|
||||
# Singe we walk through all nodes in the scene, they always have a parent.
|
||||
cast(SceneNode, node.getParent()).removeChild(node)
|
||||
break
|
||||
|
||||
# Get the objects in their groups to print.
|
||||
object_groups = []
|
||||
if stack.getProperty("print_sequence", "value") == "one_at_a_time":
|
||||
for node in OneAtATimeIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
for node in OneAtATimeIterator(self._scene.getRoot()):
|
||||
temp_list = []
|
||||
|
||||
# Node can't be printed, so don't bother sending it.
|
||||
|
@ -183,7 +185,8 @@ class StartSliceJob(Job):
|
|||
children = node.getAllChildren()
|
||||
children.append(node)
|
||||
for child_node in children:
|
||||
if child_node.getMeshData() and child_node.getMeshData().getVertices() is not None:
|
||||
mesh_data = child_node.getMeshData()
|
||||
if mesh_data and mesh_data.getVertices() is not None:
|
||||
temp_list.append(child_node)
|
||||
|
||||
if temp_list:
|
||||
|
@ -194,8 +197,9 @@ class StartSliceJob(Job):
|
|||
else:
|
||||
temp_list = []
|
||||
has_printing_mesh = False
|
||||
for node in DepthFirstIterator(self._scene.getRoot()): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax.
|
||||
if node.callDecoration("isSliceable") and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||
mesh_data = node.getMeshData()
|
||||
if node.callDecoration("isSliceable") and mesh_data and mesh_data.getVertices() is not None:
|
||||
is_non_printing_mesh = bool(node.callDecoration("isNonPrintingMesh"))
|
||||
|
||||
# Find a reason not to add the node
|
||||
|
@ -210,7 +214,7 @@ class StartSliceJob(Job):
|
|||
|
||||
Job.yieldThread()
|
||||
|
||||
#If the list doesn't have any model with suitable settings then clean the list
|
||||
# If the list doesn't have any model with suitable settings then clean the list
|
||||
# otherwise CuraEngine will crash
|
||||
if not has_printing_mesh:
|
||||
temp_list.clear()
|
||||
|
@ -261,10 +265,14 @@ class StartSliceJob(Job):
|
|||
|
||||
for group in filtered_object_groups:
|
||||
group_message = self._slice_message.addRepeatedMessage("object_lists")
|
||||
if group[0].getParent() is not None and group[0].getParent().callDecoration("isGroup"):
|
||||
self._handlePerObjectSettings(group[0].getParent(), group_message)
|
||||
parent = group[0].getParent()
|
||||
if parent is not None and parent.callDecoration("isGroup"):
|
||||
self._handlePerObjectSettings(cast(CuraSceneNode, parent), group_message)
|
||||
|
||||
for object in group:
|
||||
mesh_data = object.getMeshData()
|
||||
if mesh_data is None:
|
||||
continue
|
||||
rot_scale = object.getWorldTransformation().getTransposed().getData()[0:3, 0:3]
|
||||
translate = object.getWorldTransformation().getData()[:3, 3]
|
||||
|
||||
|
@ -288,7 +296,7 @@ class StartSliceJob(Job):
|
|||
|
||||
obj.vertices = flat_verts
|
||||
|
||||
self._handlePerObjectSettings(object, obj)
|
||||
self._handlePerObjectSettings(cast(CuraSceneNode, object), obj)
|
||||
|
||||
Job.yieldThread()
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ class CuraProfileReader(ProfileReader):
|
|||
profile = InstanceContainer(profile_id)
|
||||
profile.setMetaDataEntry("type", "quality_changes")
|
||||
try:
|
||||
profile.deserialize(serialized)
|
||||
profile.deserialize(serialized, file_name = profile_id)
|
||||
except ContainerFormatError as e:
|
||||
Logger.log("e", "Error in the format of a container: %s", str(e))
|
||||
return None
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
# Cura PostProcessingPlugin
|
||||
# Author: Amanda de Castilho
|
||||
# Date: August 28, 2018
|
||||
# Modified: November 16, 2018 by Joshua Pope-Lewis
|
||||
|
||||
# Description: This plugin inserts a line at the start of each layer,
|
||||
# M117 - displays the filename and layer height to the LCD
|
||||
# Alternatively, user can override the filename to display alt text + layer height
|
||||
# Description: This plugin shows custom messages about your print on the Status bar...
|
||||
# Please look at the 3 options
|
||||
# - Scolling (SCROLL_LONG_FILENAMES) if enabled in Marlin and you arent printing a small item select this option.
|
||||
# - Name: By default it will use the name generated by Cura (EG: TT_Test_Cube) - Type a custom name in here
|
||||
# - Max Layer: Enabling this will show how many layers are in the entire print (EG: Layer 1 of 265!)
|
||||
|
||||
from ..Script import Script
|
||||
from UM.Application import Application
|
||||
|
@ -15,35 +18,72 @@ class DisplayFilenameAndLayerOnLCD(Script):
|
|||
|
||||
def getSettingDataString(self):
|
||||
return """{
|
||||
"name": "Display filename and layer on LCD",
|
||||
"name": "Display Filename And Layer On LCD",
|
||||
"key": "DisplayFilenameAndLayerOnLCD",
|
||||
"metadata": {},
|
||||
"version": 2,
|
||||
"settings":
|
||||
{
|
||||
"scroll":
|
||||
{
|
||||
"label": "Scroll enabled/Small layers?",
|
||||
"description": "If SCROLL_LONG_FILENAMES is enabled select this setting however, if the model is small disable this setting!",
|
||||
"type": "bool",
|
||||
"default_value": false
|
||||
},
|
||||
"name":
|
||||
{
|
||||
"label": "text to display:",
|
||||
"label": "Text to display:",
|
||||
"description": "By default the current filename will be displayed on the LCD. Enter text here to override the filename and display something else.",
|
||||
"type": "str",
|
||||
"default_value": ""
|
||||
},
|
||||
"startNum":
|
||||
{
|
||||
"label": "Initial layer number:",
|
||||
"description": "Choose which number you prefer for the initial layer, 0 or 1",
|
||||
"type": "int",
|
||||
"default_value": 0,
|
||||
"minimum_value": 0,
|
||||
"maximum_value": 1
|
||||
},
|
||||
"maxlayer":
|
||||
{
|
||||
"label": "Display max layer?:",
|
||||
"description": "Display how many layers are in the entire print on status bar?",
|
||||
"type": "bool",
|
||||
"default_value": true
|
||||
}
|
||||
}
|
||||
}"""
|
||||
|
||||
def execute(self, data):
|
||||
max_layer = 0
|
||||
if self.getSettingValueByKey("name") != "":
|
||||
name = self.getSettingValueByKey("name")
|
||||
else:
|
||||
name = Application.getInstance().getPrintInformation().jobName
|
||||
lcd_text = "M117 " + name + " layer "
|
||||
i = 0
|
||||
name = Application.getInstance().getPrintInformation().jobName
|
||||
if not self.getSettingValueByKey("scroll"):
|
||||
if self.getSettingValueByKey("maxlayer"):
|
||||
lcd_text = "M117 Layer "
|
||||
else:
|
||||
lcd_text = "M117 Printing Layer "
|
||||
else:
|
||||
lcd_text = "M117 Printing " + name + " - Layer "
|
||||
i = self.getSettingValueByKey("startNum")
|
||||
for layer in data:
|
||||
display_text = lcd_text + str(i)
|
||||
display_text = lcd_text + str(i) + " " + name
|
||||
layer_index = data.index(layer)
|
||||
lines = layer.split("\n")
|
||||
for line in lines:
|
||||
if line.startswith(";LAYER_COUNT:"):
|
||||
max_layer = line
|
||||
max_layer = max_layer.split(":")[1]
|
||||
if line.startswith(";LAYER:"):
|
||||
if self.getSettingValueByKey("maxlayer"):
|
||||
display_text = display_text + " of " + max_layer
|
||||
else:
|
||||
display_text = display_text + "!"
|
||||
line_index = lines.index(line)
|
||||
lines.insert(line_index + 1, display_text)
|
||||
i += 1
|
||||
|
|
|
@ -128,9 +128,26 @@ class Stretcher():
|
|||
onestep = GCodeStep(0, in_relative_movement)
|
||||
onestep.copyPosFrom(current)
|
||||
elif _getValue(line, "G") == 1:
|
||||
last_x = current.step_x
|
||||
last_y = current.step_y
|
||||
last_z = current.step_z
|
||||
last_e = current.step_e
|
||||
current.readStep(line)
|
||||
onestep = GCodeStep(1, in_relative_movement)
|
||||
onestep.copyPosFrom(current)
|
||||
if (current.step_x == last_x and current.step_y == last_y and
|
||||
current.step_z == last_z and current.step_e != last_e
|
||||
):
|
||||
# It's an extruder only move. Preserve it rather than process it as an
|
||||
# extruded move. Otherwise, the stretched output might contain slight
|
||||
# motion in X and Y in addition to E. This can cause problems with
|
||||
# firmwares that implement pressure advance.
|
||||
onestep = GCodeStep(-1, in_relative_movement)
|
||||
onestep.copyPosFrom(current)
|
||||
# Rather than copy the original line, write a new one with consistent
|
||||
# extruder coordinates
|
||||
onestep.comment = "G1 F{} E{}".format(onestep.step_f, onestep.step_e)
|
||||
else:
|
||||
onestep = GCodeStep(1, in_relative_movement)
|
||||
onestep.copyPosFrom(current)
|
||||
|
||||
# end of relative movement
|
||||
elif _getValue(line, "G") == 90:
|
||||
|
|
|
@ -218,10 +218,10 @@ class SimulationView(CuraView):
|
|||
if theme is not None:
|
||||
self._ghost_shader.setUniformValue("u_color", Color(*theme.getColor("layerview_ghost").getRgb()))
|
||||
|
||||
for node in DepthFirstIterator(scene.getRoot()): # type: ignore
|
||||
for node in DepthFirstIterator(scene.getRoot()):
|
||||
# We do not want to render ConvexHullNode as it conflicts with the bottom layers.
|
||||
# However, it is somewhat relevant when the node is selected, so do render it then.
|
||||
if type(node) is ConvexHullNode and not Selection.isSelected(node.getWatchedNode()):
|
||||
if type(node) is ConvexHullNode and not Selection.isSelected(cast(ConvexHullNode, node).getWatchedNode()):
|
||||
continue
|
||||
|
||||
if not node.render(renderer):
|
||||
|
@ -572,14 +572,14 @@ class SimulationView(CuraView):
|
|||
self._current_layer_jumps = job.getResult().get("jumps")
|
||||
self._controller.getScene().sceneChanged.emit(self._controller.getScene().getRoot())
|
||||
|
||||
self._top_layers_job = None # type: Optional["_CreateTopLayersJob"]
|
||||
self._top_layers_job = None
|
||||
|
||||
def _updateWithPreferences(self) -> None:
|
||||
self._solid_layers = int(Application.getInstance().getPreferences().getValue("view/top_layer_count"))
|
||||
self._only_show_top_layers = bool(Application.getInstance().getPreferences().getValue("view/only_show_top_layers"))
|
||||
self._compatibility_mode = self._evaluateCompatibilityMode()
|
||||
|
||||
self.setSimulationViewType(int(float(Application.getInstance().getPreferences().getValue("layerview/layer_view_type"))));
|
||||
self.setSimulationViewType(int(float(Application.getInstance().getPreferences().getValue("layerview/layer_view_type"))))
|
||||
|
||||
for extruder_nr, extruder_opacity in enumerate(Application.getInstance().getPreferences().getValue("layerview/extruder_opacities").split("|")):
|
||||
try:
|
||||
|
|
|
@ -48,32 +48,32 @@ Window
|
|||
ToolboxLoadingPage
|
||||
{
|
||||
id: viewLoading
|
||||
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "loading"
|
||||
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "loading"
|
||||
}
|
||||
ToolboxErrorPage
|
||||
{
|
||||
id: viewErrored
|
||||
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "errored"
|
||||
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "errored"
|
||||
}
|
||||
ToolboxDownloadsPage
|
||||
{
|
||||
id: viewDownloads
|
||||
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "overview"
|
||||
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "overview"
|
||||
}
|
||||
ToolboxDetailPage
|
||||
{
|
||||
id: viewDetail
|
||||
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "detail"
|
||||
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "detail"
|
||||
}
|
||||
ToolboxAuthorPage
|
||||
{
|
||||
id: viewAuthor
|
||||
visible: toolbox.viewCategory != "installed" && toolbox.viewPage == "author"
|
||||
visible: toolbox.viewCategory !== "installed" && toolbox.viewPage === "author"
|
||||
}
|
||||
ToolboxInstalledPage
|
||||
{
|
||||
id: installedPluginList
|
||||
visible: toolbox.viewCategory == "installed"
|
||||
visible: toolbox.viewCategory === "installed"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
Item
|
||||
|
@ -11,48 +11,17 @@ Item
|
|||
id: base
|
||||
|
||||
property var packageData
|
||||
property var technicalDataSheetUrl:
|
||||
{
|
||||
var link = undefined
|
||||
if ("Technical Data Sheet" in packageData.links)
|
||||
{
|
||||
// HACK: This is the way the old API (used in 3.6-beta) used to do it. For safety it's still here,
|
||||
// but it can be removed over time.
|
||||
link = packageData.links["Technical Data Sheet"]
|
||||
}
|
||||
else if ("technicalDataSheet" in packageData.links)
|
||||
{
|
||||
link = packageData.links["technicalDataSheet"]
|
||||
}
|
||||
return link
|
||||
}
|
||||
property var safetyDataSheetUrl:
|
||||
{
|
||||
var sds_name = "safetyDataSheet"
|
||||
return (sds_name in packageData.links) ? packageData.links[sds_name] : undefined
|
||||
}
|
||||
property var printingGuidelinesUrl:
|
||||
{
|
||||
var pg_name = "printingGuidelines"
|
||||
return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
|
||||
}
|
||||
property var technicalDataSheetUrl: packageData.links.technicalDataSheet
|
||||
property var safetyDataSheetUrl: packageData.links.safetyDataSheet
|
||||
property var printingGuidelinesUrl: packageData.links.printingGuidelines
|
||||
property var materialWebsiteUrl: packageData.links.website
|
||||
|
||||
property var materialWebsiteUrl:
|
||||
{
|
||||
var pg_name = "website"
|
||||
return (pg_name in packageData.links) ? packageData.links[pg_name] : undefined
|
||||
}
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
height: visible ? childrenRect.height : 0
|
||||
height: childrenRect.height
|
||||
onVisibleChanged: packageData.type === "material" && (compatibilityItem.visible || dataSheetLinks.visible)
|
||||
|
||||
visible: packageData.type == "material" &&
|
||||
(packageData.has_configs || technicalDataSheetUrl !== undefined ||
|
||||
safetyDataSheetUrl !== undefined || printingGuidelinesUrl !== undefined ||
|
||||
materialWebsiteUrl !== undefined)
|
||||
|
||||
Item
|
||||
Column
|
||||
{
|
||||
id: combatibilityItem
|
||||
id: compatibilityItem
|
||||
visible: packageData.has_configs
|
||||
width: parent.width
|
||||
// This is a bit of a hack, but the whole QML is pretty messy right now. This needs a big overhaul.
|
||||
|
@ -61,7 +30,6 @@ Item
|
|||
Label
|
||||
{
|
||||
id: heading
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
text: catalog.i18nc("@label", "Compatibility")
|
||||
wrapMode: Text.WordWrap
|
||||
|
@ -73,8 +41,6 @@ Item
|
|||
TableView
|
||||
{
|
||||
id: table
|
||||
anchors.top: heading.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height
|
||||
width: parent.width
|
||||
frameVisible: false
|
||||
|
||||
|
@ -155,32 +121,32 @@ Item
|
|||
TableViewColumn
|
||||
{
|
||||
role: "machine"
|
||||
title: "Machine"
|
||||
title: catalog.i18nc("@label:table_header", "Machine")
|
||||
width: Math.floor(table.width * 0.25)
|
||||
delegate: columnTextDelegate
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
role: "print_core"
|
||||
title: "Print Core"
|
||||
title: catalog.i18nc("@label:table_header", "Print Core")
|
||||
width: Math.floor(table.width * 0.2)
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
role: "build_plate"
|
||||
title: "Build Plate"
|
||||
title: catalog.i18nc("@label:table_header", "Build Plate")
|
||||
width: Math.floor(table.width * 0.225)
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
role: "support_material"
|
||||
title: "Support"
|
||||
title: catalog.i18nc("@label:table_header", "Support")
|
||||
width: Math.floor(table.width * 0.225)
|
||||
}
|
||||
TableViewColumn
|
||||
{
|
||||
role: "quality"
|
||||
title: "Quality"
|
||||
title: catalog.i18nc("@label:table_header", "Quality")
|
||||
width: Math.floor(table.width * 0.1)
|
||||
}
|
||||
}
|
||||
|
@ -188,13 +154,14 @@ Item
|
|||
|
||||
Label
|
||||
{
|
||||
id: data_sheet_links
|
||||
anchors.top: combatibilityItem.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height / 2
|
||||
id: dataSheetLinks
|
||||
anchors.top: compatibilityItem.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("narrow_margin").height
|
||||
visible: base.technicalDataSheetUrl !== undefined ||
|
||||
base.safetyDataSheetUrl !== undefined || base.printingGuidelinesUrl !== undefined ||
|
||||
base.materialWebsiteUrl !== undefined
|
||||
height: visible ? contentHeight : 0
|
||||
base.safetyDataSheetUrl !== undefined ||
|
||||
base.printingGuidelinesUrl !== undefined ||
|
||||
base.materialWebsiteUrl !== undefined
|
||||
|
||||
text:
|
||||
{
|
||||
var result = ""
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import UM 1.1 as UM
|
||||
|
||||
Item
|
||||
|
@ -11,10 +10,9 @@ Item
|
|||
id: detailList
|
||||
ScrollView
|
||||
{
|
||||
frameVisible: false
|
||||
clip: true
|
||||
anchors.fill: detailList
|
||||
style: UM.Theme.styles.scrollview
|
||||
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||
|
||||
Column
|
||||
{
|
||||
anchors
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
Item
|
||||
{
|
||||
id: tile
|
||||
width: detailList.width - UM.Theme.getSize("wide_margin").width
|
||||
height: normalData.height + compatibilityChart.height + 4 * UM.Theme.getSize("default_margin").height
|
||||
Item
|
||||
height: normalData.height + 2 * UM.Theme.getSize("wide_margin").height
|
||||
Column
|
||||
{
|
||||
id: normalData
|
||||
height: childrenRect.height
|
||||
|
||||
anchors
|
||||
{
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: controls.left
|
||||
rightMargin: UM.Theme.getSize("default_margin").width * 2 + UM.Theme.getSize("toolbox_loader").width
|
||||
top: parent.top
|
||||
rightMargin: UM.Theme.getSize("wide_margin").width
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
id: packageName
|
||||
width: parent.width
|
||||
height: UM.Theme.getSize("toolbox_property_label").height
|
||||
text: model.name
|
||||
|
@ -33,9 +33,9 @@ Item
|
|||
font: UM.Theme.getFont("medium_bold")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
anchors.top: packageName.bottom
|
||||
width: parent.width
|
||||
text: model.description
|
||||
maximumLineCount: 25
|
||||
|
@ -45,6 +45,12 @@ Item
|
|||
font: UM.Theme.getFont("default")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
ToolboxCompatibilityChart
|
||||
{
|
||||
width: parent.width
|
||||
packageData: model
|
||||
}
|
||||
}
|
||||
|
||||
ToolboxDetailTileActions
|
||||
|
@ -57,20 +63,12 @@ Item
|
|||
packageData: model
|
||||
}
|
||||
|
||||
ToolboxCompatibilityChart
|
||||
{
|
||||
id: compatibilityChart
|
||||
anchors.top: normalData.bottom
|
||||
width: normalData.width
|
||||
packageData: model
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
color: UM.Theme.getColor("lining")
|
||||
width: tile.width
|
||||
height: UM.Theme.getSize("default_lining").height
|
||||
anchors.top: compatibilityChart.bottom
|
||||
anchors.top: normalData.bottom
|
||||
anchors.topMargin: UM.Theme.getSize("default_margin").height + UM.Theme.getSize("wide_margin").height //Normal margin for spacing after chart, wide margin between items.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ Column
|
|||
// Don't allow installing while another download is running
|
||||
enabled: installed || (!(toolbox.isDownloading && toolbox.activePackage != model) && !loginRequired)
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
visible: !updateButton.visible && !installed// Don't show when the update button is visible
|
||||
visible: !updateButton.visible && !installed // Don't show when the update button is visible
|
||||
}
|
||||
|
||||
Cura.SecondaryButton
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls 2.3
|
||||
import UM 1.1 as UM
|
||||
|
||||
Column
|
||||
|
|
|
@ -1,25 +1,20 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
import UM 1.1 as UM
|
||||
|
||||
ScrollView
|
||||
{
|
||||
frameVisible: false
|
||||
clip: true
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
style: UM.Theme.styles.scrollview
|
||||
|
||||
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||
|
||||
Column
|
||||
{
|
||||
width: base.width
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
height: childrenRect.height
|
||||
|
||||
ToolboxDownloadsShowcase
|
||||
{
|
||||
|
@ -31,14 +26,14 @@ ScrollView
|
|||
{
|
||||
id: allPlugins
|
||||
width: parent.width
|
||||
heading: toolbox.viewCategory == "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
|
||||
model: toolbox.viewCategory == "material" ? toolbox.materialsAvailableModel : toolbox.pluginsAvailableModel
|
||||
heading: toolbox.viewCategory === "material" ? catalog.i18nc("@label", "Community Contributions") : catalog.i18nc("@label", "Community Plugins")
|
||||
model: toolbox.viewCategory === "material" ? toolbox.materialsAvailableModel : toolbox.pluginsAvailableModel
|
||||
}
|
||||
|
||||
ToolboxDownloadsGrid
|
||||
{
|
||||
id: genericMaterials
|
||||
visible: toolbox.viewCategory == "material"
|
||||
visible: toolbox.viewCategory === "material"
|
||||
width: parent.width
|
||||
heading: catalog.i18nc("@label", "Generic Materials")
|
||||
model: toolbox.materialsGenericModel
|
||||
|
|
|
@ -1,50 +1,50 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Dialogs 1.1
|
||||
import QtQuick.Window 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.1 as UM
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: page
|
||||
frameVisible: false
|
||||
clip: true
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
style: UM.Theme.styles.scrollview
|
||||
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||
|
||||
Column
|
||||
{
|
||||
width: page.width
|
||||
spacing: UM.Theme.getSize("default_margin").height
|
||||
padding: UM.Theme.getSize("wide_margin").width
|
||||
visible: toolbox.pluginsInstalledModel.items.length > 0
|
||||
height: childrenRect.height + 4 * UM.Theme.getSize("default_margin").height
|
||||
|
||||
anchors
|
||||
{
|
||||
right: parent.right
|
||||
left: parent.left
|
||||
margins: UM.Theme.getSize("default_margin").width
|
||||
top: parent.top
|
||||
}
|
||||
height: childrenRect.height + 2 * UM.Theme.getSize("wide_margin").height
|
||||
|
||||
Label
|
||||
{
|
||||
width: page.width
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: parent.padding
|
||||
}
|
||||
text: catalog.i18nc("@title:tab", "Plugins")
|
||||
color: UM.Theme.getColor("text_medium")
|
||||
font: UM.Theme.getFont("large")
|
||||
renderType: Text.NativeRendering
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: parent.padding
|
||||
}
|
||||
id: installedPlugins
|
||||
color: "transparent"
|
||||
width: parent.width
|
||||
height: childrenRect.height + UM.Theme.getSize("default_margin").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
|
@ -65,8 +65,15 @@ ScrollView
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Label
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: parent.padding
|
||||
}
|
||||
text: catalog.i18nc("@title:tab", "Materials")
|
||||
color: UM.Theme.getColor("text_medium")
|
||||
font: UM.Theme.getFont("medium")
|
||||
|
@ -75,9 +82,14 @@ ScrollView
|
|||
|
||||
Rectangle
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: parent.padding
|
||||
}
|
||||
id: installedMaterials
|
||||
color: "transparent"
|
||||
width: parent.width
|
||||
height: childrenRect.height + UM.Theme.getSize("default_margin").width
|
||||
border.color: UM.Theme.getColor("lining")
|
||||
border.width: UM.Theme.getSize("default_lining").width
|
||||
|
|
|
@ -41,7 +41,7 @@ Item
|
|||
Column
|
||||
{
|
||||
id: pluginInfo
|
||||
topPadding: Math.floor(UM.Theme.getSize("default_margin").height / 2)
|
||||
topPadding: UM.Theme.getSize("narrow_margin").height
|
||||
property var color: model.type === "plugin" && !isEnabled ? UM.Theme.getColor("lining") : UM.Theme.getColor("text")
|
||||
width: Math.floor(tileRow.width - (authorInfo.width + pluginActions.width + 2 * tileRow.spacing + ((disableButton.visible) ? disableButton.width + tileRow.spacing : 0)))
|
||||
Label
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Copyright (c) 2019 Ultimaker B.V.
|
||||
// Toolbox is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Controls.Styles 1.4
|
||||
import QtQuick 2.10
|
||||
import QtQuick.Controls 2.3
|
||||
|
||||
import UM 1.1 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
Item
|
||||
Cura.PrimaryButton
|
||||
{
|
||||
id: base
|
||||
id: button
|
||||
|
||||
property var active: false
|
||||
property var complete: false
|
||||
|
@ -25,43 +25,36 @@ Item
|
|||
|
||||
width: UM.Theme.getSize("toolbox_action_button").width
|
||||
height: UM.Theme.getSize("toolbox_action_button").height
|
||||
|
||||
Cura.PrimaryButton
|
||||
fixedWidthMode: true
|
||||
text:
|
||||
{
|
||||
id: button
|
||||
width: UM.Theme.getSize("toolbox_action_button").width
|
||||
height: UM.Theme.getSize("toolbox_action_button").height
|
||||
fixedWidthMode: true
|
||||
text:
|
||||
if (complete)
|
||||
{
|
||||
if (complete)
|
||||
{
|
||||
return completeLabel
|
||||
}
|
||||
else if (active)
|
||||
{
|
||||
return activeLabel
|
||||
}
|
||||
else
|
||||
{
|
||||
return readyLabel
|
||||
}
|
||||
return completeLabel
|
||||
}
|
||||
onClicked:
|
||||
else if (active)
|
||||
{
|
||||
if (complete)
|
||||
{
|
||||
completeAction()
|
||||
}
|
||||
else if (active)
|
||||
{
|
||||
activeAction()
|
||||
}
|
||||
else
|
||||
{
|
||||
readyAction()
|
||||
}
|
||||
return activeLabel
|
||||
}
|
||||
else
|
||||
{
|
||||
return readyLabel
|
||||
}
|
||||
busy: active
|
||||
}
|
||||
onClicked:
|
||||
{
|
||||
if (complete)
|
||||
{
|
||||
completeAction()
|
||||
}
|
||||
else if (active)
|
||||
{
|
||||
activeAction()
|
||||
}
|
||||
else
|
||||
{
|
||||
readyAction()
|
||||
}
|
||||
}
|
||||
busy: active
|
||||
}
|
||||
|
|
|
@ -655,8 +655,12 @@ class Toolbox(QObject, Extension):
|
|||
|
||||
# Check if the download was sucessfull
|
||||
if self._download_reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
|
||||
Logger.log("w", "Failed to download package. The following error was returned: %s", json.loads(bytes(self._download_reply.readAll()).decode("utf-8")))
|
||||
return
|
||||
try:
|
||||
Logger.log("w", "Failed to download package. The following error was returned: %s", json.loads(bytes(self._download_reply.readAll()).decode("utf-8")))
|
||||
except json.decoder.JSONDecodeError:
|
||||
Logger.logException("w", "Failed to download package and failed to parse a response from it")
|
||||
finally:
|
||||
return
|
||||
# Must not delete the temporary file on Windows
|
||||
self._temp_plugin_file = tempfile.NamedTemporaryFile(mode = "w+b", suffix = ".curapackage", delete = False)
|
||||
file_path = self._temp_plugin_file.name
|
||||
|
|
|
@ -243,10 +243,11 @@ Item
|
|||
enabled: !contextMenuButton.enabled
|
||||
}
|
||||
|
||||
MonitorInfoBlurb
|
||||
{
|
||||
id: contextMenuDisabledInfo
|
||||
text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
|
||||
target: contextMenuButton
|
||||
}
|
||||
// TODO: uncomment this tooltip as soon as the required firmware is released
|
||||
// MonitorInfoBlurb
|
||||
// {
|
||||
// id: contextMenuDisabledInfo
|
||||
// text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
|
||||
// target: contextMenuButton
|
||||
// }
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ Item
|
|||
mipmap: true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Item
|
||||
{
|
||||
|
@ -99,7 +99,7 @@ Item
|
|||
height: 18 * screenScaleFactor // TODO: Theme!
|
||||
width: parent.width
|
||||
radius: 2 * screenScaleFactor // TODO: Theme!
|
||||
|
||||
|
||||
Label
|
||||
{
|
||||
text: printer && printer.name ? printer.name : ""
|
||||
|
@ -202,12 +202,13 @@ Item
|
|||
enabled: !contextMenuButton.enabled
|
||||
}
|
||||
|
||||
MonitorInfoBlurb
|
||||
{
|
||||
id: contextMenuDisabledInfo
|
||||
text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
|
||||
target: contextMenuButton
|
||||
}
|
||||
// TODO: uncomment this tooltip as soon as the required firmware is released
|
||||
// MonitorInfoBlurb
|
||||
// {
|
||||
// id: contextMenuDisabledInfo
|
||||
// text: catalog.i18nc("@info", "Please update your printer's firmware to manage the queue remotely.")
|
||||
// target: contextMenuButton
|
||||
// }
|
||||
|
||||
CameraButton
|
||||
{
|
||||
|
@ -454,4 +455,4 @@ Item
|
|||
id: overrideConfirmationDialog
|
||||
printer: base.printer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,9 +174,13 @@ class CloudApiClient:
|
|||
model: Type[CloudApiClientModel],
|
||||
) -> None:
|
||||
def parse() -> None:
|
||||
# Don't try to parse the reply if we didn't get one
|
||||
if reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) is None:
|
||||
return
|
||||
status_code, response = self._parseReply(reply)
|
||||
self._anti_gc_callbacks.remove(parse)
|
||||
return self._parseModels(response, on_finished, model)
|
||||
self._parseModels(response, on_finished, model)
|
||||
return
|
||||
|
||||
self._anti_gc_callbacks.append(parse)
|
||||
reply.finished.connect(parse)
|
||||
|
|
|
@ -969,7 +969,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
machine_compatibility = cls._parseCompatibleValue(entry.text)
|
||||
|
||||
for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces):
|
||||
machine_id_list = product_id_map.get(identifier.get("product"), [])
|
||||
machine_id_list = product_id_map.get(identifier.get("product", ""), [])
|
||||
if not machine_id_list:
|
||||
machine_id_list = cls.getPossibleDefinitionIDsFromName(identifier.get("product"))
|
||||
|
||||
|
@ -1001,7 +1001,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
result_metadata.append(new_material_metadata)
|
||||
|
||||
buildplates = machine.iterfind("./um:buildplate", cls.__namespaces)
|
||||
buildplate_map = {} # type: Dict[str, Dict[str, bool]]
|
||||
buildplate_map = {} # type: Dict[str, Dict[str, bool]]
|
||||
buildplate_map["buildplate_compatible"] = {}
|
||||
buildplate_map["buildplate_recommended"] = {}
|
||||
for buildplate in buildplates:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue