mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-23 14:44:13 -06:00
WIP: Refactor Materials management page to use new Managers
This commit is contained in:
parent
aed0c124e9
commit
1e0a078af8
6 changed files with 1264 additions and 332 deletions
|
@ -54,7 +54,7 @@ from UM.Settings.SettingFunction import SettingFunction
|
|||
from cura.Settings.MachineNameValidator import MachineNameValidator
|
||||
from cura.Machines.Models.NozzleModel import NozzleModel
|
||||
from cura.Settings.ProfilesModel import ProfilesModel, NewQualityProfilesModel, NewCustomQualityProfilesModel
|
||||
from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel
|
||||
from cura.Settings.MaterialsModel import MaterialsModel, BrandMaterialsModel, GenericMaterialsModel, NewMaterialsModel
|
||||
from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel
|
||||
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
|
||||
from cura.Settings.UserProfilesModel import UserProfilesModel
|
||||
|
@ -944,6 +944,7 @@ class CuraApplication(QtApplication):
|
|||
|
||||
qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
|
||||
qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel")
|
||||
qmlRegisterType(NewMaterialsModel, "Cura", 1, 0, "NewMaterialsModel")
|
||||
|
||||
qmlRegisterSingletonType(NewQualityProfilesModel, "Cura", 1, 0, "NewQualityProfilesModel", self.getNewQualityProfileModel)
|
||||
qmlRegisterSingletonType(NewCustomQualityProfilesModel, "Cura", 1, 0, "NewCustomQualityProfilesModel", self.getNewCustomQualityProfilesModel)
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
# Copyright (c) 2017 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from typing import Any, List
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from typing import Any, List, Optional
|
||||
from PyQt5.QtCore import Qt, QObject
|
||||
|
||||
from UM.Logger import Logger
|
||||
from UM.Qt.ListModel import ListModel
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry #To listen for changes to the materials.
|
||||
from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel #We're extending this class.
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel
|
||||
|
||||
|
||||
def getAvailableMaterials():
|
||||
def getAvailableMaterials(extruder_position: Optional[int] = None):
|
||||
from cura.CuraApplication import CuraApplication
|
||||
machine_manager = CuraApplication.getInstance().getMachineManager()
|
||||
extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
||||
|
@ -19,18 +18,21 @@ def getAvailableMaterials():
|
|||
material_manager = CuraApplication.getInstance()._material_manager
|
||||
|
||||
active_global_stack = machine_manager._global_container_stack
|
||||
active_extruder_stack = extruder_manager.getActiveExtruderStack()
|
||||
extruder_stack = extruder_manager.getActiveExtruderStack()
|
||||
if extruder_position is not None:
|
||||
if active_global_stack is not None:
|
||||
extruder_stack = active_global_stack.extruders.get(str(extruder_position))
|
||||
|
||||
if active_global_stack is None or active_extruder_stack is None:
|
||||
if active_global_stack is None or extruder_stack is None:
|
||||
Logger.log("d", "Active global stack [%s] or extruder stack [%s] is None, setting material list to empty.",
|
||||
active_global_stack, active_extruder_stack)
|
||||
active_global_stack, extruder_stack)
|
||||
return
|
||||
|
||||
machine_definition_id = active_global_stack.definition.getId()
|
||||
variant_name = None
|
||||
if active_extruder_stack.variant.getId() != "empty_variant":
|
||||
variant_name = active_extruder_stack.variant.getName()
|
||||
diameter = active_extruder_stack.getProperty("material_diameter", "value")
|
||||
if extruder_stack.variant.getId() != "empty_variant":
|
||||
variant_name = extruder_stack.variant.getName()
|
||||
diameter = extruder_stack.getProperty("material_diameter", "value")
|
||||
|
||||
# Fetch the available materials (ContainerNode) for the current active machine and extruder setup.
|
||||
result_dict = material_manager.getAvailableMaterials(machine_definition_id, variant_name, diameter)
|
||||
|
@ -44,7 +46,7 @@ class BaseMaterialsModel(ListModel):
|
|||
BrandRole = Qt.UserRole + 4
|
||||
MaterialRole = Qt.UserRole + 5
|
||||
ColorRole = Qt.UserRole + 6
|
||||
ContainerNodeRole = Qt.UserRole + 6
|
||||
ContainerNodeRole = Qt.UserRole + 7
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
@ -184,6 +186,90 @@ class BrandMaterialsModel(ListModel):
|
|||
self.setItems(brand_item_list)
|
||||
|
||||
|
||||
#
|
||||
# This model is for the Material management page.
|
||||
#
|
||||
class NewMaterialsModel(ListModel):
|
||||
RootMaterialIdRole = Qt.UserRole + 1
|
||||
DisplayNameRole = Qt.UserRole + 2
|
||||
BrandRole = Qt.UserRole + 3
|
||||
MaterialTypeRole = Qt.UserRole + 4
|
||||
ColorNameRole = Qt.UserRole + 5
|
||||
ColorCodeRole = Qt.UserRole + 6
|
||||
ContainerNodeRole = Qt.UserRole + 7
|
||||
ContainerIdRole = Qt.UserRole + 8
|
||||
|
||||
DescriptionRole = Qt.UserRole + 9
|
||||
AdhesionInfoRole = Qt.UserRole + 10
|
||||
ApproximateDiameterRole = Qt.UserRole + 11
|
||||
GuidRole = Qt.UserRole + 12
|
||||
DensityRole = Qt.UserRole + 13
|
||||
DiameterRole = Qt.UserRole + 14
|
||||
|
||||
def __init__(self, parent = None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.addRoleName(self.RootMaterialIdRole, "root_material_id")
|
||||
self.addRoleName(self.DisplayNameRole, "name")
|
||||
self.addRoleName(self.BrandRole, "brand")
|
||||
self.addRoleName(self.MaterialTypeRole, "material")
|
||||
self.addRoleName(self.ColorNameRole, "color_name")
|
||||
self.addRoleName(self.ColorCodeRole, "color_code")
|
||||
self.addRoleName(self.ContainerNodeRole, "container_node")
|
||||
self.addRoleName(self.ContainerIdRole, "container_id")
|
||||
|
||||
self.addRoleName(self.DescriptionRole, "description")
|
||||
self.addRoleName(self.AdhesionInfoRole, "adhesion_info")
|
||||
self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter")
|
||||
self.addRoleName(self.GuidRole, "guid")
|
||||
self.addRoleName(self.DensityRole, "density")
|
||||
self.addRoleName(self.DiameterRole, "diameter")
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
machine_manager = CuraApplication.getInstance().getMachineManager()
|
||||
extruder_manager = CuraApplication.getInstance().getExtruderManager()
|
||||
material_manager = CuraApplication.getInstance()._material_manager
|
||||
|
||||
machine_manager.globalContainerChanged.connect(self._update)
|
||||
extruder_manager.activeExtruderChanged.connect(self._update)
|
||||
material_manager.materialsUpdated.connect(self._update)
|
||||
|
||||
self._update()
|
||||
|
||||
def _update(self):
|
||||
result_dict = getAvailableMaterials()
|
||||
if result_dict is None:
|
||||
self.setItems([])
|
||||
return
|
||||
|
||||
material_list = []
|
||||
for root_material_id, container_node in result_dict.items():
|
||||
keys_to_fetch = ("name",
|
||||
"brand",
|
||||
"material",
|
||||
"color_name",
|
||||
"color_code",
|
||||
"description",
|
||||
"adhesion_info",
|
||||
"approximate_diameter",)
|
||||
|
||||
item = {"root_material_id": container_node.metadata["base_file"],
|
||||
"container_node": container_node,
|
||||
"guid": container_node.metadata["GUID"],
|
||||
"container_id": container_node.metadata["id"],
|
||||
"density": container_node.metadata.get("properties", {}).get("density", ""),
|
||||
"diameter": container_node.metadata.get("properties", {}).get("diameter", ""),
|
||||
}
|
||||
|
||||
for key in keys_to_fetch:
|
||||
item[key] = container_node.metadata.get(key, "")
|
||||
|
||||
material_list.append(item)
|
||||
|
||||
material_list = sorted(material_list, key = lambda k: (k["brand"], k["name"]))
|
||||
self.setItems(material_list)
|
||||
|
||||
|
||||
## A model that shows a list of currently valid materials. Used by management page.
|
||||
class MaterialsModel(InstanceContainersModel):
|
||||
def __init__(self, parent = None):
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 1.3
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import UM 1.2 as UM
|
||||
|
@ -357,8 +357,18 @@ TabView
|
|||
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
|
||||
}
|
||||
|
||||
UM.ContainerPropertyProvider { id: materialPropertyProvider; containerId: base.containerId; watchedProperties: [ "value" ]; key: model.key }
|
||||
UM.ContainerPropertyProvider { id: machinePropertyProvider; containerId: Cura.MachineManager.activeDefinitionId; watchedProperties: [ "value" ]; key: model.key }
|
||||
UM.ContainerPropertyProvider {
|
||||
id: materialPropertyProvider
|
||||
containerId: base.containerId
|
||||
watchedProperties: [ "value" ]
|
||||
key: model.key
|
||||
}
|
||||
UM.ContainerPropertyProvider {
|
||||
id: machinePropertyProvider
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
watchedProperties: [ "value" ]
|
||||
key: model.key
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,55 +1,204 @@
|
|||
//Copyright (c) 2017 Ultimaker B.V.
|
||||
//Cura is released under the terms of the LGPLv3 or higher.
|
||||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Uranium is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.1
|
||||
import QtQuick.Controls 1.1
|
||||
import QtQuick.Dialogs 1.2
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
UM.ManagementPage
|
||||
|
||||
Item
|
||||
{
|
||||
id: base;
|
||||
id: base
|
||||
property var resetEnabled: false // Keep PreferencesDialog happy
|
||||
|
||||
title: catalog.i18nc("@title:tab", "Materials");
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
// Workaround to make sure all of the items are visible
|
||||
objectList.positionViewAtBeginning();
|
||||
Cura.NewMaterialsModel {
|
||||
id: materialsModel
|
||||
}
|
||||
|
||||
model: Cura.MaterialsModel
|
||||
{
|
||||
filter:
|
||||
{
|
||||
var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() }
|
||||
if(Cura.MachineManager.filterMaterialsByMachine)
|
||||
{
|
||||
result.definition = Cura.MachineManager.activeQualityDefinitionId;
|
||||
if(Cura.MachineManager.hasVariants)
|
||||
{
|
||||
result.variant_name = Cura.MachineManager.activeQualityVariantName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.definition = "fdmprinter";
|
||||
result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
|
||||
}
|
||||
return result
|
||||
Label {
|
||||
id: titleLabel
|
||||
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
margins: 5 * screenScaleFactor
|
||||
}
|
||||
|
||||
sectionProperty: "brand"
|
||||
font.pointSize: 18
|
||||
text: catalog.i18nc("@title:tab", "Materials")
|
||||
}
|
||||
|
||||
Row // Button Row
|
||||
{
|
||||
id: buttonRow
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: titleLabel.bottom
|
||||
}
|
||||
height: childrenRect.height
|
||||
|
||||
// Activate button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Activate")
|
||||
iconName: "list-activate"
|
||||
//enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
|
||||
enabled: true // TODO
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
Cura.MachineManager.setActiveMaterial(base.currentItem.id)
|
||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||
}
|
||||
}
|
||||
|
||||
// Create button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Create")
|
||||
iconName: "list-add"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// Duplicate button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Duplicate");
|
||||
iconName: "list-add"
|
||||
enabled: true //TODO
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// Remove button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Remove")
|
||||
iconName: "list-remove"
|
||||
//enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
|
||||
enabled: true // TODO
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// Import button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Import")
|
||||
iconName: "document-import"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
// TODO
|
||||
}
|
||||
visible: true
|
||||
}
|
||||
|
||||
// Export button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Export")
|
||||
iconName: "document-export"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
// TODO
|
||||
}
|
||||
enabled: currentItem != null
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentsItem
|
||||
|
||||
anchors {
|
||||
top: titleLabel.bottom
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
margins: 5 * screenScaleFactor
|
||||
bottomMargin: 0
|
||||
}
|
||||
|
||||
clip: true
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
anchors {
|
||||
top: buttonRow.bottom
|
||||
topMargin: UM.Theme.getSize("default_margin").height
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
SystemPalette { id: palette }
|
||||
|
||||
Label
|
||||
{
|
||||
id: captionLabel
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
}
|
||||
text: "TODO"
|
||||
width: materialScrollView.width
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: materialScrollView
|
||||
anchors {
|
||||
top: captionLabel.visible ? captionLabel.bottom : parent.top
|
||||
topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
parent: viewport
|
||||
anchors.fill: parent
|
||||
color: palette.light
|
||||
}
|
||||
|
||||
width: true ? (parent.width * 0.4) | 0 : parent.width
|
||||
|
||||
ListView
|
||||
{
|
||||
id: materialListView
|
||||
|
||||
model: materialsModel
|
||||
|
||||
section.property: "brand"
|
||||
section.criteria: ViewSection.FullString
|
||||
section.delegate: Rectangle
|
||||
{
|
||||
width: materialScrollView.width
|
||||
height: childrenRect.height
|
||||
color: palette.light
|
||||
|
||||
Label
|
||||
{
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width
|
||||
text: section
|
||||
font.bold: true
|
||||
color: palette.text
|
||||
}
|
||||
}
|
||||
|
||||
delegate: Rectangle
|
||||
{
|
||||
width: objectList.width;
|
||||
height: childrenRect.height;
|
||||
color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
|
||||
property bool isCurrentItem: ListView.isCurrentItem
|
||||
width: materialScrollView.width
|
||||
height: childrenRect.height
|
||||
color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase
|
||||
|
||||
Row
|
||||
{
|
||||
|
@ -59,162 +208,118 @@ UM.ManagementPage
|
|||
anchors.right: parent.right
|
||||
Rectangle
|
||||
{
|
||||
width: Math.round(parent.height * 0.8)
|
||||
height: Math.round(parent.height * 0.8)
|
||||
color: model.metadata.color_code
|
||||
border.color: isCurrentItem ? palette.highlightedText : palette.text;
|
||||
width: Math.floor(parent.height * 0.8)
|
||||
height: Math.floor(parent.height * 0.8)
|
||||
color: model.color_code
|
||||
border.color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Label
|
||||
{
|
||||
width: Math.round((parent.width * 0.3))
|
||||
text: model.metadata.material
|
||||
width: Math.floor((parent.width * 0.3))
|
||||
text: model.material
|
||||
elide: Text.ElideRight
|
||||
font.italic: model.id == activeId
|
||||
color: isCurrentItem ? palette.highlightedText : palette.text;
|
||||
font.italic: {
|
||||
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
||||
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
|
||||
return model.root_material_id == root_material_id; // TODO
|
||||
}
|
||||
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: (model.name != model.metadata.material) ? model.name : ""
|
||||
text: (model.name != model.material) ? model.name : ""
|
||||
elide: Text.ElideRight
|
||||
font.italic: model.id == activeId
|
||||
color: isCurrentItem ? palette.highlightedText : palette.text;
|
||||
font.italic: {
|
||||
const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
|
||||
const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
|
||||
return model.root_material_id == root_material_id; // TODO
|
||||
}
|
||||
color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent;
|
||||
onClicked:
|
||||
{
|
||||
forceActiveFocus();
|
||||
if(!parent.ListView.isCurrentItem)
|
||||
{
|
||||
parent.ListView.view.currentIndex = index;
|
||||
base.itemActivated();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activeId: Cura.MachineManager.activeMaterialId
|
||||
activeIndex: getIndexById(activeId)
|
||||
function getIndexById(material_id)
|
||||
{
|
||||
for(var i = 0; i < model.rowCount(); i++) {
|
||||
if (model.getItem(i).id == material_id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
scrollviewCaption:
|
||||
{
|
||||
var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
|
||||
if (Cura.MachineManager.hasVariants)
|
||||
{
|
||||
caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName;
|
||||
}
|
||||
return caption;
|
||||
}
|
||||
detailsVisible: true
|
||||
|
||||
section.property: "section"
|
||||
section.delegate: Label
|
||||
{
|
||||
text: section
|
||||
font.bold: true
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width;
|
||||
}
|
||||
|
||||
buttons: [
|
||||
|
||||
// Activate button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Activate")
|
||||
iconName: "list-activate";
|
||||
enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
Cura.MachineManager.setActiveMaterial(base.currentItem.id)
|
||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||
}
|
||||
},
|
||||
|
||||
// Create button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Create")
|
||||
iconName: "list-add"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
Cura.ContainerManager.createMaterial()
|
||||
}
|
||||
},
|
||||
|
||||
// Duplicate button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Duplicate");
|
||||
iconName: "list-add";
|
||||
enabled: base.currentItem != null
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
Cura.ContainerManager.duplicateOriginalMaterial(base.currentItem.id)
|
||||
}
|
||||
},
|
||||
|
||||
// Remove button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Remove")
|
||||
iconName: "list-remove"
|
||||
enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
confirmDialog.open()
|
||||
}
|
||||
},
|
||||
|
||||
// Import button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Import")
|
||||
iconName: "document-import"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
importDialog.open()
|
||||
}
|
||||
visible: true
|
||||
},
|
||||
|
||||
// Export button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Export")
|
||||
iconName: "document-export"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
exportDialog.open()
|
||||
}
|
||||
enabled: currentItem != null
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
Item {
|
||||
visible: base.currentItem != null
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
parent.ListView.view.currentIndex = model.index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentIndexChanged:
|
||||
{
|
||||
var model = materialsModel.getItem(currentIndex);
|
||||
materialDetailsView.containerId = model.container_id;
|
||||
|
||||
detailsPanel.updateMaterialPropertiesObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item
|
||||
{
|
||||
id: profileName
|
||||
id: detailsPanel
|
||||
|
||||
width: parent.width;
|
||||
height: childrenRect.height
|
||||
|
||||
Label { text: materialProperties.name; font: UM.Theme.getFont("large"); }
|
||||
anchors {
|
||||
left: materialScrollView.right
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
MaterialView
|
||||
function updateMaterialPropertiesObject()
|
||||
{
|
||||
var currentItem = materialsModel.getItem(materialListView.currentIndex);
|
||||
|
||||
materialProperties.name = currentItem.name;
|
||||
materialProperties.guid = currentItem.guid;
|
||||
|
||||
materialProperties.supplier = currentItem.brand ? currentItem.brand : "Unknown";
|
||||
materialProperties.material_type = currentItem.material ? currentItem.material : "Unknown";
|
||||
materialProperties.color_name = currentItem.color_name ? currentItem.color_name : "Yellow";
|
||||
materialProperties.color_code = currentItem.color_code ? currentItem.color_code : "yellow";
|
||||
|
||||
materialProperties.description = currentItem.description ? currentItem.description : "";
|
||||
materialProperties.adhesion_info = currentItem.adhesion_info ? currentItem.adhesion_info : "";
|
||||
|
||||
if(currentItem.properties != undefined && currentItem.properties != null)
|
||||
{
|
||||
materialProperties.density = currentItem.density ? currentItem.density : 0.0;
|
||||
materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0;
|
||||
materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
materialProperties.density = 0.0;
|
||||
materialProperties.diameter = 0.0;
|
||||
materialProperties.approximate_diameter = "0";
|
||||
}
|
||||
}
|
||||
|
||||
Item
|
||||
{
|
||||
anchors.fill: parent
|
||||
|
||||
Item // Material title Label
|
||||
{
|
||||
id: profileName
|
||||
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
|
||||
Label {
|
||||
text: materialProperties.name
|
||||
font: UM.Theme.getFont("large")
|
||||
}
|
||||
}
|
||||
|
||||
MaterialView // Material detailed information view below the title Label
|
||||
{
|
||||
id: materialDetailsView
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
|
@ -257,156 +362,7 @@ UM.ManagementPage
|
|||
property string description: "";
|
||||
property string adhesion_info: "";
|
||||
}
|
||||
|
||||
UM.ConfirmRemoveDialog
|
||||
{
|
||||
id: confirmDialog
|
||||
object: base.currentItem != null ? base.currentItem.name : ""
|
||||
onYes:
|
||||
{
|
||||
// A material container can actually be multiple items, so we need to find (and remove) all of them.
|
||||
var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file")
|
||||
if(base_file == "")
|
||||
{
|
||||
base_file = base.currentItem.id
|
||||
}
|
||||
var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID")
|
||||
// remove base container first, it otherwise triggers loading the base file while removing other containers
|
||||
var base_containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "id": base_file, "base_file": base_file, "type": "material"})
|
||||
for(var i in base_containers)
|
||||
{
|
||||
Cura.ContainerManager.removeContainer(base_containers[i]);
|
||||
}
|
||||
var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"})
|
||||
for(var i in containers)
|
||||
{
|
||||
Cura.ContainerManager.removeContainer(containers[i]);
|
||||
}
|
||||
if(base.objectList.currentIndex > 0)
|
||||
{
|
||||
base.objectList.currentIndex--;
|
||||
}
|
||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: importDialog;
|
||||
title: catalog.i18nc("@title:window", "Import Material");
|
||||
selectExisting: true;
|
||||
nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
|
||||
folder: CuraApplication.getDefaultPath("dialog_material_path")
|
||||
onAccepted:
|
||||
{
|
||||
var result = Cura.ContainerManager.importMaterialContainer(fileUrl)
|
||||
|
||||
messageDialog.title = catalog.i18nc("@title:window", "Import Material")
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Could not import material <filename>%1</filename>: <message>%2</message>").arg(fileUrl).arg(result.message)
|
||||
if(result.status == "success")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Information
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully imported material <filename>%1</filename>").arg(fileUrl)
|
||||
}
|
||||
else if(result.status == "duplicate")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Warning
|
||||
}
|
||||
else
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical
|
||||
}
|
||||
messageDialog.open()
|
||||
CuraApplication.setDefaultPath("dialog_material_path", folder)
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: exportDialog;
|
||||
title: catalog.i18nc("@title:window", "Export Material");
|
||||
selectExisting: false;
|
||||
nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
|
||||
folder: CuraApplication.getDefaultPath("dialog_material_path")
|
||||
onAccepted:
|
||||
{
|
||||
if(base.currentItem.metadata.base_file)
|
||||
{
|
||||
var result = Cura.ContainerManager.exportContainer(base.currentItem.metadata.base_file, selectedNameFilter, fileUrl)
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = Cura.ContainerManager.exportContainer(base.currentItem.id, selectedNameFilter, fileUrl)
|
||||
}
|
||||
|
||||
messageDialog.title = catalog.i18nc("@title:window", "Export Material")
|
||||
if(result.status == "error")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags <filename> and <message>!", "Failed to export material to <filename>%1</filename>: <message>%2</message>").arg(fileUrl).arg(result.message)
|
||||
messageDialog.open()
|
||||
}
|
||||
else if(result.status == "success")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Information
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully exported material to <filename>%1</filename>").arg(result.path)
|
||||
messageDialog.open()
|
||||
}
|
||||
CuraApplication.setDefaultPath("dialog_material_path", folder)
|
||||
}
|
||||
}
|
||||
|
||||
MessageDialog
|
||||
{
|
||||
id: messageDialog
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: materialDiameterProvider
|
||||
|
||||
containerStackId: Cura.ExtruderManager.activeExtruderStackId
|
||||
key: "material_diameter"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 5
|
||||
}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
SystemPalette { id: palette }
|
||||
}
|
||||
|
||||
onCurrentItemChanged:
|
||||
{
|
||||
if(currentItem == null)
|
||||
{
|
||||
return
|
||||
}
|
||||
materialProperties.name = currentItem.name;
|
||||
materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID");
|
||||
|
||||
if(currentItem.metadata != undefined && currentItem.metadata != null)
|
||||
{
|
||||
materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown";
|
||||
materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown";
|
||||
materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow";
|
||||
materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow";
|
||||
|
||||
materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : "";
|
||||
materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : "";
|
||||
|
||||
if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null)
|
||||
{
|
||||
materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : 0.0;
|
||||
materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : 0.0;
|
||||
materialProperties.approximate_diameter = currentItem.metadata.approximate_diameter ? currentItem.metadata.approximate_diameter : "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
materialProperties.density = 0.0;
|
||||
materialProperties.diameter = 0.0;
|
||||
materialProperties.approximate_diameter = "0";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
467
resources/qml/Preferences/OldMaterialView.qml
Normal file
467
resources/qml/Preferences/OldMaterialView.qml
Normal file
|
@ -0,0 +1,467 @@
|
|||
// Copyright (c) 2017 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
TabView
|
||||
{
|
||||
id: base
|
||||
|
||||
property QtObject properties;
|
||||
|
||||
property bool editingEnabled: false;
|
||||
property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€"
|
||||
property real firstColumnWidth: (width * 0.50) | 0
|
||||
property real secondColumnWidth: (width * 0.40) | 0
|
||||
property string containerId: ""
|
||||
property var materialPreferenceValues: UM.Preferences.getValue("cura/material_settings") ? JSON.parse(UM.Preferences.getValue("cura/material_settings")) : {}
|
||||
|
||||
property double spoolLength: calculateSpoolLength()
|
||||
property real costPerMeter: calculateCostPerMeter()
|
||||
|
||||
property bool reevaluateLinkedMaterials: false
|
||||
property string linkedMaterialNames:
|
||||
{
|
||||
if (reevaluateLinkedMaterials)
|
||||
{
|
||||
reevaluateLinkedMaterials = false;
|
||||
}
|
||||
if(!base.containerId || !base.editingEnabled)
|
||||
{
|
||||
return ""
|
||||
}
|
||||
var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.containerId);
|
||||
return linkedMaterials.join(", ");
|
||||
}
|
||||
|
||||
Tab
|
||||
{
|
||||
title: catalog.i18nc("@title", "Information")
|
||||
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
|
||||
ScrollView
|
||||
{
|
||||
id: scrollView
|
||||
anchors.fill: parent
|
||||
horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff
|
||||
flickableItem.flickableDirection: Flickable.VerticalFlick
|
||||
frameVisible: true
|
||||
|
||||
property real columnWidth: (viewport.width * 0.5 - UM.Theme.getSize("default_margin").width) | 0
|
||||
|
||||
Flow
|
||||
{
|
||||
id: containerGrid
|
||||
|
||||
x: UM.Theme.getSize("default_margin").width
|
||||
y: UM.Theme.getSize("default_lining").height
|
||||
|
||||
width: base.width
|
||||
property real rowHeight: textField.height + UM.Theme.getSize("default_lining").height
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
|
||||
ReadOnlyTextField
|
||||
{
|
||||
id: displayNameTextField;
|
||||
width: scrollView.columnWidth;
|
||||
text: properties.name;
|
||||
readOnly: !base.editingEnabled;
|
||||
onEditingFinished: base.updateMaterialDisplayName(properties.name, text)
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Brand") }
|
||||
ReadOnlyTextField
|
||||
{
|
||||
id: textField;
|
||||
width: scrollView.columnWidth;
|
||||
text: properties.supplier;
|
||||
readOnly: !base.editingEnabled;
|
||||
onEditingFinished: base.updateMaterialSupplier(properties.supplier, text)
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
|
||||
ReadOnlyTextField
|
||||
{
|
||||
width: scrollView.columnWidth;
|
||||
text: properties.material_type;
|
||||
readOnly: !base.editingEnabled;
|
||||
onEditingFinished: base.updateMaterialType(properties.material_type, text)
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
|
||||
Row {
|
||||
width: scrollView.columnWidth
|
||||
height: parent.rowHeight
|
||||
spacing: Math.floor(UM.Theme.getSize("default_margin").width / 2)
|
||||
|
||||
// color indicator square
|
||||
Rectangle {
|
||||
id: colorSelector
|
||||
color: properties.color_code
|
||||
|
||||
width: Math.floor(colorLabel.height * 0.75)
|
||||
height: Math.floor(colorLabel.height * 0.75)
|
||||
border.width: UM.Theme.getSize("default_lining").height
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
// open the color selection dialog on click
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: colorDialog.open()
|
||||
enabled: base.editingEnabled
|
||||
}
|
||||
}
|
||||
|
||||
// pretty color name text field
|
||||
ReadOnlyTextField {
|
||||
id: colorLabel;
|
||||
text: properties.color_name;
|
||||
readOnly: !base.editingEnabled
|
||||
onEditingFinished: base.setMetaDataEntry("color_name", properties.color_name, text)
|
||||
}
|
||||
|
||||
// popup dialog to select a new color
|
||||
// if successful it sets the properties.color_code value to the new color
|
||||
ColorDialog {
|
||||
id: colorDialog
|
||||
color: properties.color_code
|
||||
onAccepted: base.setMetaDataEntry("color_code", properties.color_code, color)
|
||||
}
|
||||
}
|
||||
|
||||
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
||||
|
||||
Label { width: parent.width; height: parent.rowHeight; font.bold: true; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Properties") }
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Density") }
|
||||
ReadOnlySpinBox
|
||||
{
|
||||
id: densitySpinBox
|
||||
width: scrollView.columnWidth
|
||||
value: properties.density
|
||||
decimals: 2
|
||||
suffix: " g/cm³"
|
||||
stepSize: 0.01
|
||||
readOnly: !base.editingEnabled
|
||||
|
||||
onEditingFinished: base.setMetaDataEntry("properties/density", properties.density, value)
|
||||
onValueChanged: updateCostPerMeter()
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Diameter") }
|
||||
ReadOnlySpinBox
|
||||
{
|
||||
id: diameterSpinBox
|
||||
width: scrollView.columnWidth
|
||||
value: properties.diameter
|
||||
decimals: 2
|
||||
suffix: " mm"
|
||||
stepSize: 0.01
|
||||
readOnly: !base.editingEnabled
|
||||
|
||||
onEditingFinished:
|
||||
{
|
||||
// This does not use a SettingPropertyProvider, because we need to make the change to all containers
|
||||
// which derive from the same base_file
|
||||
var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString();
|
||||
var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
|
||||
base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, Math.round(value).toString());
|
||||
base.setMetaDataEntry("properties/diameter", properties.diameter, value);
|
||||
var new_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
|
||||
if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter)
|
||||
{
|
||||
Cura.MaterialManager.showMaterialWarningMessage(base.containerId, old_diameter);
|
||||
}
|
||||
Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value);
|
||||
}
|
||||
onValueChanged: updateCostPerMeter()
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament Cost") }
|
||||
SpinBox
|
||||
{
|
||||
id: spoolCostSpinBox
|
||||
width: scrollView.columnWidth
|
||||
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
|
||||
prefix: base.currency + " "
|
||||
decimals: 2
|
||||
maximumValue: 100000000
|
||||
|
||||
onValueChanged: {
|
||||
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
|
||||
updateCostPerMeter()
|
||||
}
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
|
||||
SpinBox
|
||||
{
|
||||
id: spoolWeightSpinBox
|
||||
width: scrollView.columnWidth
|
||||
value: base.getMaterialPreferenceValue(properties.guid, "spool_weight")
|
||||
suffix: " g"
|
||||
stepSize: 100
|
||||
decimals: 0
|
||||
maximumValue: 10000
|
||||
|
||||
onValueChanged: {
|
||||
base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
|
||||
updateCostPerMeter()
|
||||
}
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
|
||||
Label
|
||||
{
|
||||
width: scrollView.columnWidth
|
||||
text: "~ %1 m".arg(Math.round(base.spoolLength))
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
height: parent.rowHeight
|
||||
}
|
||||
|
||||
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Cost per Meter") }
|
||||
Label
|
||||
{
|
||||
width: scrollView.columnWidth
|
||||
text: "~ %1 %2/m".arg(base.costPerMeter.toFixed(2)).arg(base.currency)
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
height: parent.rowHeight
|
||||
}
|
||||
|
||||
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height; visible: unlinkMaterialButton.visible }
|
||||
Label
|
||||
{
|
||||
width: 2 * scrollView.columnWidth
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
text: catalog.i18nc("@label", "This material is linked to %1 and shares some of its properties.").arg(base.linkedMaterialNames)
|
||||
wrapMode: Text.WordWrap
|
||||
visible: unlinkMaterialButton.visible
|
||||
}
|
||||
Button
|
||||
{
|
||||
id: unlinkMaterialButton
|
||||
text: catalog.i18nc("@label", "Unlink Material")
|
||||
visible: base.linkedMaterialNames != ""
|
||||
onClicked:
|
||||
{
|
||||
Cura.ContainerManager.unlinkMaterial(base.containerId)
|
||||
base.reevaluateLinkedMaterials = true
|
||||
}
|
||||
}
|
||||
|
||||
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
||||
|
||||
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Description") }
|
||||
|
||||
ReadOnlyTextArea
|
||||
{
|
||||
text: properties.description;
|
||||
width: 2 * scrollView.columnWidth
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
readOnly: !base.editingEnabled;
|
||||
|
||||
onEditingFinished: base.setMetaDataEntry("description", properties.description, text)
|
||||
}
|
||||
|
||||
Label { width: parent.width; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Adhesion Information") }
|
||||
|
||||
ReadOnlyTextArea
|
||||
{
|
||||
text: properties.adhesion_info;
|
||||
width: 2 * scrollView.columnWidth
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
readOnly: !base.editingEnabled;
|
||||
|
||||
onEditingFinished: base.setMetaDataEntry("adhesion_info", properties.adhesion_info, text)
|
||||
}
|
||||
|
||||
Item { width: parent.width; height: UM.Theme.getSize("default_margin").height }
|
||||
}
|
||||
|
||||
function updateCostPerMeter()
|
||||
{
|
||||
base.spoolLength = calculateSpoolLength(diameterSpinBox.value, densitySpinBox.value, spoolWeightSpinBox.value);
|
||||
base.costPerMeter = calculateCostPerMeter(spoolCostSpinBox.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tab
|
||||
{
|
||||
title: catalog.i18nc("@label", "Print settings")
|
||||
anchors
|
||||
{
|
||||
leftMargin: UM.Theme.getSize("default_margin").width
|
||||
topMargin: UM.Theme.getSize("default_margin").height
|
||||
bottomMargin: UM.Theme.getSize("default_margin").height
|
||||
rightMargin: 0
|
||||
}
|
||||
|
||||
ScrollView
|
||||
{
|
||||
anchors.fill: parent;
|
||||
|
||||
ListView
|
||||
{
|
||||
model: UM.SettingDefinitionsModel
|
||||
{
|
||||
containerId: Cura.MachineManager.activeDefinitionId
|
||||
visibilityHandler: Cura.MaterialSettingsVisibilityHandler { }
|
||||
expanded: ["*"]
|
||||
}
|
||||
|
||||
delegate: UM.TooltipArea
|
||||
{
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
text: model.description
|
||||
Label
|
||||
{
|
||||
id: label
|
||||
width: base.firstColumnWidth;
|
||||
height: spinBox.height + UM.Theme.getSize("default_lining").height
|
||||
text: model.label
|
||||
elide: Text.ElideRight
|
||||
verticalAlignment: Qt.AlignVCenter
|
||||
}
|
||||
ReadOnlySpinBox
|
||||
{
|
||||
id: spinBox
|
||||
anchors.left: label.right
|
||||
value: {
|
||||
if (!isNaN(parseFloat(materialPropertyProvider.properties.value)))
|
||||
{
|
||||
return parseFloat(materialPropertyProvider.properties.value);
|
||||
}
|
||||
if (!isNaN(parseFloat(machinePropertyProvider.properties.value)))
|
||||
{
|
||||
return parseFloat(machinePropertyProvider.properties.value);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
width: base.secondColumnWidth
|
||||
readOnly: !base.editingEnabled
|
||||
suffix: " " + model.unit
|
||||
maximumValue: 99999
|
||||
decimals: model.unit == "mm" ? 2 : 0
|
||||
|
||||
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
|
||||
}
|
||||
|
||||
UM.ContainerPropertyProvider { id: materialPropertyProvider; containerId: base.containerId; watchedProperties: [ "value" ]; key: model.key }
|
||||
UM.ContainerPropertyProvider { id: machinePropertyProvider; containerId: Cura.MachineManager.activeDefinitionId; watchedProperties: [ "value" ]; key: model.key }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateSpoolLength(diameter, density, spoolWeight)
|
||||
{
|
||||
if(!diameter)
|
||||
{
|
||||
diameter = properties.diameter;
|
||||
}
|
||||
if(!density)
|
||||
{
|
||||
density = properties.density;
|
||||
}
|
||||
if(!spoolWeight)
|
||||
{
|
||||
spoolWeight = base.getMaterialPreferenceValue(properties.guid, "spool_weight");
|
||||
}
|
||||
|
||||
if (diameter == 0 || density == 0 || spoolWeight == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
var area = Math.PI * Math.pow(diameter / 2, 2); // in mm2
|
||||
var volume = (spoolWeight / density); // in cm3
|
||||
return volume / area; // in m
|
||||
}
|
||||
|
||||
function calculateCostPerMeter(spoolCost)
|
||||
{
|
||||
if(!spoolCost)
|
||||
{
|
||||
spoolCost = base.getMaterialPreferenceValue(properties.guid, "spool_cost");
|
||||
}
|
||||
|
||||
if (spoolLength == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return spoolCost / spoolLength;
|
||||
}
|
||||
|
||||
// Tiny convenience function to check if a value really changed before trying to set it.
|
||||
function setMetaDataEntry(entry_name, old_value, new_value) {
|
||||
if (old_value != new_value) {
|
||||
Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value)
|
||||
// make sure the UI properties are updated as well since we don't re-fetch the entire model here
|
||||
// When the entry_name is something like properties/diameter, we take the last part of the entry_name
|
||||
var list = entry_name.split("/")
|
||||
var key = list[list.length - 1]
|
||||
properties[key] = new_value
|
||||
}
|
||||
}
|
||||
|
||||
function setMaterialPreferenceValue(material_guid, entry_name, new_value)
|
||||
{
|
||||
if(!(material_guid in materialPreferenceValues))
|
||||
{
|
||||
materialPreferenceValues[material_guid] = {};
|
||||
}
|
||||
if(entry_name in materialPreferenceValues[material_guid] && materialPreferenceValues[material_guid][entry_name] == new_value)
|
||||
{
|
||||
// value has not changed
|
||||
return
|
||||
}
|
||||
materialPreferenceValues[material_guid][entry_name] = new_value;
|
||||
|
||||
// store preference
|
||||
UM.Preferences.setValue("cura/material_settings", JSON.stringify(materialPreferenceValues));
|
||||
}
|
||||
|
||||
function getMaterialPreferenceValue(material_guid, entry_name)
|
||||
{
|
||||
if(material_guid in materialPreferenceValues && entry_name in materialPreferenceValues[material_guid])
|
||||
{
|
||||
return materialPreferenceValues[material_guid][entry_name];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// update the display name of the material
|
||||
function updateMaterialDisplayName (old_name, new_name) {
|
||||
|
||||
// don't change when new name is the same
|
||||
if (old_name == new_name) {
|
||||
return
|
||||
}
|
||||
|
||||
// update the values
|
||||
Cura.ContainerManager.setContainerName(base.containerId, new_name)
|
||||
materialProperties.name = new_name
|
||||
}
|
||||
|
||||
// update the type of the material
|
||||
function updateMaterialType (old_type, new_type) {
|
||||
base.setMetaDataEntry("material", old_type, new_type)
|
||||
materialProperties.material_type = new_type
|
||||
}
|
||||
|
||||
// update the supplier of the material
|
||||
function updateMaterialSupplier (old_supplier, new_supplier) {
|
||||
base.setMetaDataEntry("brand", old_supplier, new_supplier)
|
||||
materialProperties.supplier = new_supplier
|
||||
}
|
||||
}
|
412
resources/qml/Preferences/OldMaterialsPage.qml
Normal file
412
resources/qml/Preferences/OldMaterialsPage.qml
Normal file
|
@ -0,0 +1,412 @@
|
|||
//Copyright (c) 2017 Ultimaker B.V.
|
||||
//Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.8
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import UM 1.2 as UM
|
||||
import Cura 1.0 as Cura
|
||||
|
||||
|
||||
UM.ManagementPage
|
||||
{
|
||||
id: base
|
||||
title: catalog.i18nc("@title:tab", "Materials")
|
||||
|
||||
Component.onCompleted:
|
||||
{
|
||||
// Workaround to make sure all of the items are visible
|
||||
objectList.positionViewAtBeginning();
|
||||
}
|
||||
|
||||
model: Cura.MaterialsModel
|
||||
{
|
||||
filter:
|
||||
{
|
||||
var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() }
|
||||
if(Cura.MachineManager.filterMaterialsByMachine)
|
||||
{
|
||||
result.definition = Cura.MachineManager.activeQualityDefinitionId;
|
||||
if(Cura.MachineManager.hasVariants)
|
||||
{
|
||||
result.variant_name = Cura.MachineManager.activeQualityVariantName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.definition = "fdmprinter";
|
||||
result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
sectionProperty: "brand"
|
||||
}
|
||||
|
||||
delegate: Rectangle
|
||||
{
|
||||
width: objectList.width;
|
||||
height: childrenRect.height;
|
||||
color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
|
||||
property bool isCurrentItem: ListView.isCurrentItem
|
||||
|
||||
Row
|
||||
{
|
||||
spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||
anchors.right: parent.right
|
||||
Rectangle
|
||||
{
|
||||
width: Math.floor(parent.height * 0.8)
|
||||
height: Math.floor(parent.height * 0.8)
|
||||
color: model.metadata.color_code
|
||||
border.color: isCurrentItem ? palette.highlightedText : palette.text;
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Label
|
||||
{
|
||||
width: Math.floor((parent.width * 0.3))
|
||||
text: model.metadata.material
|
||||
elide: Text.ElideRight
|
||||
font.italic: model.id == activeId
|
||||
color: isCurrentItem ? palette.highlightedText : palette.text;
|
||||
}
|
||||
Label
|
||||
{
|
||||
text: (model.name != model.metadata.material) ? model.name : ""
|
||||
elide: Text.ElideRight
|
||||
font.italic: model.id == activeId
|
||||
color: isCurrentItem ? palette.highlightedText : palette.text;
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent;
|
||||
onClicked:
|
||||
{
|
||||
forceActiveFocus();
|
||||
if(!parent.ListView.isCurrentItem)
|
||||
{
|
||||
parent.ListView.view.currentIndex = index;
|
||||
base.itemActivated();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activeId: Cura.MachineManager.activeMaterialId
|
||||
activeIndex: getIndexById(activeId)
|
||||
function getIndexById(material_id)
|
||||
{
|
||||
for(var i = 0; i < model.rowCount(); i++) {
|
||||
if (model.getItem(i).id == material_id) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
scrollviewCaption:
|
||||
{
|
||||
var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
|
||||
if (Cura.MachineManager.hasVariants)
|
||||
{
|
||||
caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName;
|
||||
}
|
||||
return caption;
|
||||
}
|
||||
detailsVisible: true
|
||||
|
||||
section.property: "section"
|
||||
section.delegate: Label
|
||||
{
|
||||
text: section
|
||||
font.bold: true
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: UM.Theme.getSize("default_lining").width;
|
||||
}
|
||||
|
||||
buttons: [
|
||||
|
||||
// Activate button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Activate")
|
||||
iconName: "list-activate";
|
||||
enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
Cura.MachineManager.setActiveMaterial(base.currentItem.id)
|
||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||
}
|
||||
},
|
||||
|
||||
// Create button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Create")
|
||||
iconName: "list-add"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
Cura.ContainerManager.createMaterial()
|
||||
}
|
||||
},
|
||||
|
||||
// Duplicate button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Duplicate");
|
||||
iconName: "list-add";
|
||||
enabled: base.currentItem != null
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
Cura.ContainerManager.duplicateOriginalMaterial(base.currentItem.id)
|
||||
}
|
||||
},
|
||||
|
||||
// Remove button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Remove")
|
||||
iconName: "list-remove"
|
||||
enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
confirmDialog.open()
|
||||
}
|
||||
},
|
||||
|
||||
// Import button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Import")
|
||||
iconName: "document-import"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
importDialog.open()
|
||||
}
|
||||
visible: true
|
||||
},
|
||||
|
||||
// Export button
|
||||
Button {
|
||||
text: catalog.i18nc("@action:button", "Export")
|
||||
iconName: "document-export"
|
||||
onClicked: {
|
||||
forceActiveFocus()
|
||||
exportDialog.open()
|
||||
}
|
||||
enabled: currentItem != null
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
Item {
|
||||
visible: base.currentItem != null
|
||||
anchors.fill: parent
|
||||
|
||||
Item // Material title Label
|
||||
{
|
||||
id: profileName
|
||||
|
||||
width: parent.width;
|
||||
height: childrenRect.height
|
||||
|
||||
Label { text: materialProperties.name; font: UM.Theme.getFont("large"); }
|
||||
}
|
||||
|
||||
MaterialView // Material detailed information view below the title Label
|
||||
{
|
||||
anchors
|
||||
{
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: profileName.bottom
|
||||
topMargin: UM.Theme.getSize("default_margin").height
|
||||
bottom: parent.bottom
|
||||
}
|
||||
|
||||
editingEnabled: base.currentItem != null && !base.currentItem.readOnly
|
||||
|
||||
properties: materialProperties
|
||||
containerId: base.currentItem != null ? base.currentItem.id : ""
|
||||
|
||||
property alias pane: base
|
||||
}
|
||||
|
||||
QtObject
|
||||
{
|
||||
id: materialProperties
|
||||
|
||||
property string guid: "00000000-0000-0000-0000-000000000000"
|
||||
property string name: "Unknown";
|
||||
property string profile_type: "Unknown";
|
||||
property string supplier: "Unknown";
|
||||
property string material_type: "Unknown";
|
||||
|
||||
property string color_name: "Yellow";
|
||||
property color color_code: "yellow";
|
||||
|
||||
property real density: 0.0;
|
||||
property real diameter: 0.0;
|
||||
property string approximate_diameter: "0";
|
||||
|
||||
property real spool_cost: 0.0;
|
||||
property real spool_weight: 0.0;
|
||||
property real spool_length: 0.0;
|
||||
property real cost_per_meter: 0.0;
|
||||
|
||||
property string description: "";
|
||||
property string adhesion_info: "";
|
||||
}
|
||||
|
||||
UM.ConfirmRemoveDialog
|
||||
{
|
||||
id: confirmDialog
|
||||
object: base.currentItem != null ? base.currentItem.name : ""
|
||||
onYes:
|
||||
{
|
||||
// A material container can actually be multiple items, so we need to find (and remove) all of them.
|
||||
var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file")
|
||||
if(base_file == "")
|
||||
{
|
||||
base_file = base.currentItem.id
|
||||
}
|
||||
var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID")
|
||||
// remove base container first, it otherwise triggers loading the base file while removing other containers
|
||||
var base_containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "id": base_file, "base_file": base_file, "type": "material"})
|
||||
for(var i in base_containers)
|
||||
{
|
||||
Cura.ContainerManager.removeContainer(base_containers[i]);
|
||||
}
|
||||
var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"})
|
||||
for(var i in containers)
|
||||
{
|
||||
Cura.ContainerManager.removeContainer(containers[i]);
|
||||
}
|
||||
if(base.objectList.currentIndex > 0)
|
||||
{
|
||||
base.objectList.currentIndex--;
|
||||
}
|
||||
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: importDialog;
|
||||
title: catalog.i18nc("@title:window", "Import Material");
|
||||
selectExisting: true;
|
||||
nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
|
||||
folder: CuraApplication.getDefaultPath("dialog_material_path")
|
||||
onAccepted:
|
||||
{
|
||||
var result = Cura.ContainerManager.importMaterialContainer(fileUrl)
|
||||
|
||||
messageDialog.title = catalog.i18nc("@title:window", "Import Material")
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags <filename> or <message>!", "Could not import material <filename>%1</filename>: <message>%2</message>").arg(fileUrl).arg(result.message)
|
||||
if(result.status == "success")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Information
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully imported material <filename>%1</filename>").arg(fileUrl)
|
||||
}
|
||||
else if(result.status == "duplicate")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Warning
|
||||
}
|
||||
else
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical
|
||||
}
|
||||
messageDialog.open()
|
||||
CuraApplication.setDefaultPath("dialog_material_path", folder)
|
||||
}
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: exportDialog;
|
||||
title: catalog.i18nc("@title:window", "Export Material");
|
||||
selectExisting: false;
|
||||
nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
|
||||
folder: CuraApplication.getDefaultPath("dialog_material_path")
|
||||
onAccepted:
|
||||
{
|
||||
if(base.currentItem.metadata.base_file)
|
||||
{
|
||||
var result = Cura.ContainerManager.exportContainer(base.currentItem.metadata.base_file, selectedNameFilter, fileUrl)
|
||||
}
|
||||
else
|
||||
{
|
||||
var result = Cura.ContainerManager.exportContainer(base.currentItem.id, selectedNameFilter, fileUrl)
|
||||
}
|
||||
|
||||
messageDialog.title = catalog.i18nc("@title:window", "Export Material")
|
||||
if(result.status == "error")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Critical
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags <filename> and <message>!", "Failed to export material to <filename>%1</filename>: <message>%2</message>").arg(fileUrl).arg(result.message)
|
||||
messageDialog.open()
|
||||
}
|
||||
else if(result.status == "success")
|
||||
{
|
||||
messageDialog.icon = StandardIcon.Information
|
||||
messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag <filename>!", "Successfully exported material to <filename>%1</filename>").arg(result.path)
|
||||
messageDialog.open()
|
||||
}
|
||||
CuraApplication.setDefaultPath("dialog_material_path", folder)
|
||||
}
|
||||
}
|
||||
|
||||
MessageDialog
|
||||
{
|
||||
id: messageDialog
|
||||
}
|
||||
|
||||
UM.SettingPropertyProvider
|
||||
{
|
||||
id: materialDiameterProvider
|
||||
|
||||
containerStackId: Cura.ExtruderManager.activeExtruderStackId
|
||||
key: "material_diameter"
|
||||
watchedProperties: [ "value" ]
|
||||
storeIndex: 5
|
||||
}
|
||||
|
||||
UM.I18nCatalog { id: catalog; name: "cura"; }
|
||||
SystemPalette { id: palette }
|
||||
}
|
||||
|
||||
onCurrentItemChanged:
|
||||
{
|
||||
if(currentItem == null)
|
||||
{
|
||||
return
|
||||
}
|
||||
materialProperties.name = currentItem.name;
|
||||
materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID");
|
||||
|
||||
if(currentItem.metadata != undefined && currentItem.metadata != null)
|
||||
{
|
||||
materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown";
|
||||
materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown";
|
||||
materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow";
|
||||
materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow";
|
||||
|
||||
materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : "";
|
||||
materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : "";
|
||||
|
||||
if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null)
|
||||
{
|
||||
materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : 0.0;
|
||||
materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : 0.0;
|
||||
materialProperties.approximate_diameter = currentItem.metadata.approximate_diameter ? currentItem.metadata.approximate_diameter : "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
materialProperties.density = 0.0;
|
||||
materialProperties.diameter = 0.0;
|
||||
materialProperties.approximate_diameter = "0";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue