platform: extension filter on Windows/macOS system pickers
Windows: IFileOpenDialog SetFileTypes with the allowed extensions (plus a default extension) when the host passes any. macOS: NSOpenPanel setAllowedFileTypes from the same list (empty = all).
This commit is contained in:
@@ -13,7 +13,8 @@ use cocoa::{
|
||||
},
|
||||
base::{BOOL, NO, YES, id, nil, selector},
|
||||
foundation::{
|
||||
NSArray, NSAutoreleasePool, NSBundle, NSInteger, NSProcessInfo, NSString, NSUInteger, NSURL,
|
||||
NSArray, NSAutoreleasePool, NSBundle, NSInteger, NSMutableArray, NSProcessInfo, NSString,
|
||||
NSUInteger, NSURL,
|
||||
},
|
||||
};
|
||||
use core_foundation::{
|
||||
@@ -767,6 +768,20 @@ impl Platform for MacPlatform {
|
||||
let _: () = msg_send![panel, setPrompt: ns_string(&prompt)];
|
||||
}
|
||||
|
||||
// Extension filter (the host's allowed_extensions): the
|
||||
// open panel's allowedFileTypes. Empty = any.
|
||||
if !options.allowed_extensions.is_empty() {
|
||||
let ns_array = {
|
||||
let arr = NSMutableArray::<NSString>::new();
|
||||
for ext in &options.allowed_extensions {
|
||||
let s = ns_string(ext.as_str());
|
||||
arr.addObject(&*s);
|
||||
}
|
||||
arr
|
||||
};
|
||||
let _: () = msg_send![panel, setAllowedFileTypes: &*ns_array];
|
||||
}
|
||||
|
||||
let _: () = msg_send![panel, beginWithCompletionHandler: block];
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1188,6 +1188,30 @@ fn file_open_dialog(
|
||||
folder_dialog.SetOkButtonLabel(&HSTRING::from(prompt))?;
|
||||
}
|
||||
|
||||
// Extension filter (the host's allowed_extensions, e.g.
|
||||
// .ove/.otio/.fcpxml for the project import): the common
|
||||
// ComDlg filter spec.
|
||||
if !options.allowed_extensions.is_empty() {
|
||||
let filter = options
|
||||
.allowed_extensions
|
||||
.iter()
|
||||
.map(|ext| format!("*.{ext}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join(";");
|
||||
// The HSTRINGs must outlive the call (the filter spec holds
|
||||
// raw pointers into them).
|
||||
let name = windows::core::HSTRING::from("Supported files");
|
||||
let pattern = windows::core::HSTRING::from(filter);
|
||||
let spec = Common::COMDLG_FILTERSPEC {
|
||||
pszName: name.as_ptr(),
|
||||
pszSpec: pattern.as_ptr(),
|
||||
};
|
||||
folder_dialog.SetFileTypes(1, &spec)?;
|
||||
folder_dialog.SetDefaultExtension(
|
||||
&HSTRING::from(options.allowed_extensions[0].as_str()),
|
||||
)?;
|
||||
}
|
||||
|
||||
if folder_dialog.Show(window).is_err() {
|
||||
// User cancelled
|
||||
return Ok(None);
|
||||
|
||||
Reference in New Issue
Block a user