From da2adad189c04c1eddeff0e21aee528c9c8bc350 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Fri, 17 Oct 2025 17:26:42 +0200 Subject: [PATCH 1/2] [ui] Keep projects in recent list even if there is a load error --- meshroom/ui/qml/Application.qml | 2 -- meshroom/ui/qml/Homepage.qml | 2 -- 2 files changed, 4 deletions(-) diff --git a/meshroom/ui/qml/Application.qml b/meshroom/ui/qml/Application.qml index d7fb41380a..37f2bff9b5 100644 --- a/meshroom/ui/qml/Application.qml +++ b/meshroom/ui/qml/Application.qml @@ -729,8 +729,6 @@ Page { openRecentMenu.dismiss() if (_reconstruction.load(modelData["path"])) { MeshroomApp.addRecentProjectFile(modelData["path"]) - } else { - MeshroomApp.removeRecentProjectFile(modelData["path"]) } }) diff --git a/meshroom/ui/qml/Homepage.qml b/meshroom/ui/qml/Homepage.qml index 78baac6115..df8a6ca9ef 100644 --- a/meshroom/ui/qml/Homepage.qml +++ b/meshroom/ui/qml/Homepage.qml @@ -361,8 +361,6 @@ Page { mainStack.push("Application.qml") if (_reconstruction.load(modelData["path"])) { MeshroomApp.addRecentProjectFile(modelData["path"]) - } else { - MeshroomApp.removeRecentProjectFile(modelData["path"]) } } From ac2ce534590e7ac7edb8073802314fe6660eef0e Mon Sep 17 00:00:00 2001 From: Alice Sonolet Date: Fri, 17 Oct 2025 18:23:35 +0200 Subject: [PATCH 2/2] [ui] Disable projects when the file is missing --- meshroom/ui/app.py | 13 +++++++++++-- meshroom/ui/qml/Application.qml | 2 ++ meshroom/ui/qml/Homepage.qml | 7 ++++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/meshroom/ui/app.py b/meshroom/ui/app.py index fb50f9f958..1a2bc5c981 100644 --- a/meshroom/ui/app.py +++ b/meshroom/ui/app.py @@ -3,6 +3,7 @@ import re import argparse import json +from enum import Enum from PySide6 import __version__ as PySideVersion from PySide6 import QtCore @@ -34,6 +35,12 @@ from meshroom.ui import commands +class FileStatus(Enum): + MISSING=0 + EXISTS=1 + ERROR=2 # If the file exists but have errors like missing nodes, file content corruption... + + class MessageHandler: """ MessageHandler that translates Qt logs to Python logging system. @@ -422,7 +429,8 @@ def _getRecentProjectFilesFromSettings(self) -> list[dict[str, str]]: settings.setArrayIndex(i) path = settings.value("filepath") if path: - p = {"path": path, "thumbnail": self._retrieveThumbnailPath(path)} + fileStatus = FileStatus.EXISTS if os.path.isfile(path) else FileStatus.MISSING + p = {"path": path, "thumbnail": self._retrieveThumbnailPath(path), "status": fileStatus.value} projects.append(p) settings.endArray() settings.endGroup() @@ -443,6 +451,7 @@ def _updateRecentProjectFilesThumbnails(self) -> None: for project in self._recentProjectFiles: path = project["path"] project["thumbnail"] = self._retrieveThumbnailPath(path) + project["status"] = os.path.isfile(path) @Slot(str) @Slot(QUrl) @@ -479,7 +488,7 @@ def addRecentProjectFile(self, projectFile) -> None: del projects[idx] # If so, delete its entry # Insert the newest entry at the top of the list - projects.insert(0, {"path": projectFileNorm, "thumbnail": ""}) + projects.insert(0, {"path": projectFileNorm, "thumbnail": "", "status": FileStatus.EXISTS}) # Only keep the first 40 projects maxNbProjects = 40 diff --git a/meshroom/ui/qml/Application.qml b/meshroom/ui/qml/Application.qml index 37f2bff9b5..d9ba6b515b 100644 --- a/meshroom/ui/qml/Application.qml +++ b/meshroom/ui/qml/Application.qml @@ -725,6 +725,8 @@ Page { id: recentFilesMenuItems model: MeshroomApp.recentProjectFiles MenuItem { + enabled: modelData["status"] != 0 + onTriggered: ensureSaved(function() { openRecentMenu.dismiss() if (_reconstruction.load(modelData["path"])) { diff --git a/meshroom/ui/qml/Homepage.qml b/meshroom/ui/qml/Homepage.qml index df8a6ca9ef..6a354444d5 100644 --- a/meshroom/ui/qml/Homepage.qml +++ b/meshroom/ui/qml/Homepage.qml @@ -284,7 +284,7 @@ Page { // Request latest thumbnail paths if (mainStack.currentItem instanceof Homepage) MeshroomApp.updateRecentProjectFilesThumbnails() - return [{"path": null, "thumbnail": null}].concat(MeshroomApp.recentProjectFiles) + return [{"path": null, "thumbnail": null, "status": null}].concat(MeshroomApp.recentProjectFiles) } // Update grid item when corresponding thumbnail is computed @@ -325,6 +325,10 @@ Page { height: gridView.cellHeight * 0.95 - project.height width: gridView.cellWidth * 0.9 + // Handle case where the file is missing + property bool fileExists: modelData["status"] != 0 + opacity: fileExists ? 1.0 : 0.3 + ToolTip.visible: hovered ToolTip.text: modelData["path"] ? modelData["path"] : "Open browser to select a project file" @@ -372,6 +376,7 @@ Page { id: projectContextMenu MenuItem { + enabled: projectDelegate.fileExists text: "Open" onTriggered: { if (_reconstruction.load(modelData["path"])) {