mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-06 22:47:29 -06:00
CURA-3495 open project/models in one dialog
This commit is contained in:
parent
b35a97c770
commit
e00c68344a
4 changed files with 138 additions and 48 deletions
|
@ -25,6 +25,7 @@ from UM.Settings.InstanceContainer import InstanceContainer
|
|||
from UM.Settings.Validator import Validator
|
||||
from UM.Message import Message
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Workspace.WorkspaceReader import WorkspaceReader
|
||||
|
||||
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
|
||||
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
|
||||
|
@ -1260,3 +1261,21 @@ class CuraApplication(QtApplication):
|
|||
|
||||
def addNonSliceableExtension(self, extension):
|
||||
self._non_sliceable_extensions.append(extension)
|
||||
|
||||
@pyqtSlot(str, result=bool)
|
||||
def checkIsValidProjectFile(self, file_url):
|
||||
"""
|
||||
Checks if the given file URL is a valid project file.
|
||||
"""
|
||||
file_url_prefix = 'file:///'
|
||||
|
||||
file_name = file_url
|
||||
if file_name.startswith(file_url_prefix):
|
||||
file_name = file_name[len(file_url_prefix):]
|
||||
|
||||
workspace_reader = self.getWorkspaceFileHandler().getReaderForFile(file_name)
|
||||
if workspace_reader is None:
|
||||
return False # non-project files won't get a reader
|
||||
|
||||
result = workspace_reader.preRead(file_name, show_dialog=False)
|
||||
return result == WorkspaceReader.PreReadResult.accepted
|
||||
|
|
|
@ -47,7 +47,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
self._id_mapping[old_id] = self._container_registry.uniqueName(old_id)
|
||||
return self._id_mapping[old_id]
|
||||
|
||||
def preRead(self, file_name):
|
||||
def preRead(self, file_name, show_dialog=True, *args, **kwargs):
|
||||
self._3mf_mesh_reader = Application.getInstance().getMeshFileHandler().getReaderForFile(file_name)
|
||||
if self._3mf_mesh_reader and self._3mf_mesh_reader.preRead(file_name) == WorkspaceReader.PreReadResult.accepted:
|
||||
pass
|
||||
|
@ -167,6 +167,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
Logger.log("w", "File %s is not a valid workspace.", file_name)
|
||||
return WorkspaceReader.PreReadResult.failed
|
||||
|
||||
# In case we use preRead() to check if a file is a valid project file, we don't want to show a dialog.
|
||||
if not show_dialog:
|
||||
return WorkspaceReader.PreReadResult.accepted
|
||||
|
||||
# Show the dialog, informing the user what is about to happen.
|
||||
self._dialog.setMachineConflict(machine_conflict)
|
||||
self._dialog.setQualityChangesConflict(quality_changes_conflict)
|
||||
|
|
|
@ -12,7 +12,6 @@ Item
|
|||
{
|
||||
property alias newProject: newProjectAction;
|
||||
property alias open: openAction;
|
||||
property alias loadWorkspace: loadWorkspaceAction;
|
||||
property alias quit: quitAction;
|
||||
|
||||
property alias undo: undoAction;
|
||||
|
@ -284,7 +283,7 @@ Item
|
|||
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;
|
||||
}
|
||||
|
@ -296,12 +295,6 @@ Item
|
|||
shortcut: StandardKey.New
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: loadWorkspaceAction
|
||||
text: catalog.i18nc("@action:inmenu menubar:file","&Open Project...");
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: showEngineLogAction;
|
||||
|
|
|
@ -78,11 +78,6 @@ UM.MainWindow
|
|||
|
||||
RecentFilesMenu { }
|
||||
|
||||
MenuItem
|
||||
{
|
||||
action: Cura.Actions.loadWorkspace
|
||||
}
|
||||
|
||||
MenuSeparator { }
|
||||
|
||||
MenuItem
|
||||
|
@ -752,27 +747,43 @@ 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)
|
||||
// look for valid project files
|
||||
var projectFileUrlList = [];
|
||||
for (var i in fileUrls)
|
||||
{
|
||||
Printer.readLocalFile(fileUrls[i])
|
||||
if (CuraApplication.checkIsValidProjectFile(fileUrls[i]))
|
||||
projectFileUrlList.push(fileUrls[i]);
|
||||
}
|
||||
|
||||
var meshName = backgroundItem.getMeshName(fileUrls[0].toString())
|
||||
backgroundItem.hasMesh(decodeURIComponent(meshName))
|
||||
// we only allow opening one project file
|
||||
var selectedMultipleFiles = fileUrls.length > 1;
|
||||
var hasProjectFile = projectFileUrlList.length > 0;
|
||||
var selectedMultipleWithProjectFile = hasProjectFile && selectedMultipleFiles;
|
||||
if (selectedMultipleWithProjectFile)
|
||||
{
|
||||
askOpenProjectOrModelsDialog.fileUrls = fileUrls;
|
||||
askOpenProjectOrModelsDialog.show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasProjectFile)
|
||||
loadProjectFile(projectFileUrlList[0]);
|
||||
else
|
||||
loadModelFiles(fileUrls);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -782,38 +793,101 @@ UM.MainWindow
|
|||
onTriggered: openDialog.open()
|
||||
}
|
||||
|
||||
FileDialog
|
||||
function loadProjectFile(projectFile)
|
||||
{
|
||||
id: openWorkspaceDialog;
|
||||
UM.WorkspaceFileHandler.readLocalFile(projectFile);
|
||||
|
||||
//: 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])
|
||||
}
|
||||
var meshName = backgroundItem.getMeshName(fileUrls[0].toString())
|
||||
backgroundItem.hasMesh(decodeURIComponent(meshName))
|
||||
}
|
||||
var meshName = backgroundItem.getMeshName(projectFile.toString());
|
||||
backgroundItem.hasMesh(decodeURIComponent(meshName));
|
||||
}
|
||||
|
||||
Connections
|
||||
function loadModelFiles(fileUrls)
|
||||
{
|
||||
target: Cura.Actions.loadWorkspace
|
||||
onTriggered: openWorkspaceDialog.open()
|
||||
for (var i in fileUrls)
|
||||
Printer.readLocalFile(fileUrls[i]);
|
||||
|
||||
var meshName = backgroundItem.getMeshName(fileUrls[0].toString());
|
||||
backgroundItem.hasMesh(decodeURIComponent(meshName));
|
||||
}
|
||||
|
||||
UM.Dialog
|
||||
{
|
||||
// This dialog asks the user whether he/she wants to open the project file we have detected or the model files.
|
||||
id: askOpenProjectOrModelsDialog
|
||||
|
||||
title: catalog.i18nc("@title:window", "Open file(s)")
|
||||
width: 620
|
||||
height: 250
|
||||
|
||||
maximumHeight: height
|
||||
maximumWidth: width
|
||||
minimumHeight: height
|
||||
minimumWidth: width
|
||||
|
||||
modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
|
||||
|
||||
property var fileUrls: []
|
||||
property int spacerHeight: 10
|
||||
|
||||
Column
|
||||
{
|
||||
anchors.fill: parent
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: UM.Theme.getSize("default_margin").width
|
||||
|
||||
Text
|
||||
{
|
||||
id: askOpenProjectOrModelsDialogText
|
||||
text: catalog.i18nc("@text:window", "We have found multiple project file(s) within the files you have\nselected. You can open only one project file at a time. We\nsuggest to only import models from those files. Would you like\nto proceed?")
|
||||
anchors.margins: UM.Theme.getSize("default_margin").width
|
||||
font: UM.Theme.getFont("default")
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Item // Spacer
|
||||
{
|
||||
height: askOpenProjectOrModelsDialog.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
|
||||
anchors.rightMargin: UM.Theme.getSize("default_margin").width
|
||||
onClicked:
|
||||
{
|
||||
// cancel
|
||||
askOpenProjectOrModelsDialog.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(askOpenProjectOrModelsDialog.fileUrls);
|
||||
|
||||
askOpenProjectOrModelsDialog.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EngineLog
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue