// Copyright (c) 2018 Ultimaker B.V. // Uranium is released under the terms of the LGPLv3 or higher. import QtQuick 2.7 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.2 import UM 1.2 as UM import Cura 1.0 as Cura Item { id: base property QtObject materialManager: CuraApplication.getMaterialManager() // Keep PreferencesDialog happy property var resetEnabled: false property var currentItem: null property var current_type: null property var current_brand: null property var hasCurrentItem: base.currentItem != null property var isCurrentItemActivated: { const extruder_position = Cura.ExtruderManager.activeExtruderIndex; const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position]; return base.currentItem.root_material_id == root_material_id; } property string newRootMaterialIdToSwitchTo: "" property bool toActivateNewMaterial: false property var expanded_brands: UM.Preferences.getValue("cura/expanded_brands").split(";") property var expanded_types: UM.Preferences.getValue("cura/expanded_types").split(";") property var extruder_position: Cura.ExtruderManager.activeExtruderIndex property var active_root_material_id: Cura.MachineManager.currentRootMaterialId[extruder_position] UM.I18nCatalog { id: catalog name: "cura" } Cura.MaterialBrandsModel { id: materials_model } Cura.GenericMaterialsModel { id: generic_materials_model } function expandActiveMaterial(search_root_id) { for (var n = 0; n < generic_materials_model.rowCount(); n++) { var material = generic_materials_model.getItem(n); if (material.root_material_id == search_root_id) { if (base.expanded_brands.indexOf("Generic") == -1) { base.expanded_brands.push("Generic"); base.current_brand = "Generic" } } } for (var i = 0; i < materials_model.rowCount(); i++) { var brand = materials_model.getItem(i); var types_model = brand.material_types; for (var j = 0; j < types_model.rowCount(); j++) { var type = types_model.getItem(j); var colors_model = type.colors; for (var k = 0; k < colors_model.rowCount(); k++) { var material = colors_model.getItem(k); if (material.root_material_id == search_root_id) { if (base.expanded_brands.indexOf(brand.name) == -1) { base.expanded_brands.push(brand.name); base.current_brand = brand.name } if (base.expanded_types.indexOf(brand.name+"_"+type.name) == -1) { base.expanded_types.push(brand.name+"_"+type.name) base.current_type = brand.name+"_"+type.name } } } } } UM.Preferences.setValue("cura/expanded_brands", base.expanded_brands.join(";")); UM.Preferences.setValue("cura/expanded_types", base.expanded_types.join(";")); } Component.onCompleted: { expandActiveMaterial(active_root_material_id) } onCurrentItemChanged: { materialDetailsPanel.currentItem = currentItem } Connections { target: materials_model onItemsChanged: { var currentItemId = hasCurrentItem ? base.currentItem.root_material_id : "" var position = Cura.ExtruderManager.activeExtruderIndex // try to pick the currently selected item; it may have been moved if (base.newRootMaterialIdToSwitchTo == "") { base.newRootMaterialIdToSwitchTo = currentItemId } for (var idx = 0; idx < materials_model.rowCount(); ++idx) { var item = materials_model.getItem(idx) if (item.root_material_id == base.newRootMaterialIdToSwitchTo) { // Switch to the newly created profile if needed materialDetailsPanel.currentIndex = idx materialDetailsPanel.activateDetailsWithIndex(materialListView.currentIndex) if (base.toActivateNewMaterial) { Cura.MachineManager.setMaterial(position, item.container_node) } base.newRootMaterialIdToSwitchTo = "" base.toActivateNewMaterial = false return } } materialListView.currentIndex = 0 materialListView.activateDetailsWithIndex(materialListView.currentIndex) if (base.toActivateNewMaterial) { Cura.MachineManager.setMaterial(position, materials_model.getItem(0).container_node) } base.newRootMaterialIdToSwitchTo = "" base.toActivateNewMaterial = false } } // Main layout Label { id: titleLabel anchors { top: parent.top left: parent.left right: parent.right margins: 5 * screenScaleFactor } font.pointSize: 18 text: catalog.i18nc("@title:tab", "Materials") } // Button Row 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: !isCurrentItemActivated onClicked: { forceActiveFocus() const extruder_position = Cura.ExtruderManager.activeExtruderIndex; Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node); } } // Create button Button { text: catalog.i18nc("@action:button", "Create") iconName: "list-add" onClicked: { forceActiveFocus(); base.newRootMaterialIdToSwitchTo = base.materialManager.createMaterial(); base.toActivateNewMaterial = true; } } // Duplicate button Button { text: catalog.i18nc("@action:button", "Duplicate"); iconName: "list-add" enabled: base.hasCurrentItem onClicked: { forceActiveFocus(); base.newRootMaterialIdToSwitchTo = base.materialManager.duplicateMaterial(base.currentItem.container_node); base.toActivateNewMaterial = true; } } // Remove button Button { text: catalog.i18nc("@action:button", "Remove") iconName: "list-remove" enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated onClicked: { forceActiveFocus(); confirmRemoveMaterialDialog.open(); } } // Import button Button { text: catalog.i18nc("@action:button", "Import") iconName: "document-import" onClicked: { forceActiveFocus(); importMaterialDialog.open(); } visible: true } // Export button Button { text: catalog.i18nc("@action:button", "Export") iconName: "document-export" onClicked: { forceActiveFocus(); exportMaterialDialog.open(); } 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 } visible: text != "" text: { var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName; if (Cura.MachineManager.hasVariants) { caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName; } return caption; } 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 frameVisible: true verticalScrollBarPolicy: Qt.ScrollBarAlwaysOn MaterialsList { id: materialListView } } MaterialsDetailsPanel { id: materialDetailsPanel anchors { left: materialScrollView.right leftMargin: UM.Theme.getSize("default_margin").width top: parent.top bottom: parent.bottom right: parent.right } } } // Dialogs MessageDialog { id: confirmRemoveMaterialDialog icon: StandardIcon.Question; title: catalog.i18nc("@title:window", "Confirm Remove") text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItem.name) standardButtons: StandardButton.Yes | StandardButton.No modality: Qt.ApplicationModal onYes: { base.materialManager.removeMaterial(base.currentItem.container_node); } } FileDialog { id: importMaterialDialog 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 or !", "Could not import material %1: %2").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 !", "Successfully imported material %1").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: exportMaterialDialog title: catalog.i18nc("@title:window", "Export Material") selectExisting: false nameFilters: Cura.ContainerManager.getContainerNameFilters("material") folder: CuraApplication.getDefaultPath("dialog_material_path") onAccepted: { var result = Cura.ContainerManager.exportContainer(base.currentItem.root_material_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 and !", "Failed to export material to %1: %2").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 !", "Successfully exported material to %1").arg(result.path); messageDialog.open(); } CuraApplication.setDefaultPath("dialog_material_path", folder); } } MessageDialog { id: messageDialog } }