Merge remote-tracking branch 'um/master' into theme-picker

This commit is contained in:
Victor Larchenko 2017-04-21 14:29:01 +06:00
commit e5eb0c9a14
379 changed files with 147920 additions and 59967 deletions

View file

@ -73,68 +73,76 @@ UM.Dialog
anchors.topMargin: UM.Theme.getSize("default_margin").height
}
ListView
ScrollView
{
id: projectsList
anchors.top: creditsNotes.bottom
anchors.topMargin: 10
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
height: childrenRect.height
height: base.height - y - (2 * UM.Theme.getSize("default_margin").height + closeButton.height)
delegate: Row
ListView
{
Label
{
text: "<a href='%1' title='%2'>%2</a>".arg(model.url).arg(model.name)
width: projectsList.width * 0.25
elide: Text.ElideRight
onLinkActivated: Qt.openUrlExternally(link)
}
Label
{
text: model.description
elide: Text.ElideRight
width: projectsList.width * 0.6
}
Label
{
text: model.license
elide: Text.ElideRight
width: projectsList.width * 0.15
}
}
model: ListModel
{
id: projectsModel
}
Component.onCompleted:
{
projectsModel.append({ name:"Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "AGPLv3", url: "https://github.com/Ultimaker/Cura" });
projectsModel.append({ name:"Uranium", description: catalog.i18nc("@label", "Application framework"), license: "AGPLv3", url: "https://github.com/Ultimaker/Uranium" });
projectsModel.append({ name:"CuraEngine", description: catalog.i18nc("@label", "GCode generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
projectsModel.append({ name:"libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "AGPLv3", url: "https://github.com/Ultimaker/libArcus" });
id: projectsList
projectsModel.append({ name:"Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" });
projectsModel.append({ name:"Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" });
projectsModel.append({ name:"PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" });
projectsModel.append({ name:"SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" });
projectsModel.append({ name:"Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
projectsModel.append({ name:"SciPy", description: catalog.i18nc("@label", "Support library for scientific computing "), license: "BSD-new", url: "https://www.scipy.org/" });
projectsModel.append({ name:"NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
projectsModel.append({ name:"NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" });
projectsModel.append({ name:"PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" });
projectsModel.append({ name:"python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" });
projectsModel.append({ name:"Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" });
projectsModel.append({ name:"Open Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://fonts.google.com/specimen/Open+Sans" });
projectsModel.append({ name:"Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" });
width: parent.width
delegate: Row
{
Label
{
text: "<a href='%1' title='%2'>%2</a>".arg(model.url).arg(model.name)
width: (projectsList.width * 0.25) | 0
elide: Text.ElideRight
onLinkActivated: Qt.openUrlExternally(link)
}
Label
{
text: model.description
elide: Text.ElideRight
width: (projectsList.width * 0.6) | 0
}
Label
{
text: model.license
elide: Text.ElideRight
width: (projectsList.width * 0.15) | 0
}
}
model: ListModel
{
id: projectsModel
}
Component.onCompleted:
{
projectsModel.append({ name:"Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "AGPLv3", url: "https://github.com/Ultimaker/Cura" });
projectsModel.append({ name:"Uranium", description: catalog.i18nc("@label", "Application framework"), license: "AGPLv3", url: "https://github.com/Ultimaker/Uranium" });
projectsModel.append({ name:"CuraEngine", description: catalog.i18nc("@label", "GCode generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
projectsModel.append({ name:"libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "AGPLv3", url: "https://github.com/Ultimaker/libArcus" });
projectsModel.append({ name:"Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" });
projectsModel.append({ name:"Qt5", description: catalog.i18nc("@label", "GUI framework"), license: "LGPLv3", url: "https://www.qt.io/" });
projectsModel.append({ name:"PyQt", description: catalog.i18nc("@label", "GUI framework bindings"), license: "GPL", url: "https://riverbankcomputing.com/software/pyqt" });
projectsModel.append({ name:"SIP", description: catalog.i18nc("@label", "C/C++ Binding library"), license: "GPL", url: "https://riverbankcomputing.com/software/sip" });
projectsModel.append({ name:"Protobuf", description: catalog.i18nc("@label", "Data interchange format"), license: "BSD", url: "https://developers.google.com/protocol-buffers" });
projectsModel.append({ name:"SciPy", description: catalog.i18nc("@label", "Support library for scientific computing "), license: "BSD-new", url: "https://www.scipy.org/" });
projectsModel.append({ name:"NumPy", description: catalog.i18nc("@label", "Support library for faster math"), license: "BSD", url: "http://www.numpy.org/" });
projectsModel.append({ name:"NumPy-STL", description: catalog.i18nc("@label", "Support library for handling STL files"), license: "BSD", url: "https://github.com/WoLpH/numpy-stl" });
projectsModel.append({ name:"libSavitar", description: catalog.i18nc("@label", "Support library for handling 3MF files"), license: "AGPLv3", url: "https://github.com/ultimaker/libsavitar" });
projectsModel.append({ name:"PySerial", description: catalog.i18nc("@label", "Serial communication library"), license: "Python", url: "http://pyserial.sourceforge.net/" });
projectsModel.append({ name:"python-zeroconf", description: catalog.i18nc("@label", "ZeroConf discovery library"), license: "LGPL", url: "https://github.com/jstasiak/python-zeroconf" });
projectsModel.append({ name:"Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" });
projectsModel.append({ name:"Open Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://fonts.google.com/specimen/Open+Sans" });
projectsModel.append({ name:"Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" });
}
}
}
rightButtons: Button
{
//: Close about dialog button
id: closeButton
text: catalog.i18nc("@action:button","Close");
onClicked: base.visible = false;

45
resources/qml/Actions.qml Normal file → Executable file
View file

@ -10,8 +10,8 @@ import Cura 1.0 as Cura
Item
{
property alias newProject: newProjectAction;
property alias open: openAction;
property alias loadWorkspace: loadWorkspaceAction;
property alias quit: quitAction;
property alias undo: undoAction;
@ -31,6 +31,8 @@ Item
property alias selectAll: selectAllAction;
property alias deleteAll: deleteAllAction;
property alias reloadAll: reloadAllAction;
property alias arrangeAll: arrangeAllAction;
property alias arrangeSelection: arrangeSelectionAction;
property alias resetAllTranslation: resetAllTranslationAction;
property alias resetAll: resetAllAction;
@ -183,7 +185,7 @@ Item
enabled: UM.Controller.toolsEnabled;
iconName: "edit-delete";
shortcut: StandardKey.Delete;
onTriggered: Printer.deleteSelection();
onTriggered: CuraApplication.deleteSelection();
}
Action
@ -207,7 +209,7 @@ Item
enabled: UM.Scene.numObjectsSelected > 1 ? true: false
iconName: "object-group"
shortcut: "Ctrl+G";
onTriggered: Printer.groupSelected();
onTriggered: CuraApplication.groupSelected();
}
Action
@ -217,7 +219,7 @@ Item
enabled: UM.Scene.isGroupSelected
iconName: "object-ungroup"
shortcut: "Ctrl+Shift+G";
onTriggered: Printer.ungroupSelected();
onTriggered: CuraApplication.ungroupSelected();
}
Action
@ -227,7 +229,7 @@ Item
enabled: UM.Scene.numObjectsSelected > 1 ? true: false
iconName: "merge";
shortcut: "Ctrl+Alt+G";
onTriggered: Printer.mergeSelected();
onTriggered: CuraApplication.mergeSelected();
}
Action
@ -244,7 +246,7 @@ Item
enabled: UM.Controller.toolsEnabled;
iconName: "edit-select-all";
shortcut: "Ctrl+A";
onTriggered: Printer.selectAll();
onTriggered: CuraApplication.selectAll();
}
Action
@ -254,7 +256,7 @@ Item
enabled: UM.Controller.toolsEnabled;
iconName: "edit-delete";
shortcut: "Ctrl+D";
onTriggered: Printer.deleteAll();
onTriggered: CuraApplication.deleteAll();
}
Action
@ -262,35 +264,52 @@ Item
id: reloadAllAction;
text: catalog.i18nc("@action:inmenu menubar:file","Re&load All Models");
iconName: "document-revert";
onTriggered: Printer.reloadAll();
shortcut: "F5"
onTriggered: CuraApplication.reloadAll();
}
Action
{
id: arrangeAllAction;
text: catalog.i18nc("@action:inmenu menubar:edit","Arrange All Models");
onTriggered: Printer.arrangeAll();
shortcut: "Ctrl+R";
}
Action
{
id: arrangeSelectionAction;
text: catalog.i18nc("@action:inmenu menubar:edit","Arrange Selection");
onTriggered: Printer.arrangeSelection();
}
Action
{
id: resetAllTranslationAction;
text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Model Positions");
onTriggered: Printer.resetAllTranslation();
onTriggered: CuraApplication.resetAllTranslation();
}
Action
{
id: resetAllAction;
text: catalog.i18nc("@action:inmenu menubar:edit","Reset All Model &Transformations");
onTriggered: Printer.resetAll();
onTriggered: CuraApplication.resetAll();
}
Action
{
id: openAction;
text: catalog.i18nc("@action:inmenu menubar:file","&Open File...");
text: catalog.i18nc("@action:inmenu menubar:file","&Open File(s)...");
iconName: "document-open";
shortcut: StandardKey.Open;
}
Action
{
id: loadWorkspaceAction
text: catalog.i18nc("@action:inmenu menubar:file","&Open Project...");
id: newProjectAction
text: catalog.i18nc("@action:inmenu menubar:file","&New Project...");
shortcut: StandardKey.New
}
Action

View file

@ -180,7 +180,7 @@ UM.Dialog
anchors.bottom:parent.bottom
spacing: UM.Theme.getSize("default_margin").width
Label
Text
{
text: catalog.i18nc("@label", "Printer Name:")
anchors.verticalCenter: machineName.verticalCenter

View file

@ -0,0 +1,129 @@
// Copyright (c) 2015 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.1
import UM 1.3 as UM
import Cura 1.0 as Cura
UM.Dialog
{
// This dialog asks the user whether he/she wants to open a project file as a project or import models.
id: base
title: catalog.i18nc("@title:window", "Open project file")
width: 450 * Screen.devicePixelRatio
height: 150 * Screen.devicePixelRatio
maximumHeight: height
maximumWidth: width
minimumHeight: maximumHeight
minimumWidth: maximumWidth
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
property var fileUrl
function loadProjectFile(projectFile)
{
UM.WorkspaceFileHandler.readLocalFile(projectFile);
var meshName = backgroundItem.getMeshName(projectFile.toString());
backgroundItem.hasMesh(decodeURIComponent(meshName));
}
function loadModelFiles(fileUrls)
{
for (var i in fileUrls)
{
CuraApplication.readLocalFile(fileUrls[i]);
}
var meshName = backgroundItem.getMeshName(fileUrls[0].toString());
backgroundItem.hasMesh(decodeURIComponent(meshName));
}
onVisibleChanged:
{
if (visible)
{
var rememberMyChoice = UM.Preferences.getValue("cura/choice_on_open_project") != "always_ask";
rememberChoiceCheckBox.checked = rememberMyChoice;
}
}
Column
{
anchors.fill: parent
anchors.leftMargin: 20 * Screen.devicePixelRatio
anchors.rightMargin: 20 * Screen.devicePixelRatio
anchors.bottomMargin: 20 * Screen.devicePixelRatio
spacing: 10 * Screen.devicePixelRatio
Label
{
text: catalog.i18nc("@text:window", "This is a Cura project file. Would you like to open it as a project or import the models from it?")
anchors.left: parent.left
anchors.right: parent.right
font: UM.Theme.getFont("default")
wrapMode: Text.WordWrap
}
CheckBox
{
id: rememberChoiceCheckBox
text: catalog.i18nc("@text:window", "Remember my choice")
checked: UM.Preferences.getValue("cura/choice_on_open_project") != "always_ask"
}
// Buttons
Item
{
anchors.right: parent.right
anchors.left: parent.left
height: childrenRect.height
Button
{
id: openAsProjectButton
text: catalog.i18nc("@action:button", "Open as project");
anchors.right: importModelsButton.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width * Screen.devicePixelRatio
isDefault: true
onClicked:
{
// update preference
if (rememberChoiceCheckBox.checked)
UM.Preferences.setValue("cura/choice_on_open_project", "open_as_project");
// load this file as project
base.hide();
loadProjectFile(base.fileUrl);
}
}
Button
{
id: importModelsButton
text: catalog.i18nc("@action:button", "Import models");
anchors.right: parent.right
onClicked:
{
// update preference
if (rememberChoiceCheckBox.checked)
UM.Preferences.setValue("cura/choice_on_open_project", "open_as_model");
// load models from this project file
base.hide();
loadModelFiles([base.fileUrl]);
}
}
}
}
}

291
resources/qml/Cura.qml Normal file → Executable file
View file

@ -21,7 +21,7 @@ UM.MainWindow
property bool monitoringPrint: false
Component.onCompleted:
{
Printer.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size"))
CuraApplication.setMinimumWindowSize(UM.Theme.getSize("window_minimum_size"))
// Workaround silly issues with QML Action's shortcut property.
//
// Currently, there is no way to define shortcuts as "Application Shortcut".
@ -45,7 +45,7 @@ UM.MainWindow
function getMeshName(path){
//takes the path the complete path of the meshname and returns only the filebase
var fileName = path.slice(path.lastIndexOf("/") + 1)
var fileBase = fileName.slice(0, fileName.lastIndexOf("."))
var fileBase = fileName.slice(0, fileName.indexOf("."))
return fileBase
}
@ -66,6 +66,10 @@ UM.MainWindow
{
id: fileMenu
title: catalog.i18nc("@title:menu menubar:toplevel","&File");
MenuItem
{
action: Cura.Actions.newProject;
}
MenuItem
{
@ -74,11 +78,6 @@ UM.MainWindow
RecentFilesMenu { }
MenuItem
{
action: Cura.Actions.loadWorkspace
}
MenuSeparator { }
MenuItem
@ -86,28 +85,20 @@ UM.MainWindow
text: catalog.i18nc("@action:inmenu menubar:file", "&Save Selection to File");
enabled: UM.Selection.hasSelection;
iconName: "document-save-as";
onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false });
onTriggered: UM.OutputDeviceManager.requestWriteSelectionToDevice("local_file", PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetype": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"});
}
Menu
MenuItem
{
id: saveAllMenu
title: catalog.i18nc("@title:menu menubar:file","Save &All")
iconName: "document-save-all";
enabled: devicesModel.rowCount() > 0 && UM.Backend.progress > 0.99;
Instantiator
id: saveAsMenu
text: catalog.i18nc("@title:menu menubar:file", "Save &As...")
onTriggered:
{
model: UM.OutputDevicesModel { id: devicesModel; }
MenuItem
{
text: model.description;
onTriggered: UM.OutputDeviceManager.requestWriteToDevice(model.id, PrintInformation.jobName, { "filter_by_machine": false });
}
onObjectAdded: saveAllMenu.insertItem(index, object)
onObjectRemoved: saveAllMenu.removeItem(object)
var localDeviceId = "local_file";
UM.OutputDeviceManager.requestWriteToDevice(localDeviceId, PrintInformation.jobName, { "filter_by_machine": false, "preferred_mimetype": "application/vnd.ms-package.3dmanufacturing-3dmodel+xml"});
}
}
MenuItem
{
id: saveWorkspaceMenu
@ -140,6 +131,7 @@ UM.MainWindow
MenuItem { action: Cura.Actions.redo; }
MenuSeparator { }
MenuItem { action: Cura.Actions.selectAll; }
MenuItem { action: Cura.Actions.arrangeAll; }
MenuItem { action: Cura.Actions.deleteSelection; }
MenuItem { action: Cura.Actions.deleteAll; }
MenuItem { action: Cura.Actions.resetAllTranslation; }
@ -266,58 +258,13 @@ UM.MainWindow
anchors.fill: parent;
onDropped:
{
if(drop.urls.length > 0)
if (drop.urls.length > 0)
{
// Import models
var imported_model = -1;
for(var i in drop.urls)
{
// There is no endsWith in this version of JS...
if ((drop.urls[i].length <= 12) || (drop.urls[i].substring(drop.urls[i].length-12) !== ".curaprofile")) {
// Drop an object
Printer.readLocalFile(drop.urls[i]);
if (imported_model == -1)
{
imported_model = i;
}
}
}
// Import profiles
var import_result = Cura.ContainerManager.importProfiles(drop.urls);
if (import_result.message !== "") {
messageDialog.text = import_result.message
if(import_result.status == "ok")
{
messageDialog.icon = StandardIcon.Information
}
else
{
messageDialog.icon = StandardIcon.Critical
}
messageDialog.open()
}
if (imported_model != -1)
{
var meshName = backgroundItem.getMeshName(drop.urls[imported_model].toString())
backgroundItem.hasMesh(decodeURIComponent(meshName))
}
openDialog.handleOpenFileUrls(drop.urls);
}
}
}
Legend
{
id: legend
anchors
{
top: parent.top
topMargin: UM.Theme.getSize("default_margin").height
right: sidebar.left
rightMargin: UM.Theme.getSize("default_margin").width
}
}
JobSpecs
{
id: jobSpecs
@ -546,6 +493,33 @@ UM.MainWindow
onTriggered: preferences.visible = true
}
MessageDialog
{
id: newProjectDialog
modality: Qt.ApplicationModal
title: catalog.i18nc("@title:window", "New project")
text: catalog.i18nc("@info:question", "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings.")
standardButtons: StandardButton.Yes | StandardButton.No
icon: StandardIcon.Question
onYes:
{
CuraApplication.deleteAll();
Cura.Actions.resetProfile.trigger();
}
}
Connections
{
target: Cura.Actions.newProject
onTriggered:
{
if(Printer.platformActivity || Cura.MachineManager.hasUserSettings)
{
newProjectDialog.visible = true
}
}
}
Connections
{
target: Cura.Actions.addProfile
@ -630,6 +604,7 @@ UM.MainWindow
MenuItem { action: Cura.Actions.multiplyObject; }
MenuSeparator { }
MenuItem { action: Cura.Actions.selectAll; }
MenuItem { action: Cura.Actions.arrangeAll; }
MenuItem { action: Cura.Actions.deleteAll; }
MenuItem { action: Cura.Actions.reloadAll; }
MenuItem { action: Cura.Actions.resetAllTranslation; }
@ -646,7 +621,7 @@ UM.MainWindow
{
if(objectContextMenu.objectId != 0)
{
Printer.deleteObject(objectContextMenu.objectId);
CuraApplication.deleteObject(objectContextMenu.objectId);
objectContextMenu.objectId = 0;
}
}
@ -679,7 +654,7 @@ UM.MainWindow
{
if(objectContextMenu.objectId != 0)
{
Printer.centerObject(objectContextMenu.objectId);
CuraApplication.centerObject(objectContextMenu.objectId);
objectContextMenu.objectId = 0;
}
}
@ -690,6 +665,7 @@ UM.MainWindow
{
id: contextMenu;
MenuItem { action: Cura.Actions.selectAll; }
MenuItem { action: Cura.Actions.arrangeAll; }
MenuItem { action: Cura.Actions.deleteAll; }
MenuItem { action: Cura.Actions.reloadAll; }
MenuItem { action: Cura.Actions.resetAllTranslation; }
@ -733,27 +709,119 @@ UM.MainWindow
id: openDialog;
//: File open dialog title
title: catalog.i18nc("@title:window","Open file")
title: catalog.i18nc("@title:window","Open file(s)")
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
selectMultiple: true
nameFilters: UM.MeshFileHandler.supportedReadFileTypes;
folder: CuraApplication.getDefaultPath("dialog_load_path")
onAccepted:
{
//Because several implementations of the file dialog only update the folder
//when it is explicitly set.
// Because several implementations of the file dialog only update the folder
// when it is explicitly set.
var f = folder;
folder = f;
CuraApplication.setDefaultPath("dialog_load_path", folder);
for(var i in fileUrls)
handleOpenFileUrls(fileUrls);
}
// Yeah... I know... it is a mess to put all those things here.
// There are lots of user interactions in this part of the logic, such as showing a warning dialog here and there,
// etc. This means it will come back and forth from time to time between QML and Python. So, separating the logic
// and view here may require more effort but make things more difficult to understand.
function handleOpenFileUrls(fileUrlList)
{
// look for valid project files
var projectFileUrlList = [];
var hasGcode = false;
var nonGcodeFileList = [];
for (var i in fileUrlList)
{
Printer.readLocalFile(fileUrls[i])
var endsWithG = /\.g$/;
var endsWithGcode = /\.gcode$/;
if (endsWithG.test(fileUrlList[i]) || endsWithGcode.test(fileUrlList[i]))
{
continue;
}
else if (CuraApplication.checkIsValidProjectFile(fileUrlList[i]))
{
projectFileUrlList.push(fileUrlList[i]);
}
nonGcodeFileList.push(fileUrlList[i]);
}
hasGcode = nonGcodeFileList.length < fileUrlList.length;
// show a warning if selected multiple files together with Gcode
var hasProjectFile = projectFileUrlList.length > 0;
var selectedMultipleFiles = fileUrlList.length > 1;
if (selectedMultipleFiles && hasGcode)
{
infoMultipleFilesWithGcodeDialog.selectedMultipleFiles = selectedMultipleFiles;
infoMultipleFilesWithGcodeDialog.hasProjectFile = hasProjectFile;
infoMultipleFilesWithGcodeDialog.fileUrls = nonGcodeFileList.slice();
infoMultipleFilesWithGcodeDialog.projectFileUrlList = projectFileUrlList.slice();
infoMultipleFilesWithGcodeDialog.open();
}
else
{
handleOpenFiles(selectedMultipleFiles, hasProjectFile, fileUrlList, projectFileUrlList);
}
}
function handleOpenFiles(selectedMultipleFiles, hasProjectFile, fileUrlList, projectFileUrlList)
{
// we only allow opening one project file
if (selectedMultipleFiles && hasProjectFile)
{
openFilesIncludingProjectsDialog.fileUrls = fileUrlList.slice();
openFilesIncludingProjectsDialog.show();
return;
}
var meshName = backgroundItem.getMeshName(fileUrls[0].toString())
backgroundItem.hasMesh(decodeURIComponent(meshName))
if (hasProjectFile)
{
var projectFile = projectFileUrlList[0];
// check preference
var choice = UM.Preferences.getValue("cura/choice_on_open_project");
if (choice == "open_as_project")
{
openFilesIncludingProjectsDialog.loadProjectFile(projectFile);
}
else if (choice == "open_as_model")
{
openFilesIncludingProjectsDialog.loadModelFiles([projectFile].slice());
}
else // always ask
{
// ask whether to open as project or as models
askOpenAsProjectOrModelsDialog.fileUrl = projectFile;
askOpenAsProjectOrModelsDialog.show();
}
}
else
{
openFilesIncludingProjectsDialog.loadModelFiles(fileUrlList.slice());
}
}
}
MessageDialog {
id: infoMultipleFilesWithGcodeDialog
title: catalog.i18nc("@title:window", "Open File(s)")
icon: StandardIcon.Information
standardButtons: StandardButton.Ok
text: catalog.i18nc("@text:window", "We have found one or more G-Code files within the files you have selected. You can only open one G-Code file at a time. If you want to open a G-Code file, please just select only one.")
property var selectedMultipleFiles
property var hasProjectFile
property var fileUrls
property var projectFileUrlList
onAccepted:
{
openDialog.handleOpenFiles(selectedMultipleFiles, hasProjectFile, fileUrls, projectFileUrlList);
}
}
@ -763,36 +831,14 @@ UM.MainWindow
onTriggered: openDialog.open()
}
FileDialog
OpenFilesIncludingProjectsDialog
{
id: openWorkspaceDialog;
//: File open dialog title
title: catalog.i18nc("@title:window","Open workspace")
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
selectMultiple: false
nameFilters: UM.WorkspaceFileHandler.supportedReadFileTypes;
folder: CuraApplication.getDefaultPath("dialog_load_path")
onAccepted:
{
//Because several implementations of the file dialog only update the folder
//when it is explicitly set.
var f = folder;
folder = f;
CuraApplication.setDefaultPath("dialog_load_path", folder);
for(var i in fileUrls)
{
UM.WorkspaceFileHandler.readLocalFile(fileUrls[i])
}
}
id: openFilesIncludingProjectsDialog
}
Connections
AskOpenAsProjectOrModelsDialog
{
target: Cura.Actions.loadWorkspace
onTriggered: openWorkspaceDialog.open()
id: askOpenAsProjectOrModelsDialog
}
EngineLog
@ -833,7 +879,7 @@ UM.MainWindow
function start(id)
{
var actions = Cura.MachineActionManager.getFirstStartActions(id)
var actions = Cura.MachineActionManager.getFirstStartActions(id)
resetPages() // Remove previous pages
for (var i = 0; i < actions.length; i++)
@ -855,14 +901,14 @@ UM.MainWindow
{
id: messageDialog
modality: Qt.ApplicationModal
onAccepted: Printer.messageBoxClosed(clickedButton)
onApply: Printer.messageBoxClosed(clickedButton)
onDiscard: Printer.messageBoxClosed(clickedButton)
onHelp: Printer.messageBoxClosed(clickedButton)
onNo: Printer.messageBoxClosed(clickedButton)
onRejected: Printer.messageBoxClosed(clickedButton)
onReset: Printer.messageBoxClosed(clickedButton)
onYes: Printer.messageBoxClosed(clickedButton)
onAccepted: CuraApplication.messageBoxClosed(clickedButton)
onApply: CuraApplication.messageBoxClosed(clickedButton)
onDiscard: CuraApplication.messageBoxClosed(clickedButton)
onHelp: CuraApplication.messageBoxClosed(clickedButton)
onNo: CuraApplication.messageBoxClosed(clickedButton)
onRejected: CuraApplication.messageBoxClosed(clickedButton)
onReset: CuraApplication.messageBoxClosed(clickedButton)
onYes: CuraApplication.messageBoxClosed(clickedButton)
}
Connections
@ -880,6 +926,20 @@ UM.MainWindow
}
}
DiscardOrKeepProfileChangesDialog
{
id: discardOrKeepProfileChangesDialog
}
Connections
{
target: Printer
onShowDiscardOrKeepProfileChanges:
{
discardOrKeepProfileChangesDialog.show()
}
}
Connections
{
target: Cura.Actions.addMachine
@ -927,4 +987,3 @@ UM.MainWindow
}
}
}

View file

@ -0,0 +1,223 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.1
import QtQuick.Controls 1.1
import QtQuick.Dialogs 1.2
import QtQuick.Window 2.1
import UM 1.2 as UM
import Cura 1.1 as Cura
UM.Dialog
{
id: base
title: catalog.i18nc("@title:window", "Discard or Keep changes")
width: 800 * Screen.devicePixelRatio
height: 400 * Screen.devicePixelRatio
property var changesModel: Cura.UserChangesModel{ id: userChangesModel}
onVisibilityChanged:
{
if(visible)
{
changesModel.forceUpdate()
discardOrKeepProfileChangesDropDownButton.currentIndex = 0;
for (var i = 0; i < discardOrKeepProfileChangesDropDownButton.model.count; ++i)
{
var code = discardOrKeepProfileChangesDropDownButton.model.get(i).code;
if (code == UM.Preferences.getValue("cura/choice_on_profile_override"))
{
discardOrKeepProfileChangesDropDownButton.currentIndex = i;
break;
}
}
}
}
Column
{
anchors.fill: parent
spacing: UM.Theme.getSize("default_margin").width
UM.I18nCatalog
{
id: catalog;
name: "cura"
}
Row
{
height: childrenRect.height
anchors.margins: UM.Theme.getSize("default_margin").width
anchors.left: parent.left
anchors.right: parent.right
spacing: UM.Theme.getSize("default_margin").width
Label
{
text: catalog.i18nc("@text:window", "You have customized some profile settings.\nWould you like to keep or discard those settings?")
anchors.margins: UM.Theme.getSize("default_margin").width
font: UM.Theme.getFont("default")
wrapMode: Text.WordWrap
}
}
TableView
{
anchors.margins: UM.Theme.getSize("default_margin").width
anchors.left: parent.left
anchors.right: parent.right
height: base.height - 150 * Screen.devicePixelRatio
id: tableView
Component
{
id: labelDelegate
Label
{
property var extruder_name: userChangesModel.getItem(styleData.row).extruder
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
font: UM.Theme.getFont("system")
text:
{
var result = styleData.value
if (extruder_name != "")
{
result += " (" + extruder_name + ")"
}
return result
}
}
}
Component
{
id: defaultDelegate
Label
{
text: styleData.value
font: UM.Theme.getFont("system")
color: UM.Theme.getColor("setting_control_disabled_text")
}
}
TableViewColumn
{
role: "label"
title: catalog.i18nc("@title:column", "Profile settings")
delegate: labelDelegate
width: tableView.width * 0.4
}
TableViewColumn
{
role: "original_value"
title: catalog.i18nc("@title:column", "Default")
width: tableView.width * 0.3
delegate: defaultDelegate
}
TableViewColumn
{
role: "user_value"
title: catalog.i18nc("@title:column", "Customized")
width: tableView.width * 0.3 - 1
}
section.property: "category"
section.delegate: Label
{
text: section
font.bold: true
}
model: base.changesModel
}
Item
{
anchors.right: parent.right
anchors.left: parent.left
anchors.margins: UM.Theme.getSize("default_margin").width
height:childrenRect.height
ComboBox
{
id: discardOrKeepProfileChangesDropDownButton
width: 300
model: ListModel
{
id: discardOrKeepProfileListModel
Component.onCompleted: {
append({ text: catalog.i18nc("@option:discardOrKeep", "Always ask me this"), code: "always_ask" })
append({ text: catalog.i18nc("@option:discardOrKeep", "Discard and never ask again"), code: "always_discard" })
append({ text: catalog.i18nc("@option:discardOrKeep", "Keep and never ask again"), code: "always_keep" })
}
}
onActivated:
{
var code = model.get(index).code;
UM.Preferences.setValue("cura/choice_on_profile_override", code);
if (code == "always_keep") {
keepButton.enabled = true;
discardButton.enabled = false;
}
else if (code == "always_discard") {
keepButton.enabled = false;
discardButton.enabled = true;
}
else {
keepButton.enabled = true;
discardButton.enabled = true;
}
}
}
}
Item
{
anchors.right: parent.right
anchors.left: parent.left
anchors.margins: UM.Theme.getSize("default_margin").width
height: childrenRect.height
Button
{
id: discardButton
text: catalog.i18nc("@action:button", "Discard");
anchors.right: parent.right
onClicked:
{
CuraApplication.discardOrKeepProfileChangesClosed("discard")
base.hide()
}
isDefault: true
}
Button
{
id: keepButton
text: catalog.i18nc("@action:button", "Keep");
anchors.right: discardButton.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
onClicked:
{
CuraApplication.discardOrKeepProfileChangesClosed("keep")
base.hide()
}
}
Button
{
id: createNewProfileButton
text: catalog.i18nc("@action:button", "Create New Profile");
anchors.left: parent.left
action: Cura.Actions.addProfile
onClicked: base.hide()
}
}
}
}

View file

@ -27,7 +27,7 @@ UM.Dialog
interval: 1000;
running: false;
repeat: true;
onTriggered: textArea.text = Printer.getEngineLog();
onTriggered: textArea.text = CuraApplication.getEngineLog();
}
UM.I18nCatalog{id: catalog; name:"cura"}
}
@ -43,7 +43,7 @@ UM.Dialog
{
if(visible)
{
textArea.text = Printer.getEngineLog();
textArea.text = CuraApplication.getEngineLog();
updateTimer.start();
} else
{

View file

@ -12,7 +12,7 @@ import Cura 1.0 as Cura
Item {
id: base
property bool activity: Printer.getPlatformActivity
property bool activity: CuraApplication.platformActivity
property string fileBaseName
property variant activeMachineName: Cura.MachineManager.activeMachineName
@ -132,7 +132,7 @@ Item {
}
}
Label
Text
{
id: boundingSpec
anchors.top: jobNameRow.bottom
@ -141,7 +141,7 @@ Item {
verticalAlignment: Text.AlignVCenter
font: UM.Theme.getFont("small")
color: UM.Theme.getColor("text_subtext")
text: Printer.getSceneBoundingBoxString
text: CuraApplication.getSceneBoundingBoxString
}
Rectangle
@ -169,7 +169,7 @@ Item {
color: UM.Theme.getColor("text_subtext")
source: UM.Theme.getIcon("print_time")
}
Label
Text
{
id: timeSpec
anchors.right: lengthIcon.left
@ -192,7 +192,7 @@ Item {
color: UM.Theme.getColor("text_subtext")
source: UM.Theme.getIcon("category_material")
}
Label
Text
{
id: lengthSpec
anchors.right: parent.right

View file

@ -1,65 +0,0 @@
// Copyright (c) 2015 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import UM 1.1 as UM
import Cura 1.0 as Cura
Item {
id: base
UM.I18nCatalog { id: catalog; name:"cura"}
width: childrenRect.width
height: childrenRect.height
Connections
{
target: Printer
onViewLegendItemsChanged:
{
legendItemRepeater.model = items
}
}
Column
{
Repeater
{
id: legendItemRepeater
Item {
anchors.right: parent.right
height: childrenRect.height
width: childrenRect.width
Rectangle {
id: swatch
anchors.right: parent.right
anchors.verticalCenter: label.verticalCenter
height: UM.Theme.getSize("setting_control").height / 2
width: height
color: modelData.color
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("text_subtext")
}
Label {
id: label
text: modelData.title
font: UM.Theme.getFont("small")
color: UM.Theme.getColor("text_subtext")
anchors.right: swatch.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2
}
}
}
}
}

View file

@ -15,6 +15,15 @@ Menu
property int extruderIndex: 0
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
UM.SettingPropertyProvider
{
id: materialDiameterProvider
containerStackId: Cura.MachineManager.activeMachineId
key: "material_diameter"
watchedProperties: [ "value" ]
}
MenuItem
{
id: automaticMaterial
@ -141,7 +150,7 @@ Menu
function materialFilter()
{
var result = { "type": "material" };
var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value) };
if(Cura.MachineManager.filterMaterialsByMachine)
{
result.definition = Cura.MachineManager.activeQualityDefinitionId;

View file

@ -4,7 +4,7 @@
import QtQuick 2.2
import QtQuick.Controls 1.1
import UM 1.2 as UM
import UM 1.3 as UM
import Cura 1.0 as Cura
Menu
@ -13,11 +13,11 @@ Menu
title: catalog.i18nc("@title:menu menubar:file", "Open &Recent")
iconName: "document-open-recent";
enabled: Printer.recentFiles.length > 0;
enabled: CuraApplication.recentFiles.length > 0;
Instantiator
{
model: Printer.recentFiles
model: CuraApplication.recentFiles
MenuItem
{
text:
@ -25,8 +25,44 @@ Menu
var path = modelData.toString()
return (index + 1) + ". " + path.slice(path.lastIndexOf("/") + 1);
}
onTriggered: {
Printer.readLocalFile(modelData);
onTriggered:
{
var toShowDialog = false;
var toOpenAsProject = false;
var toOpenAsModel = false;
if (CuraApplication.checkIsValidProjectFile(modelData)) {
// check preference
var choice = UM.Preferences.getValue("cura/choice_on_open_project");
if (choice == "open_as_project")
{
toOpenAsProject = true;
}else if (choice == "open_as_model"){
toOpenAsModel = true;
}else{
toShowDialog = true;
}
}
else {
toOpenAsModel = true;
}
if (toShowDialog) {
askOpenAsProjectOrModelsDialog.fileUrl = modelData;
askOpenAsProjectOrModelsDialog.show();
return;
}
// open file in the prefered way
if (toOpenAsProject)
{
UM.WorkspaceFileHandler.readLocalFile(modelData);
}
else if (toOpenAsModel)
{
CuraApplication.readLocalFile(modelData);
}
var meshName = backgroundItem.getMeshName(modelData.toString())
backgroundItem.hasMesh(decodeURIComponent(meshName))
}
@ -34,4 +70,9 @@ Menu
onObjectAdded: menu.insertItem(index, object)
onObjectRemoved: menu.removeItem(object)
}
Cura.AskOpenAsProjectOrModelsDialog
{
id: askOpenAsProjectOrModelsDialog
}
}

View file

@ -80,7 +80,7 @@ Item
}
}
property bool activity: Printer.getPlatformActivity;
property bool activity: CuraApplication.platformActivity;
property int totalHeight: childrenRect.height + UM.Theme.getSize("default_margin").height
property string fileBaseName
property string statusText:
@ -205,8 +205,8 @@ Item
onAdditionalComponentsChanged:
{
if(areaId == "monitorButtons") {
for (var component in Printer.additionalComponents["monitorButtons"]) {
Printer.additionalComponents["monitorButtons"][component].parent = additionalComponentsRow
for (var component in CuraApplication.additionalComponents["monitorButtons"]) {
CuraApplication.additionalComponents["monitorButtons"][component].parent = additionalComponentsRow
}
}
}

View file

@ -20,7 +20,7 @@ UM.Dialog
height: minimumHeight
property var objectId: 0;
onAccepted: Printer.multiplyObject(base.objectId, parseInt(copiesField.text))
onAccepted: CuraApplication.multiplyObject(base.objectId, parseInt(copiesField.text))
property variant catalog: UM.I18nCatalog { name: "cura" }

View file

@ -0,0 +1,112 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
import QtQuick.Window 2.1
import UM 1.3 as UM
import Cura 1.0 as Cura
UM.Dialog
{
// This dialog asks the user whether he/she wants to open the project file we have detected or the model files.
id: base
title: catalog.i18nc("@title:window", "Open file(s)")
width: 420 * Screen.devicePixelRatio
height: 170 * Screen.devicePixelRatio
maximumHeight: height
maximumWidth: width
minimumHeight: height
minimumWidth: width
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
property var fileUrls: []
property int spacerHeight: 10
function loadProjectFile(projectFile)
{
UM.WorkspaceFileHandler.readLocalFile(projectFile);
var meshName = backgroundItem.getMeshName(projectFile.toString());
backgroundItem.hasMesh(decodeURIComponent(meshName));
}
function loadModelFiles(fileUrls)
{
for (var i in fileUrls)
{
CuraApplication.readLocalFile(fileUrls[i]);
}
var meshName = backgroundItem.getMeshName(fileUrls[0].toString());
backgroundItem.hasMesh(decodeURIComponent(meshName));
}
Column
{
anchors.fill: parent
anchors.leftMargin: 20 * Screen.devicePixelRatio
anchors.rightMargin: 20 * Screen.devicePixelRatio
anchors.bottomMargin: 20 * Screen.devicePixelRatio
anchors.left: parent.left
anchors.right: parent.right
spacing: 10 * Screen.devicePixelRatio
Text
{
text: catalog.i18nc("@text:window", "We have found one or more project file(s) within the files you have selected. You can open only one project file at a time. We suggest to only import models from those files. Would you like to proceed?")
anchors.left: parent.left
anchors.right: parent.right
font: UM.Theme.getFont("default")
wrapMode: Text.WordWrap
}
Item // Spacer
{
height: base.spacerHeight
width: height
}
// Buttons
Item
{
anchors.right: parent.right
anchors.left: parent.left
height: childrenRect.height
Button
{
id: cancelButton
text: catalog.i18nc("@action:button", "Cancel");
anchors.right: importAllAsModelsButton.left
onClicked:
{
// cancel
base.hide();
}
}
Button
{
id: importAllAsModelsButton
text: catalog.i18nc("@action:button", "Import all as models");
anchors.right: parent.right
isDefault: true
onClicked:
{
// load models from all selected file
loadModelFiles(base.fileUrls);
base.hide();
}
}
}
}
}

866
resources/qml/Preferences/GeneralPage.qml Normal file → Executable file
View file

@ -25,6 +25,30 @@ UM.PreferencesPage
}
}
function setDefaultDiscardOrKeepProfile(code)
{
for (var i = 0; i < choiceOnProfileOverrideDropDownButton.model.count; i++)
{
if (choiceOnProfileOverrideDropDownButton.model.get(i).code == code)
{
choiceOnProfileOverrideDropDownButton.currentIndex = i;
break;
}
}
}
function setDefaultOpenProjectOption(code)
{
for (var i = 0; i < choiceOnOpenProjectDropDownButton.model.count; ++i)
{
if (choiceOnOpenProjectDropDownButton.model.get(i).code == code)
{
choiceOnOpenProjectDropDownButton.currentIndex = i
break;
}
}
}
function reset()
{
UM.Preferences.resetPreference("general/language")
@ -45,9 +69,17 @@ UM.PreferencesPage
showOverhangCheckbox.checked = boolCheck(UM.Preferences.getValue("view/show_overhang"))
UM.Preferences.resetPreference("view/center_on_select");
centerOnSelectCheckbox.checked = boolCheck(UM.Preferences.getValue("view/center_on_select"))
UM.Preferences.resetPreference("view/invert_zoom");
invertZoomCheckbox.checked = boolCheck(UM.Preferences.getValue("view/invert_zoom"))
UM.Preferences.resetPreference("view/top_layer_count");
topLayerCountCheckbox.checked = boolCheck(UM.Preferences.getValue("view/top_layer_count"))
UM.Preferences.resetPreference("cura/choice_on_profile_override")
setDefaultDiscardOrKeepProfile(UM.Preferences.getValue("cura/choice_on_profile_override"))
UM.Preferences.resetPreference("cura/choice_on_open_project")
setDefaultOpenProjectOption(UM.Preferences.getValue("cura/choice_on_open_project"))
if (plugins.find("id", "SliceInfoPlugin") > -1) {
UM.Preferences.resetPreference("info/send_slice_info")
sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info"))
@ -58,390 +90,552 @@ UM.PreferencesPage
}
}
Column
ScrollView
{
//: Model used to check if a plugin exists
UM.PluginsModel { id: plugins }
width: parent.width
height: parent.height
//: Language selection label
UM.I18nCatalog{id: catalog; name:"cura"}
Label
Column
{
font.bold: true
text: catalog.i18nc("@label","Interface")
}
//: Model used to check if a plugin exists
UM.PluginsModel { id: plugins }
//: Language selection label
UM.I18nCatalog{id: catalog; name:"cura"}
Row
{
spacing: UM.Theme.getSize("default_margin").width
Label
{
id: languageLabel
text: catalog.i18nc("@label","Language:")
anchors.verticalCenter: languageComboBox.verticalCenter
font.bold: true
text: catalog.i18nc("@label","Interface")
}
ComboBox
Row
{
id: languageComboBox
model: ListModel
spacing: UM.Theme.getSize("default_margin").width
Label
{
id: languageList
Component.onCompleted: {
append({ text: "English", code: "en" })
append({ text: "Deutsch", code: "de" })
append({ text: "Español", code: "es" })
append({ text: "Suomi", code: "fi" })
append({ text: "Français", code: "fr" })
append({ text: "Italiano", code: "it" })
append({ text: "Nederlands", code: "nl" })
append({ text: "Português do Brasil", code: "ptbr" })
append({ text: "Русский", code: "ru" })
append({ text: "Türkçe", code: "tr" })
}
id: languageLabel
text: catalog.i18nc("@label","Language:")
anchors.verticalCenter: languageComboBox.verticalCenter
}
currentIndex:
ComboBox
{
var code = UM.Preferences.getValue("general/language");
for(var i = 0; i < languageList.count; ++i)
id: languageComboBox
model: ListModel
{
if(model.get(i).code == code)
{
return i
id: languageList
Component.onCompleted: {
append({ text: "English", code: "en" })
append({ text: "Deutsch", code: "de" })
append({ text: "Español", code: "es" })
append({ text: "Suomi", code: "fi" })
append({ text: "Français", code: "fr" })
append({ text: "Italiano", code: "it" })
append({ text: "Nederlands", code: "nl" })
append({ text: "Português do Brasil", code: "ptbr" })
append({ text: "Русский", code: "ru" })
append({ text: "Türkçe", code: "tr" })
}
}
}
onActivated: UM.Preferences.setValue("general/language", model.get(index).code)
Component.onCompleted:
{
// Because ListModel is stupid and does not allow using qsTr() for values.
for(var i = 0; i < languageList.count; ++i)
currentIndex:
{
languageList.setProperty(i, "text", catalog.i18n(languageList.get(i).text));
}
// Glorious hack time. ComboBox does not update the text properly after changing the
// model. So change the indices around to force it to update.
currentIndex += 1;
currentIndex -= 1;
}
}
Label
{
id: currencyLabel
text: catalog.i18nc("@label","Currency:")
anchors.verticalCenter: languageComboBox.verticalCenter
}
TextField
{
id: currencyField
text: UM.Preferences.getValue("cura/currency")
onTextChanged: UM.Preferences.setValue("cura/currency", text)
}
}
Label
{
id: languageCaption
//: Language change warning
text: catalog.i18nc("@label", "You will need to restart the application for language changes to have effect.")
wrapMode: Text.WordWrap
font.italic: true
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").width
}
Row
{
spacing: UM.Theme.getSize("default_margin").width
Label
{
id: themeLabel
text: catalog.i18nc("@label","Theme:")
anchors.verticalCenter: themeComboBox.verticalCenter
}
ComboBox
{
id: themeComboBox
model: ListModel
{
id: themeList
Component.onCompleted: {
append({ text: catalog.i18nc("@item:inlistbox", "Ultimaker"), code: "cura" })
}
}
currentIndex:
{
var code = UM.Preferences.getValue("general/theme");
for(var i = 0; i < themeList.count; ++i)
{
if(model.get(i).code == code)
var code = UM.Preferences.getValue("general/language");
for(var i = 0; i < languageList.count; ++i)
{
return i
if(model.get(i).code == code)
{
return i
}
}
}
}
onActivated: UM.Preferences.setValue("general/theme", model.get(index).code)
onActivated: UM.Preferences.setValue("general/language", model.get(index).code)
Component.onCompleted:
Component.onCompleted:
{
// Because ListModel is stupid and does not allow using qsTr() for values.
for(var i = 0; i < languageList.count; ++i)
{
languageList.setProperty(i, "text", catalog.i18n(languageList.get(i).text));
}
// Glorious hack time. ComboBox does not update the text properly after changing the
// model. So change the indices around to force it to update.
currentIndex += 1;
currentIndex -= 1;
}
}
Label
{
// Because ListModel is stupid and does not allow using qsTr() for values.
for(var i = 0; i < themeList.count; ++i)
{
themeList.setProperty(i, "text", catalog.i18n(themeList.get(i).text));
}
// Glorious hack time. ComboBox does not update the text properly after changing the
// model. So change the indices around to force it to update.
currentIndex += 1;
currentIndex -= 1;
id: currencyLabel
text: catalog.i18nc("@label","Currency:")
anchors.verticalCenter: languageComboBox.verticalCenter
}
}
}
Label
{
id: themeCaption
//: Theme change warning
text: catalog.i18nc("@label", "You will need to restart the application for theme changes to have effect.")
wrapMode: Text.WordWrap
font.italic: true
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").width
}
Label
{
font.bold: true
text: catalog.i18nc("@label","Viewport behavior")
}
UM.TooltipArea
{
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Highlight unsupported areas of the model in red. Without support these areas will not print properly.")
CheckBox
{
id: showOverhangCheckbox
checked: boolCheck(UM.Preferences.getValue("view/show_overhang"))
onClicked: UM.Preferences.setValue("view/show_overhang", checked)
text: catalog.i18nc("@option:check","Display overhang");
}
}
UM.TooltipArea {
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Moves the camera so the model is in the center of the view when an model is selected")
CheckBox
{
id: centerOnSelectCheckbox
text: catalog.i18nc("@action:button","Center camera when item is selected");
checked: boolCheck(UM.Preferences.getValue("view/center_on_select"))
onClicked: UM.Preferences.setValue("view/center_on_select", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should models on the platform be moved so that they no longer intersect?")
CheckBox
{
id: pushFreeCheckbox
text: catalog.i18nc("@option:check", "Ensure models are kept apart")
checked: boolCheck(UM.Preferences.getValue("physics/automatic_push_free"))
onCheckedChanged: UM.Preferences.setValue("physics/automatic_push_free", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should models on the platform be moved down to touch the build plate?")
CheckBox
{
id: dropDownCheckbox
text: catalog.i18nc("@option:check", "Automatically drop models to the build plate")
checked: boolCheck(UM.Preferences.getValue("physics/automatic_drop_down"))
onCheckedChanged: UM.Preferences.setValue("physics/automatic_drop_down", checked)
}
}
UM.TooltipArea {
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Display 5 top layers in layer view or only the top-most layer. Rendering 5 layers takes longer, but may show more information.")
CheckBox
{
id: topLayerCountCheckbox
text: catalog.i18nc("@action:button","Display five top layers in layer view");
checked: UM.Preferences.getValue("view/top_layer_count") == 5
onClicked:
TextField
{
if(UM.Preferences.getValue("view/top_layer_count") == 5)
id: currencyField
text: UM.Preferences.getValue("cura/currency")
onTextChanged: UM.Preferences.setValue("cura/currency", text)
}
}
Label
{
id: languageCaption
//: Language change warning
text: catalog.i18nc("@label", "You will need to restart the application for language changes to have effect.")
wrapMode: Text.WordWrap
font.italic: true
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").width
}
Row
{
spacing: UM.Theme.getSize("default_margin").width
Label
{
id: themeLabel
text: catalog.i18nc("@label","Theme:")
anchors.verticalCenter: themeComboBox.verticalCenter
}
ComboBox
{
id: themeComboBox
model: ListModel
{
id: themeList
Component.onCompleted: {
append({ text: catalog.i18nc("@item:inlistbox", "Ultimaker"), code: "cura" })
}
}
currentIndex:
{
var code = UM.Preferences.getValue("general/theme");
for(var i = 0; i < themeList.count; ++i)
{
if(model.get(i).code == code)
{
return i
}
}
}
onActivated: UM.Preferences.setValue("general/theme", model.get(index).code)
Component.onCompleted:
{
// Because ListModel is stupid and does not allow using qsTr() for values.
for(var i = 0; i < themeList.count; ++i)
{
themeList.setProperty(i, "text", catalog.i18n(themeList.get(i).text));
}
// Glorious hack time. ComboBox does not update the text properly after changing the
// model. So change the indices around to force it to update.
currentIndex += 1;
currentIndex -= 1;
}
}
}
Label
{
id: themeCaption
//: Theme change warning
text: catalog.i18nc("@label", "You will need to restart the application for theme changes to have effect.")
wrapMode: Text.WordWrap
font.italic: true
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").width
}
Label
{
font.bold: true
text: catalog.i18nc("@label","Viewport behavior")
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").width
}
UM.TooltipArea
{
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Slice automatically when changing settings.")
CheckBox
{
id: autoSliceCheckbox
checked: boolCheck(UM.Preferences.getValue("general/auto_slice"))
onClicked: UM.Preferences.setValue("general/auto_slice", checked)
text: catalog.i18nc("@option:check","Slice automatically");
}
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").width
}
Label
{
font.bold: true
text: catalog.i18nc("@label","Viewport behavior")
}
UM.TooltipArea
{
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Highlight unsupported areas of the model in red. Without support these areas will not print properly.")
CheckBox
{
id: showOverhangCheckbox
checked: boolCheck(UM.Preferences.getValue("view/show_overhang"))
onClicked: UM.Preferences.setValue("view/show_overhang", checked)
text: catalog.i18nc("@option:check","Display overhang");
}
}
UM.TooltipArea {
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Moves the camera so the model is in the center of the view when an model is selected")
CheckBox
{
id: centerOnSelectCheckbox
text: catalog.i18nc("@action:button","Center camera when item is selected");
checked: boolCheck(UM.Preferences.getValue("view/center_on_select"))
onClicked: UM.Preferences.setValue("view/center_on_select", checked)
enabled: Qt.platform.os != "windows" // Hack: disable the feature on windows as it's broken for pyqt 5.7.1.
}
}
UM.TooltipArea {
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Should the default zoom behavior of cura be inverted?")
CheckBox
{
id: invertZoomCheckbox
text: catalog.i18nc("@action:button","Invert the direction of camera zoom.");
checked: boolCheck(UM.Preferences.getValue("view/invert_zoom"))
onClicked: UM.Preferences.setValue("view/invert_zoom", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should models on the platform be moved so that they no longer intersect?")
CheckBox
{
id: pushFreeCheckbox
text: catalog.i18nc("@option:check", "Ensure models are kept apart")
checked: boolCheck(UM.Preferences.getValue("physics/automatic_push_free"))
onCheckedChanged: UM.Preferences.setValue("physics/automatic_push_free", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should models on the platform be moved down to touch the build plate?")
CheckBox
{
id: dropDownCheckbox
text: catalog.i18nc("@option:check", "Automatically drop models to the build plate")
checked: boolCheck(UM.Preferences.getValue("physics/automatic_drop_down"))
onCheckedChanged: UM.Preferences.setValue("physics/automatic_drop_down", checked)
}
}
UM.TooltipArea
{
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip","Show caution message in gcode reader.")
CheckBox
{
id: gcodeShowCautionCheckbox
checked: boolCheck(UM.Preferences.getValue("gcodereader/show_caution"))
onClicked: UM.Preferences.setValue("gcodereader/show_caution", checked)
text: catalog.i18nc("@option:check","Caution message in gcode reader");
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should layer be forced into compatibility mode?")
CheckBox
{
id: forceLayerViewCompatibilityModeCheckbox
text: catalog.i18nc("@option:check", "Force layer view compatibility mode (restart required)")
checked: boolCheck(UM.Preferences.getValue("view/force_layer_view_compatibility_mode"))
onCheckedChanged: UM.Preferences.setValue("view/force_layer_view_compatibility_mode", checked)
}
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").height
}
Label
{
font.bold: true
text: catalog.i18nc("@label","Opening and saving files")
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip","Should models be scaled to the build volume if they are too large?")
CheckBox
{
id: scaleToFitCheckbox
text: catalog.i18nc("@option:check","Scale large models")
checked: boolCheck(UM.Preferences.getValue("mesh/scale_to_fit"))
onCheckedChanged: UM.Preferences.setValue("mesh/scale_to_fit", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip","An model may appear extremely small if its unit is for example in meters rather than millimeters. Should these models be scaled up?")
CheckBox
{
id: scaleTinyCheckbox
text: catalog.i18nc("@option:check","Scale extremely small models")
checked: boolCheck(UM.Preferences.getValue("mesh/scale_tiny_meshes"))
onCheckedChanged: UM.Preferences.setValue("mesh/scale_tiny_meshes", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should a prefix based on the printer name be added to the print job name automatically?")
CheckBox
{
id: prefixJobNameCheckbox
text: catalog.i18nc("@option:check", "Add machine prefix to job name")
checked: boolCheck(UM.Preferences.getValue("cura/jobname_prefix"))
onCheckedChanged: UM.Preferences.setValue("cura/jobname_prefix", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should a summary be shown when saving a project file?")
CheckBox
{
text: catalog.i18nc("@option:check", "Show summary dialog when saving project")
checked: boolCheck(UM.Preferences.getValue("cura/dialog_on_project_save"))
onCheckedChanged: UM.Preferences.setValue("cura/dialog_on_project_save", checked)
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Default behavior when opening a project file")
Column
{
spacing: 4
Label
{
UM.Preferences.setValue("view/top_layer_count", 1)
text: catalog.i18nc("@window:text", "Default behavior when opening a project file: ")
}
else
ComboBox
{
UM.Preferences.setValue("view/top_layer_count", 5)
id: choiceOnOpenProjectDropDownButton
width: 200
model: ListModel
{
id: openProjectOptionModel
Component.onCompleted: {
append({ text: catalog.i18nc("@option:openProject", "Always ask"), code: "always_ask" })
append({ text: catalog.i18nc("@option:openProject", "Always open as a project"), code: "open_as_project" })
append({ text: catalog.i18nc("@option:openProject", "Always import models"), code: "open_as_model" })
}
}
currentIndex:
{
var index = 0;
var currentChoice = UM.Preferences.getValue("cura/choice_on_open_project");
for (var i = 0; i < model.count; ++i)
{
if (model.get(i).code == currentChoice)
{
index = i;
break;
}
}
return index;
}
onActivated: UM.Preferences.setValue("cura/choice_on_open_project", model.get(index).code)
}
}
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should only the top layers be displayed in layerview?")
CheckBox
Item
{
id: topLayersOnlyCheckbox
text: catalog.i18nc("@option:check", "Only display top layer(s) in layer view")
checked: boolCheck(UM.Preferences.getValue("view/only_show_top_layers"))
onCheckedChanged: UM.Preferences.setValue("view/only_show_top_layers", checked)
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").width
}
}
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").height
}
Label
{
font.bold: true
text: catalog.i18nc("@label","Opening files")
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip","Should models be scaled to the build volume if they are too large?")
CheckBox
UM.TooltipArea
{
id: scaleToFitCheckbox
text: catalog.i18nc("@option:check","Scale large models")
checked: boolCheck(UM.Preferences.getValue("mesh/scale_to_fit"))
onCheckedChanged: UM.Preferences.setValue("mesh/scale_to_fit", checked)
width: childrenRect.width;
height: childrenRect.height;
text: catalog.i18nc("@info:tooltip", "When you have made changes to a profile and switched to a different one, a dialog will be shown asking whether you want to keep your modifications or not, or you can choose a default behaviour and never show that dialog again.")
Column
{
spacing: 4
Label
{
font.bold: true
text: catalog.i18nc("@label", "Override Profile")
}
ComboBox
{
id: choiceOnProfileOverrideDropDownButton
width: 200
model: ListModel
{
id: discardOrKeepProfileListModel
Component.onCompleted: {
append({ text: catalog.i18nc("@option:discardOrKeep", "Always ask me this"), code: "always_ask" })
append({ text: catalog.i18nc("@option:discardOrKeep", "Discard and never ask again"), code: "always_discard" })
append({ text: catalog.i18nc("@option:discardOrKeep", "Keep and never ask again"), code: "always_keep" })
}
}
currentIndex:
{
var index = 0;
var code = UM.Preferences.getValue("cura/choice_on_profile_override");
for (var i = 0; i < model.count; ++i)
{
if (model.get(i).code == code)
{
index = i;
break;
}
}
return index;
}
onActivated: UM.Preferences.setValue("cura/choice_on_profile_override", model.get(index).code)
}
}
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip","An model may appear extremely small if its unit is for example in meters rather than millimeters. Should these models be scaled up?")
CheckBox
Item
{
id: scaleTinyCheckbox
text: catalog.i18nc("@option:check","Scale extremely small models")
checked: boolCheck(UM.Preferences.getValue("mesh/scale_tiny_meshes"))
onCheckedChanged: UM.Preferences.setValue("mesh/scale_tiny_meshes", checked)
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").height
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should a prefix based on the printer name be added to the print job name automatically?")
CheckBox
Label
{
id: prefixJobNameCheckbox
text: catalog.i18nc("@option:check", "Add machine prefix to job name")
checked: boolCheck(UM.Preferences.getValue("cura/jobname_prefix"))
onCheckedChanged: UM.Preferences.setValue("cura/jobname_prefix", checked)
font.bold: true
visible: checkUpdatesCheckbox.visible || sendDataCheckbox.visible
text: catalog.i18nc("@label","Privacy")
}
}
UM.TooltipArea {
width: childrenRect.width
height: childrenRect.height
text: catalog.i18nc("@info:tooltip", "Should a summary be shown when saving a project file?")
UM.TooltipArea {
visible: plugins.find("id", "UpdateChecker") > -1
width: childrenRect.width
height: visible ? childrenRect.height : 0
text: catalog.i18nc("@info:tooltip","Should Cura check for updates when the program is started?")
CheckBox
{
text: catalog.i18nc("@option:check", "Show summary dialog when saving project")
checked: boolCheck(UM.Preferences.getValue("cura/dialog_on_project_save"))
onCheckedChanged: UM.Preferences.setValue("cura/dialog_on_project_save", checked)
CheckBox
{
id: checkUpdatesCheckbox
text: catalog.i18nc("@option:check","Check for updates on start")
checked: boolCheck(UM.Preferences.getValue("info/automatic_update_check"))
onCheckedChanged: UM.Preferences.setValue("info/automatic_update_check", checked)
}
}
}
UM.TooltipArea {
visible: plugins.find("id", "SliceInfoPlugin") > -1
width: childrenRect.width
height: visible ? childrenRect.height : 0
text: catalog.i18nc("@info:tooltip","Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored.")
Item
{
//: Spacer
height: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("default_margin").height
}
Label
{
font.bold: true
visible: checkUpdatesCheckbox.visible || sendDataCheckbox.visible
text: catalog.i18nc("@label","Privacy")
}
UM.TooltipArea {
visible: plugins.find("id", "UpdateChecker") > -1
width: childrenRect.width
height: visible ? childrenRect.height : 0
text: catalog.i18nc("@info:tooltip","Should Cura check for updates when the program is started?")
CheckBox
{
id: checkUpdatesCheckbox
text: catalog.i18nc("@option:check","Check for updates on start")
checked: boolCheck(UM.Preferences.getValue("info/automatic_update_check"))
onCheckedChanged: UM.Preferences.setValue("info/automatic_update_check", checked)
}
}
UM.TooltipArea {
visible: plugins.find("id", "SliceInfoPlugin") > -1
width: childrenRect.width
height: visible ? childrenRect.height : 0
text: catalog.i18nc("@info:tooltip","Should anonymous data about your print be sent to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored.")
CheckBox
{
id: sendDataCheckbox
text: catalog.i18nc("@option:check","Send (anonymous) print information")
checked: boolCheck(UM.Preferences.getValue("info/send_slice_info"))
onCheckedChanged: UM.Preferences.setValue("info/send_slice_info", checked)
CheckBox
{
id: sendDataCheckbox
text: catalog.i18nc("@option:check","Send (anonymous) print information")
checked: boolCheck(UM.Preferences.getValue("info/send_slice_info"))
onCheckedChanged: UM.Preferences.setValue("info/send_slice_info", checked)
}
}
}
}

View file

@ -43,7 +43,7 @@ UM.ManagementPage
{
text: catalog.i18nc("@action:button", "Add");
iconName: "list-add";
onClicked: Printer.requestAddPrinter()
onClicked: CuraApplication.requestAddPrinter()
},
Button
{
@ -66,7 +66,7 @@ UM.ManagementPage
visible: base.currentItem != null
anchors.fill: parent
Label
Text
{
id: machineName
text: base.currentItem && base.currentItem.name ? base.currentItem.name : ""
@ -89,15 +89,20 @@ UM.ManagementPage
id: machineActionRepeater
model: base.currentItem ? Cura.MachineActionManager.getSupportedActions(Cura.MachineManager.getDefinitionByMachineId(base.currentItem.id)) : null
Button
Item
{
text: machineActionRepeater.model[index].label
onClicked:
width: childrenRect.width + 2
height: childrenRect.height
Button
{
actionDialog.content = machineActionRepeater.model[index].displayItem;
machineActionRepeater.model[index].displayItem.reset();
actionDialog.title = machineActionRepeater.model[index].label;
actionDialog.show();
text: machineActionRepeater.model[index].label
onClicked:
{
actionDialog.content = machineActionRepeater.model[index].displayItem;
machineActionRepeater.model[index].displayItem.reset();
actionDialog.title = machineActionRepeater.model[index].label;
actionDialog.show();
}
}
}
}
@ -141,26 +146,28 @@ UM.ManagementPage
property var connectedPrinter: printerConnected ? Cura.MachineManager.printerOutputDevices[0] : null
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
Label
Text
{
text: catalog.i18nc("@label", "Printer type:")
visible: base.currentItem && "definition_name" in base.currentItem.metadata
}
Label {
Text
{
text: (base.currentItem && "definition_name" in base.currentItem.metadata) ? base.currentItem.metadata.definition_name : ""
}
Label
Text
{
text: catalog.i18nc("@label", "Connection:")
visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId
}
Label {
Text
{
width: parent.width * 0.7
text: machineInfo.printerConnected ? machineInfo.connectedPrinter.connectionText : catalog.i18nc("@info:status", "The printer is not connected.")
visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId
wrapMode: Text.WordWrap
}
Label
Text
{
text: catalog.i18nc("@label", "State:")
visible: base.currentItem && base.currentItem.id == Cura.MachineManager.activeMachineId && machineInfo.printerAcceptsCommands
@ -211,8 +218,8 @@ UM.ManagementPage
Component.onCompleted:
{
for (var component in Printer.additionalComponents["machinesDetailPane"]) {
Printer.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn
for (var component in CuraApplication.additionalComponents["machinesDetailPane"]) {
CuraApplication.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn
}
}
}
@ -222,8 +229,8 @@ UM.ManagementPage
onAdditionalComponentsChanged:
{
if(areaId == "machinesDetailPane") {
for (var component in Printer.additionalComponents["machinesDetailPane"]) {
Printer.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn
for (var component in CuraApplication.additionalComponents["machinesDetailPane"]) {
CuraApplication.additionalComponents["machinesDetailPane"][component].parent = additionalComponentsColumn
}
}
}

View file

@ -153,10 +153,12 @@ TabView
value: base.getMaterialPreferenceValue(properties.guid, "spool_cost")
prefix: base.currency + " "
decimals: 2
maximumValue: 1000
maximumValue: 100000000
onEditingFinished: base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
onValueChanged: updateCostPerMeter()
onValueChanged: {
base.setMaterialPreferenceValue(properties.guid, "spool_cost", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament weight") }
@ -170,8 +172,10 @@ TabView
decimals: 0
maximumValue: 10000
onEditingFinished: base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
onValueChanged: updateCostPerMeter()
onValueChanged: {
base.setMaterialPreferenceValue(properties.guid, "spool_weight", parseFloat(value))
updateCostPerMeter()
}
}
Label { width: base.firstColumnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Filament length") }
@ -269,17 +273,28 @@ TabView
{
id: spinBox
anchors.left: label.right
value: parseFloat(provider.properties.value);
width: base.secondColumnWidth;
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
suffix: " " + model.unit
maximumValue: 99999
decimals: model.unit == "mm" ? 2 : 0
onEditingFinished: provider.setPropertyValue("value", value)
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
}
UM.ContainerPropertyProvider { id: provider; containerId: base.containerId; 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 }
}
}
}

View file

@ -18,7 +18,7 @@ UM.ManagementPage
{
filter:
{
var result = { "type": "material" }
var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value) }
if(Cura.MachineManager.filterMaterialsByMachine)
{
result.definition = Cura.MachineManager.activeQualityDefinitionId;
@ -128,7 +128,11 @@ UM.ManagementPage
text: catalog.i18nc("@action:button", "Activate");
iconName: "list-activate";
enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
onClicked: Cura.MachineManager.setActiveMaterial(base.currentItem.id)
onClicked:
{
Cura.MachineManager.setActiveMaterial(base.currentItem.id)
currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
}
},
Button
{
@ -323,6 +327,15 @@ UM.ManagementPage
id: messageDialog
}
UM.SettingPropertyProvider
{
id: materialDiameterProvider
containerStackId: Cura.MachineManager.activeMachineId
key: "material_diameter"
watchedProperties: [ "value" ]
}
UM.I18nCatalog { id: catalog; name: "cura"; }
SystemPalette { id: palette }
}

View file

@ -1,4 +1,4 @@
// Copyright (c) 2016 Ultimaker B.V.
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2
@ -12,7 +12,7 @@ import Cura 1.0 as Cura
Column
{
id: printMonitor
property var connectedPrinter: printerConnected ? Cura.MachineManager.printerOutputDevices[0] : null
property var connectedPrinter: Cura.MachineManager.printerOutputDevices.length >= 1 ? Cura.MachineManager.printerOutputDevices[0] : null
Cura.ExtrudersModel
{
@ -20,47 +20,611 @@ Column
simpleNames: true
}
Item
Rectangle
{
width: base.width - 2 * UM.Theme.getSize("default_margin").width
height: childrenRect.height + UM.Theme.getSize("default_margin").height
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
id: connectedPrinterHeader
width: parent.width
height: childrenRect.height + UM.Theme.getSize("default_margin").height * 2
color: UM.Theme.getColor("setting_category")
Label
Text
{
text: printerConnected ? connectedPrinter.connectionText : catalog.i18nc("@info:status", "The printer is not connected.")
color: printerConnected && printerAcceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
font: UM.Theme.getFont("default")
id: connectedPrinterNameLabel
text: connectedPrinter != null ? connectedPrinter.name : catalog.i18nc("@info:status", "No printer connected")
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
anchors.left: parent.left
anchors.top: parent.top
anchors.margins: UM.Theme.getSize("default_margin").width
}
Text
{
id: connectedPrinterAddressLabel
text: (connectedPrinter != null && connectedPrinter.address != null) ? connectedPrinter.address : ""
font: UM.Theme.getFont("small")
color: UM.Theme.getColor("text_inactive")
anchors.top: parent.top
anchors.right: parent.right
anchors.margins: UM.Theme.getSize("default_margin").width
}
Text
{
text: connectedPrinter != null ? connectedPrinter.connectionText : catalog.i18nc("@info:status", "The printer is not connected.")
color: connectedPrinter != null && connectedPrinter.acceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
font: UM.Theme.getFont("very_small")
wrapMode: Text.WordWrap
width: parent.width
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.top: connectedPrinterNameLabel.bottom
}
}
Loader
Rectangle
{
sourceComponent: monitorSection
property string label: catalog.i18nc("@label", "Temperatures")
}
Repeater
{
model: machineExtruderCount.properties.value
delegate: Loader
color: UM.Theme.getColor("sidebar_lining")
width: parent.width
height: childrenRect.height
Flow
{
sourceComponent: monitorItem
property string label: machineExtruderCount.properties.value > 1 ? extrudersModel.getItem(index).name : catalog.i18nc("@label", "Hotend")
property string value: printerConnected ? Math.round(connectedPrinter.hotendTemperatures[index]) + "°C" : ""
id: extrudersGrid
spacing: UM.Theme.getSize("sidebar_lining_thin").width
width: parent.width
Repeater
{
id: extrudersRepeater
model: machineExtruderCount.properties.value
delegate: Rectangle
{
id: extruderRectangle
color: UM.Theme.getColor("sidebar")
width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : extrudersGrid.width / 2 - UM.Theme.getSize("sidebar_lining_thin").width / 2
height: UM.Theme.getSize("sidebar_extruder_box").height
Text //Extruder name.
{
text: ExtruderManager.getExtruderName(index) != "" ? ExtruderManager.getExtruderName(index) : catalog.i18nc("@label", "Hotend")
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("default")
anchors.left: parent.left
anchors.top: parent.top
anchors.margins: UM.Theme.getSize("default_margin").width
}
Text //Temperature indication.
{
id: extruderTemperature
text: (connectedPrinter != null && connectedPrinter.hotendIds[index] != null && connectedPrinter.hotendTemperatures[index] != null) ? Math.round(connectedPrinter.hotendTemperatures[index]) + "°C" : ""
color: UM.Theme.getColor("text")
font: UM.Theme.getFont("large")
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: UM.Theme.getSize("default_margin").width
MouseArea //For tooltip.
{
id: extruderTemperatureTooltipArea
hoverEnabled: true
anchors.fill: parent
onHoveredChanged:
{
if (containsMouse)
{
base.showTooltip(
base,
{x: 0, y: parent.mapToItem(base, 0, -parent.height / 4).y},
catalog.i18nc("@tooltip", "The current temperature of this extruder.")
);
}
else
{
base.hideTooltip();
}
}
}
}
Rectangle //Material colour indication.
{
id: materialColor
width: materialName.height * 0.75
height: materialName.height * 0.75
color: (connectedPrinter != null && connectedPrinter.materialColors[index] != null && connectedPrinter.materialIds[index] != "") ? connectedPrinter.materialColors[index] : "#00000000"
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
visible: connectedPrinter != null && connectedPrinter.materialColors[index] != null && connectedPrinter.materialIds[index] != ""
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: materialName.verticalCenter
MouseArea //For tooltip.
{
id: materialColorTooltipArea
hoverEnabled: true
anchors.fill: parent
onHoveredChanged:
{
if (containsMouse)
{
base.showTooltip(
base,
{x: 0, y: parent.mapToItem(base, 0, -parent.height / 2).y},
catalog.i18nc("@tooltip", "The colour of the material in this extruder.")
);
}
else
{
base.hideTooltip();
}
}
}
}
Text //Material name.
{
id: materialName
text: (connectedPrinter != null && connectedPrinter.materialNames[index] != null && connectedPrinter.materialIds[index] != "") ? connectedPrinter.materialNames[index] : ""
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
anchors.left: materialColor.right
anchors.bottom: parent.bottom
anchors.margins: UM.Theme.getSize("default_margin").width
MouseArea //For tooltip.
{
id: materialNameTooltipArea
hoverEnabled: true
anchors.fill: parent
onHoveredChanged:
{
if (containsMouse)
{
base.showTooltip(
base,
{x: 0, y: parent.mapToItem(base, 0, 0).y},
catalog.i18nc("@tooltip", "The material in this extruder.")
);
}
else
{
base.hideTooltip();
}
}
}
}
Text //Variant name.
{
id: variantName
text: (connectedPrinter != null && connectedPrinter.hotendIds[index] != null) ? connectedPrinter.hotendIds[index] : ""
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: UM.Theme.getSize("default_margin").width
MouseArea //For tooltip.
{
id: variantNameTooltipArea
hoverEnabled: true
anchors.fill: parent
onHoveredChanged:
{
if (containsMouse)
{
base.showTooltip(
base,
{x: 0, y: parent.mapToItem(base, 0, -parent.height / 4).y},
catalog.i18nc("@tooltip", "The nozzle inserted in this extruder.")
);
}
else
{
base.hideTooltip();
}
}
}
}
}
}
}
}
Repeater
Rectangle
{
model: machineHeatedBed.properties.value == "True" ? 1 : 0
delegate: Loader
color: UM.Theme.getColor("sidebar_lining")
width: parent.width
height: UM.Theme.getSize("sidebar_lining_thin").width
}
Rectangle
{
color: UM.Theme.getColor("sidebar")
width: parent.width
height: machineHeatedBed.properties.value == "True" ? UM.Theme.getSize("sidebar_extruder_box").height : 0
visible: machineHeatedBed.properties.value == "True"
Text //Build plate label.
{
sourceComponent: monitorItem
property string label: catalog.i18nc("@label", "Build plate")
property string value: printerConnected ? Math.round(connectedPrinter.bedTemperature) + "°C" : ""
text: catalog.i18nc("@label", "Build plate")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
anchors.left: parent.left
anchors.top: parent.top
anchors.margins: UM.Theme.getSize("default_margin").width
}
Text //Target temperature.
{
id: bedTargetTemperature
text: connectedPrinter != null ? connectedPrinter.targetBedTemperature + "°C" : ""
font: UM.Theme.getFont("small")
color: UM.Theme.getColor("text_inactive")
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.bottom: bedCurrentTemperature.bottom
MouseArea //For tooltip.
{
id: bedTargetTemperatureTooltipArea
hoverEnabled: true
anchors.fill: parent
onHoveredChanged:
{
if (containsMouse)
{
base.showTooltip(
base,
{x: 0, y: bedTargetTemperature.mapToItem(base, 0, -parent.height / 4).y},
catalog.i18nc("@tooltip", "The target temperature of the heated bed. The bed will heat up or cool down towards this temperature. If this is 0, the bed heating is turned off.")
);
}
else
{
base.hideTooltip();
}
}
}
}
Text //Current temperature.
{
id: bedCurrentTemperature
text: connectedPrinter != null ? connectedPrinter.bedTemperature + "°C" : ""
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
anchors.right: bedTargetTemperature.left
anchors.top: parent.top
anchors.margins: UM.Theme.getSize("default_margin").width
MouseArea //For tooltip.
{
id: bedTemperatureTooltipArea
hoverEnabled: true
anchors.fill: parent
onHoveredChanged:
{
if (containsMouse)
{
base.showTooltip(
base,
{x: 0, y: bedCurrentTemperature.mapToItem(base, 0, -parent.height / 4).y},
catalog.i18nc("@tooltip", "The current temperature of the heated bed.")
);
}
else
{
base.hideTooltip();
}
}
}
}
Rectangle //Input field for pre-heat temperature.
{
id: preheatTemperatureControl
color: !enabled ? UM.Theme.getColor("setting_control_disabled") : UM.Theme.getColor("setting_validation_ok")
enabled:
{
if (connectedPrinter == null)
{
return false; //Can't preheat if not connected.
}
if (!connectedPrinter.acceptsCommands)
{
return false; //Not allowed to do anything.
}
if (connectedPrinter.jobState == "printing" || connectedPrinter.jobState == "pre_print" || connectedPrinter.jobState == "resuming" || connectedPrinter.jobState == "pausing" || connectedPrinter.jobState == "paused" || connectedPrinter.jobState == "error" || connectedPrinter.jobState == "offline")
{
return false; //Printer is in a state where it can't react to pre-heating.
}
return true;
}
border.width: UM.Theme.getSize("default_lining").width
border.color: !enabled ? UM.Theme.getColor("setting_control_disabled_border") : preheatTemperatureInputMouseArea.containsMouse ? UM.Theme.getColor("setting_control_border_highlight") : UM.Theme.getColor("setting_control_border")
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.bottom: parent.bottom
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
width: UM.Theme.getSize("setting_control").width
height: UM.Theme.getSize("setting_control").height
Rectangle //Highlight of input field.
{
anchors.fill: parent
anchors.margins: UM.Theme.getSize("default_lining").width
color: UM.Theme.getColor("setting_control_highlight")
opacity: preheatTemperatureControl.hovered ? 1.0 : 0
}
Text //Maximum temperature indication.
{
text: (bedTemperature.properties.maximum_value != "None" ? bedTemperature.properties.maximum_value : "") + "°C"
color: UM.Theme.getColor("setting_unit")
font: UM.Theme.getFont("default")
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
anchors.verticalCenter: parent.verticalCenter
}
MouseArea //Change cursor on hovering.
{
id: preheatTemperatureInputMouseArea
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.IBeamCursor
onHoveredChanged:
{
if (containsMouse)
{
base.showTooltip(
base,
{x: 0, y: preheatTemperatureInputMouseArea.mapToItem(base, 0, 0).y},
catalog.i18nc("@tooltip of temperature input", "The temperature to pre-heat the bed to.")
);
}
else
{
base.hideTooltip();
}
}
}
TextInput
{
id: preheatTemperatureInput
font: UM.Theme.getFont("default")
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
selectByMouse: true
maximumLength: 10
enabled: parent.enabled
validator: RegExpValidator { regExp: /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } //Floating point regex.
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("setting_unit_margin").width
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
Component.onCompleted:
{
if ((bedTemperature.resolve != "None" && bedTemperature.resolve) && (bedTemperature.stackLevels[0] != 0) && (bedTemperature.stackLevels[0] != 1))
{
// We have a resolve function. Indicates that the setting is not settable per extruder and that
// we have to choose between the resolved value (default) and the global value
// (if user has explicitly set this).
text = bedTemperature.resolve;
}
else
{
text = bedTemperature.properties.value;
}
}
}
}
UM.RecolorImage
{
id: preheatCountdownIcon
width: UM.Theme.getSize("save_button_specs_icons").width
height: UM.Theme.getSize("save_button_specs_icons").height
sourceSize.width: width
sourceSize.height: height
color: UM.Theme.getColor("text")
visible: preheatCountdown.visible
source: UM.Theme.getIcon("print_time")
anchors.right: preheatCountdown.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2
anchors.verticalCenter: preheatCountdown.verticalCenter
}
Timer
{
id: preheatUpdateTimer
interval: 100 //Update every 100ms. You want to update every 1s, but then you have one timer for the updating running out of sync with the actual date timer and you might skip seconds.
running: connectedPrinter != null && connectedPrinter.preheatBedRemainingTime != ""
repeat: true
onTriggered: update()
property var endTime: new Date() //Set initial endTime to be the current date, so that the endTime has initially already passed and the timer text becomes invisible if you were to update.
function update()
{
preheatCountdown.text = ""
if (connectedPrinter != null)
{
preheatCountdown.text = connectedPrinter.preheatBedRemainingTime;
}
if (preheatCountdown.text == "") //Either time elapsed or not connected.
{
stop();
}
}
}
Text
{
id: preheatCountdown
text: connectedPrinter != null ? connectedPrinter.preheatBedRemainingTime : ""
visible: text != "" //Has no direct effect, but just so that we can link visibility of clock icon to visibility of the countdown text.
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
anchors.right: preheatButton.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: preheatButton.verticalCenter
}
Button //The pre-heat button.
{
id: preheatButton
height: UM.Theme.getSize("setting_control").height
enabled:
{
if (!preheatTemperatureControl.enabled)
{
return false; //Not connected, not authenticated or printer is busy.
}
if (preheatUpdateTimer.running)
{
return true; //Can always cancel if the timer is running.
}
if (bedTemperature.properties.minimum_value != "None" && parseInt(preheatTemperatureInput.text) < parseInt(bedTemperature.properties.minimum_value))
{
return false; //Target temperature too low.
}
if (bedTemperature.properties.maximum_value != "None" && parseInt(preheatTemperatureInput.text) > parseInt(bedTemperature.properties.maximum_value))
{
return false; //Target temperature too high.
}
if (parseInt(preheatTemperatureInput.text) == 0)
{
return false; //Setting the temperature to 0 is not allowed (since that cancels the pre-heating).
}
return true; //Preconditions are met.
}
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: UM.Theme.getSize("default_margin").width
style: ButtonStyle {
background: Rectangle
{
border.width: UM.Theme.getSize("default_lining").width
implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2)
border.color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_border");
}
else if(control.pressed)
{
return UM.Theme.getColor("action_button_active_border");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_border");
}
else
{
return UM.Theme.getColor("action_button_border");
}
}
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled");
}
else if(control.pressed)
{
return UM.Theme.getColor("action_button_active");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered");
}
else
{
return UM.Theme.getColor("action_button");
}
}
Behavior on color
{
ColorAnimation
{
duration: 50
}
}
Text
{
id: actualLabel
anchors.centerIn: parent
color:
{
if(!control.enabled)
{
return UM.Theme.getColor("action_button_disabled_text");
}
else if(control.pressed)
{
return UM.Theme.getColor("action_button_active_text");
}
else if(control.hovered)
{
return UM.Theme.getColor("action_button_hovered_text");
}
else
{
return UM.Theme.getColor("action_button_text");
}
}
font: UM.Theme.getFont("action_button")
text: preheatUpdateTimer.running ? catalog.i18nc("@button Cancel pre-heating", "Cancel") : catalog.i18nc("@button", "Pre-heat")
}
}
}
onClicked:
{
if (!preheatUpdateTimer.running)
{
connectedPrinter.preheatBed(preheatTemperatureInput.text, connectedPrinter.preheatBedTimeout);
preheatUpdateTimer.start();
preheatUpdateTimer.update(); //Update once before the first timer is triggered.
}
else
{
connectedPrinter.cancelPreheatBed();
preheatUpdateTimer.update();
}
}
onHoveredChanged:
{
if (hovered)
{
base.showTooltip(
base,
{x: 0, y: preheatButton.mapToItem(base, 0, 0).y},
catalog.i18nc("@tooltip of pre-heat", "Heat the bed in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the bed to heat up when you're ready to print.")
);
}
else
{
base.hideTooltip();
}
}
}
}
UM.SettingPropertyProvider
{
id: bedTemperature
containerStackId: Cura.MachineManager.activeMachineId
key: "material_bed_temperature"
watchedProperties: ["value", "minimum_value", "maximum_value", "resolve"]
storeIndex: 0
property var resolve: Cura.MachineManager.activeStackId != Cura.MachineManager.activeMachineId ? properties.resolve : "None"
}
UM.SettingPropertyProvider
{
id: machineExtruderCount
containerStackId: Cura.MachineManager.activeMachineId
key: "machine_extruder_count"
watchedProperties: ["value"]
}
Loader
@ -72,19 +636,19 @@ Column
{
sourceComponent: monitorItem
property string label: catalog.i18nc("@label", "Job Name")
property string value: printerConnected ? connectedPrinter.jobName : ""
property string value: connectedPrinter != null ? connectedPrinter.jobName : ""
}
Loader
{
sourceComponent: monitorItem
property string label: catalog.i18nc("@label", "Printing Time")
property string value: printerConnected ? getPrettyTime(connectedPrinter.timeTotal) : ""
property string value: connectedPrinter != null ? getPrettyTime(connectedPrinter.timeTotal) : ""
}
Loader
{
sourceComponent: monitorItem
property string label: catalog.i18nc("@label", "Estimated time left")
property string value: printerConnected ? getPrettyTime(connectedPrinter.timeTotal - connectedPrinter.timeElapsed) : ""
property string value: connectedPrinter != null ? getPrettyTime(connectedPrinter.timeTotal - connectedPrinter.timeElapsed) : ""
}
Component
@ -98,21 +662,21 @@ Column
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
Label
Text
{
width: parent.width * 0.4
anchors.verticalCenter: parent.verticalCenter
text: label
color: printerConnected && printerAcceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
color: connectedPrinter != null && connectedPrinter.acceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
font: UM.Theme.getFont("default")
elide: Text.ElideRight
}
Label
Text
{
width: parent.width * 0.6
anchors.verticalCenter: parent.verticalCenter
text: value
color: printerConnected && printerAcceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
color: connectedPrinter != null && connectedPrinter.acceptsCommands ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
font: UM.Theme.getFont("default")
elide: Text.ElideRight
}
@ -125,10 +689,10 @@ Column
Rectangle
{
color: UM.Theme.getColor("setting_category")
width: base.width - 2 * UM.Theme.getSize("default_margin").width
width: base.width
height: UM.Theme.getSize("section").height
Label
Text
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left

View file

@ -14,7 +14,10 @@ Item {
property real progress: UM.Backend.progress;
property int backendState: UM.Backend.state;
property bool activity: Printer.getPlatformActivity;
property var backend: CuraApplication.getBackend();
property bool activity: CuraApplication.platformActivity;
property int totalHeight: childrenRect.height + UM.Theme.getSize("default_margin").height
property string fileBaseName
property string statusText:
@ -27,7 +30,7 @@ Item {
switch(base.backendState)
{
case 1:
return catalog.i18nc("@label:PrintjobStatus", "Preparing to slice...");
return catalog.i18nc("@label:PrintjobStatus", "Ready to slice");
case 2:
return catalog.i18nc("@label:PrintjobStatus", "Slicing...");
case 3:
@ -41,7 +44,7 @@ Item {
}
}
Label {
Text {
id: statusLabel
width: parent.width - 2 * UM.Theme.getSize("default_margin").width
anchors.top: parent.top
@ -73,6 +76,18 @@ Item {
}
}
// Shortcut for "save as/print/..."
Action {
shortcut: "Ctrl+P"
onTriggered:
{
// only work when the button is enabled
if (saveToButton.enabled) {
saveToButton.clicked();
}
}
}
Item {
id: saveRow
width: base.width
@ -95,18 +110,114 @@ Item {
onAdditionalComponentsChanged:
{
if(areaId == "saveButton") {
for (var component in Printer.additionalComponents["saveButton"]) {
Printer.additionalComponents["saveButton"][component].parent = additionalComponentsRow
for (var component in CuraApplication.additionalComponents["saveButton"]) {
CuraApplication.additionalComponents["saveButton"][component].parent = additionalComponentsRow
}
}
}
}
Connections {
target: UM.Preferences
onPreferenceChanged:
{
var autoSlice = UM.Preferences.getValue("general/auto_slice");
prepareButton.autoSlice = autoSlice;
saveToButton.autoSlice = autoSlice;
}
}
// Prepare button, only shows if auto_slice is off
Button {
id: prepareButton
tooltip: UM.OutputDeviceManager.activeDeviceDescription;
// 1 = not started, 2 = Processing
enabled: (base.backendState == 1 || base.backendState == 2) && base.activity == true
visible: {
return !autoSlice && (base.backendState == 1 || base.backendState == 2) && base.activity == true;
}
property bool autoSlice
height: UM.Theme.getSize("save_button_save_to_button").height
anchors.top: parent.top
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
// 1 = not started, 5 = disabled
text: [1, 5].indexOf(UM.Backend.state) != -1 ? catalog.i18nc("@label:Printjob", "Prepare") : catalog.i18nc("@label:Printjob", "Cancel")
onClicked:
{
if ([1, 5].indexOf(UM.Backend.state) != -1) {
backend.forceSlice();
} else {
backend.stopSlicing();
}
}
style: ButtonStyle {
background: Rectangle
{
border.width: UM.Theme.getSize("default_lining").width
border.color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_border");
else if(control.pressed)
return UM.Theme.getColor("action_button_active_border");
else if(control.hovered)
return UM.Theme.getColor("action_button_hovered_border");
else
return UM.Theme.getColor("action_button_border");
}
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled");
else if(control.pressed)
return UM.Theme.getColor("action_button_active");
else if(control.hovered)
return UM.Theme.getColor("action_button_hovered");
else
return UM.Theme.getColor("action_button");
}
Behavior on color { ColorAnimation { duration: 50; } }
implicitWidth: actualLabel.contentWidth + (UM.Theme.getSize("default_margin").width * 2)
Label {
id: actualLabel
anchors.centerIn: parent
color:
{
if(!control.enabled)
return UM.Theme.getColor("action_button_disabled_text");
else if(control.pressed)
return UM.Theme.getColor("action_button_active_text");
else if(control.hovered)
return UM.Theme.getColor("action_button_hovered_text");
else
return UM.Theme.getColor("action_button_text");
}
font: UM.Theme.getFont("action_button")
text: control.text;
}
}
label: Item { }
}
}
Button {
id: saveToButton
tooltip: UM.OutputDeviceManager.activeDeviceDescription;
// 3 = done, 5 = disabled
enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true
visible: {
return autoSlice || ((base.backendState == 3 || base.backendState == 5) && base.activity == true);
}
property bool autoSlice
height: UM.Theme.getSize("save_button_save_to_button").height
anchors.top: parent.top
@ -116,7 +227,7 @@ Item {
text: UM.OutputDeviceManager.activeDeviceShortDescription
onClicked:
{
UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, { "filter_by_machine": true })
UM.OutputDeviceManager.requestWriteToDevice(UM.OutputDeviceManager.activeDevice, PrintInformation.jobName, { "filter_by_machine": true, "preferred_mimetype":Printer.preferredOutputMimetype })
}
style: ButtonStyle {
@ -181,8 +292,9 @@ Item {
anchors.rightMargin: UM.Theme.getSize("default_margin").width
width: UM.Theme.getSize("save_button_save_to_button").height
height: UM.Theme.getSize("save_button_save_to_button").height
// 3 = Done, 5 = Disabled
enabled: (base.backendState == 3 || base.backendState == 5) && base.activity == true
visible: devicesModel.deviceCount > 1
visible: (devicesModel.deviceCount > 1) && (base.backendState == 3 || base.backendState == 5) && base.activity == true
style: ButtonStyle {

View file

@ -95,13 +95,17 @@ SettingItem
value:
{
// FIXME this needs to go away once 'resolve' is combined with 'value' in our data model.
var value;
if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1)) {
var value = undefined;
if ((base.resolve != "None") && (base.stackLevel != 0) && (base.stackLevel != 1))
{
// We have a resolve function. Indicates that the setting is not settable per extruder and that
// we have to choose between the resolved value (default) and the global value
// (if user has explicitly set this).
value = base.resolve;
} else {
}
if (value == undefined)
{
value = propertyProvider.properties.value;
}

View file

@ -98,9 +98,9 @@ SettingItem
selectByMouse: true;
maximumLength: 10;
maximumLength: (definition.type == "[int]") ? 20 : (definition.type == "str") ? -1 : 10;
validator: RegExpValidator { regExp: (definition.type == "int") ? /^-?[0-9]{0,10}$/ : /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ } // definition.type property from parent loader used to disallow fractional number entry
validator: RegExpValidator { regExp: (definition.type == "[int]") ? /^\[?(\s*-?[0-9]{0,9}\s*,)*(\s*-?[0-9]{0,9})\s*\]?$/ : (definition.type == "int") ? /^-?[0-9]{0,10}$/ : (definition.type == "float") ? /^-?[0-9]{0,9}[.,]?[0-9]{0,10}$/ : /^.*$/ } // definition.type property from parent loader used to disallow fractional number entry
Binding
{

View file

@ -18,23 +18,10 @@ Item
signal showTooltip(Item item, point location, string text);
signal hideTooltip();
function toggleFilterField()
{
filterContainer.visible = !filterContainer.visible
if(filterContainer.visible)
{
filter.forceActiveFocus();
}
else
{
filter.text = "";
}
}
Rectangle
{
id: filterContainer
visible: false
visible: true
border.width: UM.Theme.getSize("default_lining").width
border.color:
@ -70,7 +57,7 @@ Item
anchors.right: clearFilterButton.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
placeholderText: catalog.i18nc("@label:textbox", "Filter...")
placeholderText: catalog.i18nc("@label:textbox", "Search...")
style: TextFieldStyle
{
@ -168,14 +155,14 @@ Item
containerId: Cura.MachineManager.activeDefinitionId
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order", "support_mesh", "anti_overhang_mesh"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
expanded: Printer.expandedCategories
expanded: CuraApplication.expandedCategories
onExpandedChanged:
{
if(!findingSettings)
{
// Do not change expandedCategories preference while filtering settings
// because all categories are expanded while filtering
Printer.setExpandedCategories(expanded)
CuraApplication.setExpandedCategories(expanded)
}
}
onVisibilityChanged: Cura.SettingInheritanceManager.forceUpdate()
@ -217,6 +204,8 @@ Item
{
case "int":
return "SettingTextField.qml"
case "[int]":
return "SettingTextField.qml"
case "float":
return "SettingTextField.qml"
case "enum":
@ -310,7 +299,7 @@ Item
}
}
UM.I18nCatalog { id: catalog; name: "uranium"; }
UM.I18nCatalog { id: catalog; name: "cura"; }
add: Transition {
SequentialAnimation {

156
resources/qml/Sidebar.qml Normal file → Executable file
View file

@ -1,4 +1,4 @@
// Copyright (c) 2015 Ultimaker B.V.
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the AGPLv3 or higher.
import QtQuick 2.2
@ -15,7 +15,7 @@ Rectangle
id: base;
property int currentModeIndex;
property bool monitoringPrint: false
property bool monitoringPrint: false; // When adding more "tabs", one want to replace this bool with a ListModel
property bool hideSettings: PrintInformation.preSliced
Connections
{
@ -31,6 +31,7 @@ Rectangle
// Is there an output device for this printer?
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
property int backendState: UM.Backend.state;
color: UM.Theme.getColor("sidebar")
UM.I18nCatalog { id: catalog; name:"cura"}
@ -331,7 +332,7 @@ Rectangle
}
}
Label {
Text {
id: settingsModeLabel
text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox","Print Setup disabled\nG-code files cannot be modified");
anchors.left: parent.left
@ -361,7 +362,7 @@ Rectangle
anchors.left: parent.left
anchors.leftMargin: model.index * (settingsModeSelection.width / 2)
anchors.verticalCenter: parent.verticalCenter
width: 0.5 * parent.width - (model.showFilterButton ? toggleFilterButton.width : 0)
width: 0.5 * parent.width
text: model.text
exclusiveGroup: modeMenuGroup;
checkable: true;
@ -406,66 +407,82 @@ Rectangle
}
}
ExclusiveGroup { id: modeMenuGroup; }
ListView{
id: modesList
property var index: 0
model: modesListModel
delegate: wizardDelegate
anchors.top: parent.top
anchors.left: parent.left
width: parent.width
}
}
Button
{
id: toggleFilterButton
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.top: headerSeparator.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
height: settingsModeSelection.height
width: visible ? height : 0
visible: !monitoringPrint && !hideSettings && modesListModel.get(base.currentModeIndex) != undefined && modesListModel.get(base.currentModeIndex).showFilterButton
opacity: visible ? 1 : 0
onClicked: sidebarContents.currentItem.toggleFilterField()
style: ButtonStyle
Text
{
background: Rectangle
{
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("toggle_checked_border")
color: visible ? UM.Theme.getColor("toggle_checked") : UM.Theme.getColor("toggle_hovered")
Behavior on color { ColorAnimation { duration: 50; } }
}
label: UM.RecolorImage
{
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width / 2
id: toggleLeftText
anchors.right: modeToggleSwitch.left
anchors.rightMargin: UM.Theme.getSize("toggle_button_text_anchoring_margin").width
anchors.verticalCenter: parent.verticalCenter
text: ""
color: UM.Theme.getColor("toggle_active_text")
font: UM.Theme.getFont("default")
source: UM.Theme.getIcon("search")
color: UM.Theme.getColor("toggle_checked_text")
MouseArea
{
anchors.fill: parent
onClicked:
{
modeToggleSwitch.checked = false;
}
Component.onCompleted:
{
clicked.connect(modeToggleSwitch.clicked)
}
}
}
}
Label {
id: monitorLabel
text: catalog.i18nc("@label","Printer Monitor");
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width;
anchors.top: headerSeparator.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width * 0.45
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
visible: monitoringPrint
Switch
{
id: modeToggleSwitch
checked: false
anchors.right: toggleRightText.left
anchors.rightMargin: UM.Theme.getSize("toggle_button_text_anchoring_margin").width
anchors.verticalCenter: parent.verticalCenter
onClicked:
{
var index = 0;
if (checked)
{
index = 1;
}
updateActiveMode(index);
}
function updateActiveMode(index)
{
base.currentModeIndex = index;
UM.Preferences.setValue("cura/active_mode", index);
}
style: UM.Theme.styles.toggle_button
}
Text
{
id: toggleRightText
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: ""
color: UM.Theme.getColor("toggle_active_text")
font: UM.Theme.getFont("default")
MouseArea
{
anchors.fill: parent
onClicked:
{
modeToggleSwitch.checked = true;
}
Component.onCompleted:
{
clicked.connect(modeToggleSwitch.clicked)
}
}
}
}
StackView
@ -511,10 +528,8 @@ Rectangle
Loader
{
anchors.bottom: footerSeparator.top
anchors.top: monitorLabel.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.top: headerSeparator.bottom
anchors.left: base.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: base.right
source: monitoringPrint ? "PrintMonitor.qml": "SidebarContents.qml"
}
@ -529,6 +544,8 @@ Rectangle
anchors.bottomMargin: UM.Theme.getSize("default_margin").height
}
// SaveButton and MonitorButton are actually the bottom footer panels.
// "!monitoringPrint" currently means "show-settings-mode"
SaveButton
{
id: saveButton
@ -553,6 +570,7 @@ Rectangle
id: tooltip;
}
// Setting mode: Recommended or Custom
ListModel
{
id: modesListModel;
@ -581,21 +599,23 @@ Rectangle
modesListModel.append({
text: catalog.i18nc("@title:tab", "Recommended"),
tooltipText: catalog.i18nc("@tooltip", "<b>Recommended Print Setup</b><br/><br/>Print with the recommended settings for the selected printer, material and quality."),
item: sidebarSimple,
showFilterButton: false
item: sidebarSimple
})
modesListModel.append({
text: catalog.i18nc("@title:tab", "Custom"),
tooltipText: catalog.i18nc("@tooltip", "<b>Custom Print Setup</b><br/><br/>Print with finegrained control over every last bit of the slicing process."),
item: sidebarAdvanced,
showFilterButton: true
item: sidebarAdvanced
})
sidebarContents.push({ "item": modesListModel.get(base.currentModeIndex).item, "immediate": true });
var index = parseInt(UM.Preferences.getValue("cura/active_mode"))
if(index)
toggleLeftText.text = modesListModel.get(0).text;
toggleRightText.text = modesListModel.get(1).text;
var index = parseInt(UM.Preferences.getValue("cura/active_mode"));
if (index)
{
currentModeIndex = index;
modeToggleSwitch.checked = index > 0;
}
}
@ -618,4 +638,4 @@ Rectangle
watchedProperties: [ "value" ]
storeIndex: 0
}
}
}

View file

@ -128,7 +128,7 @@ Column
border.color: UM.Theme.getColor("setting_control_border")
}
Label
Text
{
anchors.verticalCenter: parent.verticalCenter
anchors.left: swatch.visible ? swatch.right : parent.left
@ -174,7 +174,7 @@ Column
rightMargin: UM.Theme.getSize("default_margin").width
}
Label
Text
{
id: variantLabel
text:
@ -272,7 +272,7 @@ Column
}
Label
Text
{
id: globalProfileLabel
text: catalog.i18nc("@label","Profile:");

View file

@ -33,7 +33,7 @@ Item
width: base.width * .45 - UM.Theme.getSize("default_margin").width
height: childrenRect.height
Label
Text
{
id: infillLabel
//: Infill selection label
@ -162,7 +162,7 @@ Item
}
}
}
Label
Text
{
id: infillLabel
font: UM.Theme.getFont("default")
@ -225,14 +225,14 @@ Item
anchors.right: parent.right
height: childrenRect.height
Label
Text
{
id: enableSupportLabel
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: enableSupportCheckBox.verticalCenter
width: parent.width * .45 - 3 * UM.Theme.getSize("default_margin").width
text: catalog.i18nc("@label", "Enable Support");
text: catalog.i18nc("@label", "Generate Support");
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
}
@ -263,7 +263,7 @@ Item
onEntered:
{
base.showTooltip(enableSupportCheckBox, Qt.point(-enableSupportCheckBox.x, 0),
catalog.i18nc("@label", "Enable support structures. These structures support parts of the model with severe overhangs."));
catalog.i18nc("@label", "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."));
}
onExited:
{
@ -272,7 +272,7 @@ Item
}
}
Label
Text
{
id: supportExtruderLabel
visible: (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)
@ -372,7 +372,7 @@ Item
}
Label
Text
{
id: adhesionHelperLabel
anchors.left: parent.left
@ -398,7 +398,7 @@ Item
style: UM.Theme.styles.checkbox;
enabled: base.settingsEnabled
checked: platformAdhesionType.properties.value != "skirt"
checked: platformAdhesionType.properties.value != "skirt" && platformAdhesionType.properties.value != "none"
MouseArea
{
@ -470,7 +470,7 @@ Item
width: parent.width
height: childrenRect.height
Label
Text
{
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width

View file

@ -43,7 +43,7 @@ UM.PointingRectangle {
base.opacity = 0;
}
Label {
Text {
id: label;
anchors {
top: parent.top;

View file

@ -13,13 +13,13 @@ UM.Dialog
{
title: catalog.i18nc("@title:window", "Save Project")
width: 550
minimumWidth: 550
width: 550 * Screen.devicePixelRatio
minimumWidth: 550 * Screen.devicePixelRatio
height: 350
minimumHeight: 350
height: 350 * Screen.devicePixelRatio
minimumHeight: 350 * Screen.devicePixelRatio
property int spacerHeight: 10
property int spacerHeight: 10 * Screen.devicePixelRatio
property bool dontShowAgain: true
@ -41,15 +41,8 @@ UM.Dialog
Item
{
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
anchors.bottomMargin: 20
anchors.leftMargin:20
anchors.rightMargin: 20
anchors.fill: parent
anchors.margins: 20 * Screen.devicePixelRatio
UM.SettingDefinitionsModel
{
@ -63,8 +56,12 @@ UM.Dialog
}
UM.I18nCatalog
{
id: catalog;
name: "cura";
id: catalog
name: "cura"
}
SystemPalette
{
id: palette
}
Column
@ -75,12 +72,12 @@ UM.Dialog
{
id: titleLabel
text: catalog.i18nc("@action:title", "Summary - Cura Project")
font.pixelSize: 22
font.pointSize: 18
}
Rectangle
{
id: separator
color: "black"
color: palette.text
width: parent.width
height: 1
}
@ -229,6 +226,13 @@ UM.Dialog
width: parent.width / 3
}
}
Item // Spacer
{
height: spacerHeight
width: height
}
CheckBox
{
id: dontShowAgainCheckbox