Skip to content

Commit

Permalink
Merge pull request #1864 from alicevision/dev/saveImportImagesFolder
Browse files Browse the repository at this point in the history
[ui] Use the location of the most recently imported images as the base folder for the "Import Images" dialog
  • Loading branch information
fabiencastan authored Jan 22, 2023
2 parents 0ca3145 + 3d0bc9e commit 40b182e
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 8 deletions.
88 changes: 85 additions & 3 deletions meshroom/ui/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,12 @@ def addRecentProjectFile(self, projectFile):
# add the new value in the first place
projects.insert(0, projectFileNorm)

# keep only the 10 first elements
# keep only the 20 first elements
projects = projects[0:20]

settings = QSettings()
settings.beginGroup("RecentFiles")
size = settings.beginWriteArray("Projects")
settings.beginWriteArray("Projects")
for i, p in enumerate(projects):
settings.setArrayIndex(i)
settings.setValue("filepath", p)
Expand Down Expand Up @@ -292,7 +292,7 @@ def removeRecentProjectFile(self, projectFile):

settings = QSettings()
settings.beginGroup("RecentFiles")
size = settings.beginWriteArray("Projects")
settings.beginWriteArray("Projects")
for i, p in enumerate(projects):
settings.setArrayIndex(i)
settings.setValue("filepath", p)
Expand All @@ -301,6 +301,86 @@ def removeRecentProjectFile(self, projectFile):

self.recentProjectFilesChanged.emit()

def _recentImportedImagesFolders(self):
folders = []
settings = QSettings()
settings.beginGroup("RecentFiles")
size = settings.beginReadArray("ImagesFolders")
for i in range(size):
settings.setArrayIndex(i)
f = settings.value("path")
if f:
folders.append(f)
settings.endArray()
return folders

@Slot(QUrl)
def addRecentImportedImagesFolder(self, imagesFolder):
if isinstance(imagesFolder, QUrl):
folderPath = imagesFolder.toLocalFile()
if not folderPath:
folderPath = imagesFolder.toString()
else:
raise TypeError("Unexpected data type: {}".format(imagesFolder.__class__))

folders = self._recentImportedImagesFolders()

# remove duplicates while preserving order
from collections import OrderedDict
uniqueFolders = OrderedDict.fromkeys(folders)
folders = list(uniqueFolders)
# remove previous usage of the value
if folderPath in uniqueFolders:
folders.remove(folderPath)
# add the new value in the first place
folders.insert(0, folderPath)

# keep only the first three elements to have a backup if one of the folders goes missing
folders = folders[0:3]

settings = QSettings()
settings.beginGroup("RecentFiles")
settings.beginWriteArray("ImagesFolders")
for i, p in enumerate(folders):
settings.setArrayIndex(i)
settings.setValue("path", p)
settings.endArray()
settings.sync()

self.recentImportedImagesFoldersChanged.emit()

@Slot(QUrl)
def removeRecentImportedImagesFolder(self, imagesFolder):
if isinstance(imagesFolder, QUrl):
folderPath = imagesFolder.toLocalFile()
if not folderPath:
folderPath = imagesFolder.toString()
else:
raise TypeError("Unexpected data type: {}".format(imagesFolder.__class__))

folders = self._recentImportedImagesFolders()

# remove duplicates while preserving order
from collections import OrderedDict
uniqueFolders = OrderedDict.fromkeys(folders)
folders = list(uniqueFolders)
# remove previous usage of the value
if folderPath not in uniqueFolders:
return

folders.remove(folderPath)

settings = QSettings()
settings.beginGroup("RecentFiles")
settings.beginWriteArray("ImagesFolders")
for i, f in enumerate(folders):
settings.setArrayIndex(i)
settings.setValue("path", f)
settings.endArray()
settings.sync()

self.recentImportedImagesFoldersChanged.emit()

@Slot(str, result=str)
def markdownToHtml(self, md):
"""
Expand Down Expand Up @@ -358,7 +438,9 @@ def _default8bitViewerEnabled(self):
licensesModel = Property("QVariantList", _licensesModel, constant=True)
pipelineTemplateFilesChanged = Signal()
recentProjectFilesChanged = Signal()
recentImportedImagesFoldersChanged = Signal()
pipelineTemplateFiles = Property("QVariantList", _pipelineTemplateFiles, notify=pipelineTemplateFilesChanged)
pipelineTemplateNames = Property("QVariantList", _pipelineTemplateNames, notify=pipelineTemplateFilesChanged)
recentProjectFiles = Property("QVariantList", _recentProjectFiles, notify=recentProjectFilesChanged)
recentImportedImagesFolders = Property("QVariantList", _recentImportedImagesFolders, notify=recentImportedImagesFoldersChanged)
default8bitViewerEnabled = Property(bool, _default8bitViewerEnabled, constant=True)
1 change: 1 addition & 0 deletions meshroom/ui/qml/ImageGallery/ImageGallery.qml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Panel {
readonly property string currentItemSource: grid.currentItem ? grid.currentItem.source : ""
readonly property var currentItemMetadata: grid.currentItem ? grid.currentItem.metadata : undefined
readonly property int centerViewId: (_reconstruction && _reconstruction.sfmTransform) ? parseInt(_reconstruction.sfmTransform.attribute("transformation").value) : 0
readonly property alias galleryGrid: grid

property int defaultCellSize: 160
property bool readOnly: false
Expand Down
1 change: 1 addition & 0 deletions meshroom/ui/qml/WorkspaceView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Item {
property bool readOnly: false
property alias panel3dViewer: panel3dViewerLoader.item
readonly property Viewer2D viewer2D: viewer2D
readonly property alias imageGallery: imageGallery

implicitWidth: 300
implicitHeight: 400
Expand Down
37 changes: 32 additions & 5 deletions meshroom/ui/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ ApplicationWindow {
SystemPalette { id: activePalette }
SystemPalette { id: disabledPalette; colorGroup: SystemPalette.Disabled }

property url imagesFolder: {
var recentImportedImagesFolders = MeshroomApp.recentImportedImagesFolders
if (recentImportedImagesFolders.length > 0) {
for (var i = 0; i < recentImportedImagesFolders.length; i++) {
if (Filepath.exists(recentImportedImagesFolders[i]))
return Filepath.stringToUrl(recentImportedImagesFolders[i])
else
MeshroomApp.removeRecentImportedImagesFolder(Filepath.stringToUrl(recentImportedImagesFolders[i]))
}
}
return ""
}

Settings {
id: settings_General
category: 'General'
Expand Down Expand Up @@ -328,6 +341,8 @@ ApplicationWindow {
nameFilters: []
onAccepted: {
_reconstruction.importImagesUrls(importImagesDialog.fileUrls)
imagesFolder = Filepath.dirname(importImagesDialog.fileUrls[0])
MeshroomApp.addRecentImportedImagesFolder(imagesFolder)
}
}

Expand Down Expand Up @@ -475,15 +490,27 @@ ApplicationWindow {

// 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));
function initFileDialogFolder(dialog, importImages = false) {
let folder = "";

if (imagesFolder.toString() === "" && workspaceView.imageGallery.galleryGrid.itemAtIndex(0) !== null) {
imagesFolder = Filepath.stringToUrl(Filepath.dirname(workspaceView.imageGallery.galleryGrid.itemAtIndex(0).source));
}

if (_reconstruction.graph && _reconstruction.graph.filepath) {
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]));
folder = Filepath.stringToUrl(Filepath.dirname(projects[0]));
}
}

if (importImages && imagesFolder.toString() !== "" && Filepath.exists(imagesFolder)) {
folder = imagesFolder;
}

dialog.folder = folder;
}

header: MenuBar {
Expand Down Expand Up @@ -606,7 +633,7 @@ ApplicationWindow {
text: "Import Images"
shortcut: "Ctrl+I"
onTriggered: {
initFileDialogFolder(importImagesDialog);
initFileDialogFolder(importImagesDialog, true);
importImagesDialog.open();
}
}
Expand Down

0 comments on commit 40b182e

Please sign in to comment.