// Copyright (c) 2018 Ultimaker B.V. // Cura is released under the terms of the LGPLv3 or higher. import QtQuick 2.2 import QtQuick.Controls 1.1 import UM 1.2 as UM import Cura 1.0 as Cura Menu { id: menu title: "Material" property int extruderIndex: 0 property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0 property bool isClusterPrinter: { if(Cura.MachineManager.printerOutputDevices.length == 0) { return false; } var clusterSize = Cura.MachineManager.printerOutputDevices[0].clusterSize; // This is not a cluster printer or the cluster it is just one printer if(clusterSize == undefined || clusterSize == 1) { return false; } return true; } UM.SettingPropertyProvider { id: materialDiameterProvider containerStackId: Cura.ExtruderManager.activeExtruderStackId key: "material_diameter" watchedProperties: [ "value" ] storeIndex: 5 } MenuItem { id: automaticMaterial text: { if(printerConnected && Cura.MachineManager.printerOutputDevices[0].materialNames.length > extruderIndex && !isClusterPrinter) { var materialName = Cura.MachineManager.printerOutputDevices[0].materialNames[extruderIndex]; return catalog.i18nc("@title:menuitem %1 is the automatically selected material", "Automatic: %1").arg(materialName); } return ""; } visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].materialNames.length > extruderIndex && !isClusterPrinter onTriggered: { var materialId = Cura.MachineManager.printerOutputDevices[0].materialIds[extruderIndex]; var items = materialsModel.items; for(var i in items) { if (items[i]["metadata"]["GUID"] == materialId) { Cura.MachineManager.setActiveMaterial(items[i].id); break; } } } } MenuSeparator { visible: automaticMaterial.visible } Instantiator { model: genericMaterialsModel MenuItem { text: model.name checkable: true checked: model.id == Cura.MachineManager.allActiveMaterialIds[Cura.ExtruderManager.extruderIds[extruderIndex]] exclusiveGroup: group onTriggered: { // This workaround is done because of the application menus for materials and variants for multiextrusion printers. // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); Cura.MachineManager.setActiveMaterial(model.id); Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); } } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) } MenuSeparator { } Instantiator { model: brandModel Menu { id: brandMenu title: brandName property string brandName: model.name property var brandMaterials: model.materials Instantiator { model: brandMaterials Menu { id: brandMaterialsMenu title: materialName property string materialName: model.name property var brandMaterialColors: model.colors Instantiator { model: brandMaterialColors MenuItem { text: model.name checkable: true checked: model.id == Cura.MachineManager.allActiveMaterialIds[Cura.ExtruderManager.extruderIds[extruderIndex]] exclusiveGroup: group onTriggered: { // This workaround is done because of the application menus for materials and variants for multiextrusion printers. // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI. var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex; Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex); Cura.MachineManager.setActiveMaterial(model.id); Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex); } } onObjectAdded: brandMaterialsMenu.insertItem(index, object) onObjectRemoved: brandMaterialsMenu.removeItem(object) } } onObjectAdded: brandMenu.insertItem(index, object) onObjectRemoved: brandMenu.removeItem(object) } } onObjectAdded: menu.insertItem(index, object) onObjectRemoved: menu.removeItem(object) } ListModel { id: genericMaterialsModel Component.onCompleted: populateMenuModels() } ListModel { id: brandModel } //: Model used to populate the brandModel Cura.MaterialsModel { id: materialsModel filter: materialFilter() onModelReset: populateMenuModels() onDataChanged: populateMenuModels() } ExclusiveGroup { id: group } MenuSeparator { } MenuItem { action: Cura.Actions.manageMaterials } function materialFilter() { 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 = Cura.MachineManager.activeQualityVariantId; } } 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; } function populateMenuModels() { // Create a structure of unique brands and their material-types genericMaterialsModel.clear() brandModel.clear(); var items = materialsModel.items; var materialsByBrand = {}; for (var i in items) { var brandName = items[i]["metadata"]["brand"]; var materialName = items[i]["metadata"]["material"]; if (brandName == "Generic") { // Add to top section var materialId = items[i].id; genericMaterialsModel.append({ id: materialId, name: items[i].name }); } else { // Add to per-brand, per-material menu if (!materialsByBrand.hasOwnProperty(brandName)) { materialsByBrand[brandName] = {}; } if (!materialsByBrand[brandName].hasOwnProperty(materialName)) { materialsByBrand[brandName][materialName] = []; } materialsByBrand[brandName][materialName].push({ id: items[i].id, name: items[i].name }); } } for (var brand in materialsByBrand) { var materialsByBrandModel = []; var materials = materialsByBrand[brand]; for (var material in materials) { materialsByBrandModel.push({ name: material, colors: materials[material] }) } brandModel.append({ name: brand, materials: materialsByBrandModel }); } } }