mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-11 17:19:04 +08:00
Revert making the open file dialog a separate LocalFileProvider plugin
This reverts commits 00de7497a4c2986cf8fd13be8f598a0f615f3d63 to 5f6b3b52c1848416c98f7d276fe02f08d067f675 CURA-7868
This commit is contained in:
parent
606ec587fe
commit
96c4d66029
@ -1,47 +0,0 @@
|
||||
# Copyright (c) 2021 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import os.path
|
||||
|
||||
from UM.FileProvider import FileProvider # The plug-in type we're going to implement.
|
||||
from UM.i18n import i18nCatalog
|
||||
from UM.Logger import Logger
|
||||
from UM.PluginRegistry import PluginRegistry # To get resources from the plug-in folder.
|
||||
from cura.CuraApplication import CuraApplication # To create QML elements.
|
||||
|
||||
i18n_catalog = i18nCatalog("cura")
|
||||
|
||||
|
||||
class LocalFileProvider(FileProvider):
|
||||
"""
|
||||
Allows the user to open files from their local file system.
|
||||
|
||||
These files will then be interpreted through the file handlers.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.menu_item_display_text = i18n_catalog.i18nc("@menu Open files from local disk", "Local disk")
|
||||
self.shortcut = "Ctrl+O"
|
||||
|
||||
self._dialog = None # Lazy-load this QML element.
|
||||
|
||||
def _load_file_dialog(self):
|
||||
"""
|
||||
Loads the file dialog QML element into the QML context so that it can be shown.
|
||||
:return:
|
||||
"""
|
||||
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
|
||||
if plugin_path is None:
|
||||
plugin_path = os.path.dirname(__file__)
|
||||
path = os.path.join(plugin_path, "OpenLocalFile.qml")
|
||||
self._dialog = CuraApplication.getInstance().createQmlComponent(path)
|
||||
if self._dialog is None:
|
||||
Logger.log("e", "Unable to create open file dialogue.")
|
||||
|
||||
def run(self):
|
||||
if self._dialog is None:
|
||||
self._load_file_dialog()
|
||||
if self._dialog is None:
|
||||
return # Will already have logged an error in _load_file_dialog.
|
||||
self._dialog.show()
|
@ -1,171 +0,0 @@
|
||||
// Copyright (c) 2021 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Dialogs 1.2
|
||||
|
||||
import UM 1.3 as UM
|
||||
import Cura 1.1 as Cura
|
||||
|
||||
Item
|
||||
{
|
||||
id: base
|
||||
|
||||
function show()
|
||||
{
|
||||
openDialog.visible = true;
|
||||
}
|
||||
|
||||
UM.I18nCatalog
|
||||
{
|
||||
id: catalog
|
||||
name: "cura"
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: openDialog;
|
||||
|
||||
//: File open dialog title
|
||||
title: catalog.i18nc("@title:window","Open file(s)")
|
||||
modality: Qt.WindowModal
|
||||
selectMultiple: true
|
||||
nameFilters: UM.MeshFileHandler.supportedReadFileTypes;
|
||||
folder:
|
||||
{
|
||||
//Because several implementations of the file dialog only update the folder when it is explicitly set.
|
||||
folder = CuraApplication.getDefaultPath("dialog_load_path");
|
||||
return 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);
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Cura.AskOpenAsProjectOrModelsDialog
|
||||
{
|
||||
id: askOpenAsProjectOrModelsDialog
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: CuraApplication
|
||||
onOpenProjectFile:
|
||||
{
|
||||
askOpenAsProjectOrModelsDialog.fileUrl = project_file;
|
||||
askOpenAsProjectOrModelsDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
Cura.OpenFilesIncludingProjectsDialog
|
||||
{
|
||||
id: openFilesIncludingProjectsDialog
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
# Copyright (c) 2021 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from . import LocalFileProvider
|
||||
|
||||
|
||||
def getMetaData():
|
||||
return {}
|
||||
|
||||
def register(app):
|
||||
return { "file_provider": LocalFileProvider.LocalFileProvider() }
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"name": "Local File Provider",
|
||||
"description": "Enables opening files from the local file system.",
|
||||
"author": "Ultimaker B.V.",
|
||||
"version": "1.0.0",
|
||||
"api": "7.4.0",
|
||||
"i18n-catalog": "cura"
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2021 Ultimaker B.V.
|
||||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.7
|
||||
@ -96,7 +96,7 @@ Item
|
||||
id: openFileButton
|
||||
height: UM.Theme.getSize("stage_menu").height
|
||||
width: UM.Theme.getSize("stage_menu").height
|
||||
onClicked: CuraApplication.getFileProviderModel().triggerFirst()
|
||||
onClicked: Cura.Actions.open.trigger()
|
||||
hoverEnabled: true
|
||||
|
||||
contentItem: Item
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2021 Ultimaker B.V.
|
||||
// Copyright (c) 2018 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
pragma Singleton
|
||||
@ -12,6 +12,7 @@ import Cura 1.0 as Cura
|
||||
Item
|
||||
{
|
||||
property alias newProject: newProjectAction;
|
||||
property alias open: openAction;
|
||||
property alias quit: quitAction;
|
||||
|
||||
property alias undo: undoAction;
|
||||
@ -412,6 +413,14 @@ Item
|
||||
onTriggered: CuraApplication.resetAll();
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: openAction;
|
||||
text: catalog.i18nc("@action:inmenu menubar:file","&Open File(s)...");
|
||||
iconName: "document-open";
|
||||
shortcut: StandardKey.Open;
|
||||
}
|
||||
|
||||
Action
|
||||
{
|
||||
id: newProjectAction
|
||||
|
@ -619,6 +619,114 @@ UM.MainWindow
|
||||
onTriggered: base.exitFullscreen()
|
||||
}
|
||||
|
||||
FileDialog
|
||||
{
|
||||
id: openDialog;
|
||||
|
||||
//: File open dialog title
|
||||
title: catalog.i18nc("@title:window","Open file(s)")
|
||||
modality: Qt.WindowModal
|
||||
selectMultiple: true
|
||||
nameFilters: UM.MeshFileHandler.supportedReadFileTypes;
|
||||
folder:
|
||||
{
|
||||
//Because several implementations of the file dialog only update the folder when it is explicitly set.
|
||||
folder = CuraApplication.getDefaultPath("dialog_load_path");
|
||||
return 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);
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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: packageInstallDialog
|
||||
@ -627,6 +735,51 @@ UM.MainWindow
|
||||
modality: Qt.ApplicationModal
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: Cura.Actions.open
|
||||
onTriggered: openDialog.open()
|
||||
}
|
||||
|
||||
OpenFilesIncludingProjectsDialog
|
||||
{
|
||||
id: openFilesIncludingProjectsDialog
|
||||
}
|
||||
|
||||
AskOpenAsProjectOrModelsDialog
|
||||
{
|
||||
id: askOpenAsProjectOrModelsDialog
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: CuraApplication
|
||||
onOpenProjectFile:
|
||||
{
|
||||
askOpenAsProjectOrModelsDialog.fileUrl = project_file;
|
||||
askOpenAsProjectOrModelsDialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
Connections
|
||||
{
|
||||
target: Cura.Actions.showProfileFolder
|
||||
|
@ -22,7 +22,7 @@ Menu
|
||||
MenuItem
|
||||
{
|
||||
id: openMenu
|
||||
onTriggered: CuraApplication.getFileProviderModel().triggerFirst()
|
||||
action: Cura.Actions.open
|
||||
visible: (base.fileProviderModel.count == 1)
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2021 Ultimaker B.V.
|
||||
// Copyright (c) 2020 Ultimaker B.V.
|
||||
// Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
import QtQuick 2.2
|
||||
@ -21,8 +21,21 @@ Menu
|
||||
model: CuraApplication.getFileProviderModel()
|
||||
MenuItem
|
||||
{
|
||||
text: model.displayText
|
||||
onTriggered: CuraApplication.getFileProviderModel().trigger(model.name)
|
||||
text:
|
||||
{
|
||||
return model.displayText;
|
||||
}
|
||||
onTriggered:
|
||||
{
|
||||
if (model.index == 0) // The 0th element is the "From Disk" option, which should activate the open local file dialog
|
||||
{
|
||||
Cura.Actions.open.trigger()
|
||||
}
|
||||
else
|
||||
{
|
||||
CuraApplication.getFileProviderModel().trigger(model.name);
|
||||
}
|
||||
}
|
||||
shortcut: model.shortcut
|
||||
}
|
||||
onObjectAdded: openFilesMenu.insertItem(index, object)
|
||||
|
Loading…
x
Reference in New Issue
Block a user