Skip to content

Commit faff99f

Browse files
authored
Merge pull request #2625 from alicevision/fix/validateSavePermissions
[ui] Add Validation for Save file path accessibility
2 parents e8d177e + 21b5080 commit faff99f

File tree

2 files changed

+50
-9
lines changed

2 files changed

+50
-9
lines changed

meshroom/ui/components/filepath.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ def removeExtension(self, path):
5757
""" Returns the pathname without its extension (.ext)"""
5858
return os.path.splitext(self.asStr(path))[0]
5959

60+
@Slot(str, result=bool)
61+
@Slot(QUrl, result=bool)
62+
def accessible(self, path):
63+
""" Returns whether a path is accessible for the user """
64+
path = self.asStr(path)
65+
return os.path.isdir(self.asStr(path)) and os.access(path, os.R_OK) and os.access(path, os.W_OK)
66+
6067
@Slot(str, result=bool)
6168
@Slot(QUrl, result=bool)
6269
def isFile(self, path):

meshroom/ui/qml/Application.qml

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ Page {
6262
}
6363
}
6464

65+
Component {
66+
id: permissionsDialog
67+
68+
MessageDialog {
69+
title: "Permission Denied"
70+
71+
required property string filepath
72+
73+
preset: "Warning"
74+
text: "The location does not exist or you do not have necessary permissions to save to the provided filepath."
75+
detailedText: "Filepath: " + filepath
76+
helperText: "Please check the location or permissions and try again or choose a different location."
77+
78+
standardButtons: Dialog.Ok
79+
onClosed: destroy()
80+
}
81+
}
82+
6583
function validateFilepathForSave(filepath: string, sourceSaveDialog: Dialog): bool {
6684
/**
6785
* Return true if `filepath` is valid for saving a file to disk.
@@ -70,19 +88,35 @@ Page {
7088
*/
7189
const emptyFilename = Filepath.basename(filepath).trim() === ".mg";
7290

73-
// Provided filename is valid
74-
if (!emptyFilename) {
75-
return true
91+
// Provided filename is not valid
92+
if (emptyFilename) {
93+
// Instantiate the Warning Dialog with the provided filepath
94+
const warningDialog = invalidFilepathDialog.createObject(root, {"filepath": Filepath.urlToString(filepath)});
95+
96+
// And open the dialog
97+
warningDialog.closed.connect(sourceSaveDialog.open);
98+
warningDialog.open();
99+
100+
return false;
76101
}
77102

78-
// Instantiate the Warning Dialog with the provided filepath
79-
const warningDialog = invalidFilepathDialog.createObject(root, {"filepath": Filepath.urlToString(filepath)});
103+
// Check if the user has access to the directory where the file is to be saved
104+
const hasPermission = Filepath.accessible(Filepath.dirname(filepath));
105+
106+
// Either the directory does not exist or is inaccessible for the user
107+
if (!hasPermission) {
108+
// Intantiate the permissions dialog with the provided filepath
109+
const warningDialog = permissionsDialog.createObject(root, {"filepath": Filepath.urlToString(filepath)});
80110

81-
// And open the dialog
82-
warningDialog.closed.connect(sourceSaveDialog.open);
83-
warningDialog.open();
111+
// Connect and show the dialog
112+
warningDialog.closed.connect(sourceSaveDialog.open);
113+
warningDialog.open();
114+
115+
return false;
116+
}
84117

85-
return false
118+
// Everything is valid
119+
return true;
86120
}
87121

88122
// File dialogs

0 commit comments

Comments
 (0)