Merge pull request #1535 from LipuFei/feature_CURA-3495_open_in_one

CURA-3495 Open project/models menu item
This commit is contained in:
jack 2017-03-20 10:59:40 +01:00 committed by GitHub
commit 42e7a0defa
5 changed files with 140 additions and 52 deletions

View file

@ -25,6 +25,7 @@ from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.Validator import Validator from UM.Settings.Validator import Validator
from UM.Message import Message from UM.Message import Message
from UM.i18n import i18nCatalog from UM.i18n import i18nCatalog
from UM.Workspace.WorkspaceReader import WorkspaceReader
from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation
from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation from UM.Operations.RemoveSceneNodeOperation import RemoveSceneNodeOperation
@ -1260,3 +1261,21 @@ class CuraApplication(QtApplication):
def addNonSliceableExtension(self, extension): def addNonSliceableExtension(self, extension):
self._non_sliceable_extensions.append(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

View file

@ -47,7 +47,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._id_mapping[old_id] = self._container_registry.uniqueName(old_id) self._id_mapping[old_id] = self._container_registry.uniqueName(old_id)
return self._id_mapping[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) 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: if self._3mf_mesh_reader and self._3mf_mesh_reader.preRead(file_name) == WorkspaceReader.PreReadResult.accepted:
pass pass
@ -167,6 +167,10 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Logger.log("w", "File %s is not a valid workspace.", file_name) Logger.log("w", "File %s is not a valid workspace.", file_name)
return WorkspaceReader.PreReadResult.failed 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. # Show the dialog, informing the user what is about to happen.
self._dialog.setMachineConflict(machine_conflict) self._dialog.setMachineConflict(machine_conflict)
self._dialog.setQualityChangesConflict(quality_changes_conflict) self._dialog.setQualityChangesConflict(quality_changes_conflict)

View file

@ -21,7 +21,7 @@ class ImageReader(MeshReader):
self._supported_extensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"] self._supported_extensions = [".jpg", ".jpeg", ".bmp", ".gif", ".png"]
self._ui = ImageReaderUI(self) self._ui = ImageReaderUI(self)
def preRead(self, file_name): def preRead(self, file_name, *args, **kwargs):
img = QImage(file_name) img = QImage(file_name)
if img.isNull(): if img.isNull():

View file

@ -12,7 +12,6 @@ Item
{ {
property alias newProject: newProjectAction; property alias newProject: newProjectAction;
property alias open: openAction; property alias open: openAction;
property alias loadWorkspace: loadWorkspaceAction;
property alias quit: quitAction; property alias quit: quitAction;
property alias undo: undoAction; property alias undo: undoAction;
@ -284,7 +283,7 @@ Item
Action Action
{ {
id: openAction; id: openAction;
text: catalog.i18nc("@action:inmenu menubar:file","&Open File..."); text: catalog.i18nc("@action:inmenu menubar:file","&Open File(s)...");
iconName: "document-open"; iconName: "document-open";
shortcut: StandardKey.Open; shortcut: StandardKey.Open;
} }
@ -296,12 +295,6 @@ Item
shortcut: StandardKey.New shortcut: StandardKey.New
} }
Action
{
id: loadWorkspaceAction
text: catalog.i18nc("@action:inmenu menubar:file","&Open Project...");
}
Action Action
{ {
id: showEngineLogAction; id: showEngineLogAction;

View file

@ -78,11 +78,6 @@ UM.MainWindow
RecentFilesMenu { } RecentFilesMenu { }
MenuItem
{
action: Cura.Actions.loadWorkspace
}
MenuSeparator { } MenuSeparator { }
MenuItem MenuItem
@ -744,27 +739,43 @@ UM.MainWindow
id: openDialog; id: openDialog;
//: File open dialog title //: 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; modality: UM.Application.platform == "linux" ? Qt.NonModal : Qt.WindowModal;
selectMultiple: true selectMultiple: true
nameFilters: UM.MeshFileHandler.supportedReadFileTypes; nameFilters: UM.MeshFileHandler.supportedReadFileTypes;
folder: CuraApplication.getDefaultPath("dialog_load_path") folder: CuraApplication.getDefaultPath("dialog_load_path")
onAccepted: onAccepted:
{ {
//Because several implementations of the file dialog only update the folder // Because several implementations of the file dialog only update the folder
//when it is explicitly set. // when it is explicitly set.
var f = folder; var f = folder;
folder = f; folder = f;
CuraApplication.setDefaultPath("dialog_load_path", folder); 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()) // we only allow opening one project file
backgroundItem.hasMesh(decodeURIComponent(meshName)) 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);
} }
} }
@ -774,38 +785,101 @@ UM.MainWindow
onTriggered: openDialog.open() onTriggered: openDialog.open()
} }
FileDialog function loadProjectFile(projectFile)
{ {
id: openWorkspaceDialog; UM.WorkspaceFileHandler.readLocalFile(projectFile);
//: File open dialog title var meshName = backgroundItem.getMeshName(projectFile.toString());
title: catalog.i18nc("@title:window","Open workspace") backgroundItem.hasMesh(decodeURIComponent(meshName));
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))
}
} }
Connections function loadModelFiles(fileUrls)
{ {
target: Cura.Actions.loadWorkspace for (var i in fileUrls)
onTriggered: openWorkspaceDialog.open() 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 EngineLog
@ -846,7 +920,7 @@ UM.MainWindow
function start(id) function start(id)
{ {
var actions = Cura.MachineActionManager.getFirstStartActions(id) var actions = Cura.MachineActionManager.getFirstStartActions(id)
resetPages() // Remove previous pages resetPages() // Remove previous pages
for (var i = 0; i < actions.length; i++) for (var i = 0; i < actions.length; i++)
@ -905,7 +979,6 @@ UM.MainWindow
{ {
discardOrKeepProfileChangesDialog.show() discardOrKeepProfileChangesDialog.show()
} }
} }
Connections Connections
@ -955,4 +1028,3 @@ UM.MainWindow
} }
} }
} }