Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use most recent project as base folder for file dialogs #1778

Merged
merged 3 commits into from
Sep 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions meshroom/core/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def fileFeatures(self):
return Graph.IO.getFeaturesForVersion(self.header.get(Graph.IO.Keys.FileVersion, "0.0"))

@Slot(str)
def load(self, filepath, setupProjectFile=True, importScene=False):
def load(self, filepath, setupProjectFile=True, importProject=False):
"""
Load a meshroom graph ".mg" file.

Expand All @@ -250,17 +250,17 @@ def load(self, filepath, setupProjectFile=True, importScene=False):
setupProjectFile: Store the reference to the project file and setup the cache directory.
If false, it only loads the graph of the project file as a template.
"""
if not importScene:
if not importProject:
self.clear()
with open(filepath) as jsonFile:
fileData = json.load(jsonFile)

# older versions of Meshroom files only contained the serialized nodes
graphData = fileData.get(Graph.IO.Keys.Graph, fileData)

if importScene:
if importProject:
self._importedNodes.clear()
graphData = self.updateImportedScene(graphData)
graphData = self.updateImportedProject(graphData)

if not isinstance(graphData, dict):
raise RuntimeError('loadGraph error: Graph is not a dict. File: {}'.format(filepath))
Expand Down Expand Up @@ -289,7 +289,7 @@ def load(self, filepath, setupProjectFile=True, importScene=False):
# Add node to the graph with raw attributes values
self._addNode(n, nodeName)

if importScene:
if importProject:
self._importedNodes.add(n)

# Create graph edges by resolving attributes expressions
Expand All @@ -302,12 +302,12 @@ def load(self, filepath, setupProjectFile=True, importScene=False):

return True

def updateImportedScene(self, data):
def updateImportedProject(self, data):
"""
Update the names and links of the scene to import so that it can fit
Update the names and links of the project to import so that it can fit
correctly in the existing graph.

Parse all the nodes from the scene that is going to be imported.
Parse all the nodes from the project that is going to be imported.
If their name already exists in the graph, replace them with new names,
then parse all the nodes' inputs/outputs to replace the old names with
the new ones in the links.
Expand Down Expand Up @@ -336,7 +336,7 @@ def createUniqueNodeName(nodeNames, inputName):
# First pass to get all the names that already exist in the graph, update them, and keep track of the changes
for nodeName, nodeData in sorted(data.items(), key=lambda x: self.getNodeIndexFromName(x[0])):
if not isinstance(nodeData, dict):
raise RuntimeError('updateImportedScene error: Node is not a dict.')
raise RuntimeError('updateImportedProject error: Node is not a dict.')

if nodeName in self._nodes.keys() or nodeName in updatedData.keys():
newName = createUniqueNodeName(self._nodes.keys(), nodeData["nodeType"])
Expand Down Expand Up @@ -1403,7 +1403,7 @@ def edges(self):

@property
def importedNodes(self):
"""" Return the list of nodes that were added to the graph with the latest 'Import Scene' action. """
"""" Return the list of nodes that were added to the graph with the latest 'Import Project' action. """
return self._importedNodes

@property
Expand Down
12 changes: 6 additions & 6 deletions meshroom/ui/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def __init__(self, graph, data, position=None, parent=None):
self.nodeNames = []

def redoImpl(self):
data = self.graph.updateImportedScene(self.data)
data = self.graph.updateImportedProject(self.data)
nodes = self.graph.pasteNodes(data, self.position)
self.nodeNames = [node.name for node in nodes]
self.setText("Paste Node{} ({})".format("s" if len(self.nodeNames) > 1 else "", ", ".join(self.nodeNames)))
Expand All @@ -217,20 +217,20 @@ def undoImpl(self):
self.graph.removeNode(name)


class ImportSceneCommand(GraphCommand):
class ImportProjectCommand(GraphCommand):
"""
Handle the import of a scene into a Graph.
Handle the import of a project into a Graph.
"""
def __init__(self, graph, filepath=None, yOffset=0, parent=None):
super(ImportSceneCommand, self).__init__(graph, parent)
super(ImportProjectCommand, self).__init__(graph, parent)
self.filepath = filepath
self.importedNames = []
self.yOffset = yOffset

def redoImpl(self):
status = self.graph.load(self.filepath, setupProjectFile=False, importScene=True)
status = self.graph.load(self.filepath, setupProjectFile=False, importProject=True)
importedNodes = self.graph.importedNodes
self.setText("Import Scene ({} nodes)".format(importedNodes.count))
self.setText("Import Project ({} nodes)".format(importedNodes.count))

lowestY = 0
for node in self.graph.nodes:
Expand Down
4 changes: 2 additions & 2 deletions meshroom/ui/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def loadGraph(self, filepath, setupProjectFile=True):
return status

@Slot(QUrl, result=bool)
def importScene(self, filepath):
def importProject(self, filepath):
if isinstance(filepath, (QUrl)):
# depending how the QUrl has been initialized,
# toLocalFile() may return the local path or an empty string
Expand All @@ -364,7 +364,7 @@ def importScene(self, filepath):
else:
localFile = filepath
yOffset = self.layout.gridSpacing + self.layout.nodeHeight
return self.push(commands.ImportSceneCommand(self._graph, localFile, yOffset=yOffset))
return self.push(commands.ImportProjectCommand(self._graph, localFile, yOffset=yOffset))

@Slot(QUrl)
def saveAs(self, url):
Expand Down
57 changes: 36 additions & 21 deletions meshroom/ui/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -322,12 +322,12 @@ ApplicationWindow {
}

FileDialog {
id: importSceneDialog
title: "Import Scene"
id: importProjectDialog
title: "Import Project"
selectMultiple: false
nameFilters: ["Meshroom Graphs (*.mg)"]
onAccepted: {
graphEditor.uigraph.importScene(importSceneDialog.fileUrl)
graphEditor.uigraph.importProject(importProjectDialog.fileUrl)
}
}

Expand Down Expand Up @@ -451,7 +451,7 @@ ApplicationWindow {
Action {
id: pasteAction

property string tooltip: "Paste the clipboard content to the scene if it contains valid nodes"
property string tooltip: "Paste the clipboard content to the project if it contains valid nodes"
text: "Paste Node(s)"
shortcut: "Ctrl+V"
onTriggered: graphEditor.pasteNodes()
Expand All @@ -462,6 +462,20 @@ ApplicationWindow {
onTriggered: _PaletteManager.togglePalette()
}


// Utility functions for elements in the menubar

function initFileDialogFolder(dialog) {
if(_reconstruction.graph && _reconstruction.graph.filepath) {
dialog.folder = Filepath.stringToUrl(Filepath.dirname(_reconstruction.graph.filepath));
} else {
var projects = MeshroomApp.recentProjectFiles;
if (projects.length > 0 && Filepath.exists(projects[0])) {
dialog.folder = Filepath.stringToUrl(Filepath.dirname(projects[0]));
}
}
}

header: MenuBar {
palette.window: Qt.darker(activePalette.window, 1.15)
Menu {
Expand Down Expand Up @@ -511,10 +525,8 @@ ApplicationWindow {
text: "Open"
shortcut: "Ctrl+O"
onTriggered: ensureSaved(function() {
if(_reconstruction.graph && _reconstruction.graph.filepath) {
openFileDialog.folder = Filepath.stringToUrl(Filepath.dirname(_reconstruction.graph.filepath))
}
openFileDialog.open()
initFileDialogFolder(openFileDialog);
openFileDialog.open();
})
}
Menu {
Expand Down Expand Up @@ -558,16 +570,22 @@ ApplicationWindow {
}
}
Action {
id: importSceneAction
text: "Import Scene"
id: importProjectAction
text: "Import Project"
shortcut: "Ctrl+Shift+I"
onTriggered: importSceneDialog.open()
onTriggered: {
initFileDialogFolder(importProjectDialog);
importProjectDialog.open();
}
}
Action {
id: importActionItem
text: "Import Images"
shortcut: "Ctrl+I"
onTriggered: importFilesDialog.open()
onTriggered: {
initFileDialogFolder(importFilesDialog);
importFilesDialog.open();
}
}

Action {
Expand Down Expand Up @@ -604,7 +622,8 @@ ApplicationWindow {
}
else
{
saveFileDialog.open()
initFileDialogFolder(saveFileDialog);
saveFileDialog.open();
}
}
}
Expand All @@ -613,21 +632,17 @@ ApplicationWindow {
text: "Save As..."
shortcut: "Ctrl+Shift+S"
onTriggered: {
if(_reconstruction.graph && _reconstruction.graph.filepath) {
saveFileDialog.folder = Filepath.stringToUrl(Filepath.dirname(_reconstruction.graph.filepath))
}
saveFileDialog.open()
initFileDialogFolder(saveFileDialog);
saveFileDialog.open();
}
}
Action {
id: saveAsTemplateAction
text: "Save As Template..."
shortcut: "Ctrl+Shift+T"
onTriggered: {
if(_reconstruction.graph && _reconstruction.graph.filepath) {
saveTemplateDialog.folder = Filepath.stringToUrl(Filepath.dirname(_reconstruction.graph.filepath))
}
saveTemplateDialog.open()
initFileDialogFolder(saveTemplateDialog);
saveTemplateDialog.open();
}
}
MenuSeparator { }
Expand Down