in native/Avalonia.Native/src/OSX/StorageProvider.mm [490:602]
void SetAccessoryView(NSSavePanel* panel,
IAvnFilePickerFileTypes* filters,
bool is_save_panel)
{
NSView* accessory_view = CreateAccessoryView();
NSPopUpButton* popup = [accessory_view viewWithTag:kFileTypePopupTag];
NSMutableArray<NSArray<NSString*>*>* file_type_lists = [NSMutableArray array];
NSMutableArray* file_uttype_lists = [NSMutableArray array];
int default_extension_index = -1;
for (int i = 0; i < filters->GetCount(); i++)
{
NSString* type_description = GetNSStringAndRelease(filters->GetName(i));
[popup addItemWithTitle:type_description];
// If any type is included, enable allowsOtherFileTypes, and skip this filter on save panel.
if (filters->IsAnyType(i)) {
panel.allowsOtherFileTypes = YES;
}
// If default extension is specified, auto select it later.
if (filters->IsDefaultType(i)) {
default_extension_index = i;
}
IAvnStringArray* array;
// Prefer types priority of: file ext -> apple type id -> mime.
// On macOS 10 we only support file extensions.
if (@available(macOS 11, *)) {
NSMutableArray* file_uttype_array = [NSMutableArray array];
bool typeCompleted = false;
if (filters->IsAnyType(i)) {
UTType* type = [UTType typeWithIdentifier:@"public.item"];
[file_uttype_array addObject:type];
typeCompleted = true;
}
if (!typeCompleted && filters->GetExtensions(i, &array) == 0) {
for (NSString* ext in GetNSArrayOfStringsAndRelease(array))
{
UTType* type = [UTType typeWithFilenameExtension:ext];
if (type && ![file_uttype_array containsObject:type]) {
[file_uttype_array addObject:type];
typeCompleted = true;
}
}
}
if (!typeCompleted && filters->GetAppleUniformTypeIdentifiers(i, &array) == 0) {
for (NSString* ext in GetNSArrayOfStringsAndRelease(array))
{
UTType* type = [UTType typeWithIdentifier:ext];
if (type && ![file_uttype_array containsObject:type]) {
[file_uttype_array addObject:type];
typeCompleted = true;
}
}
}
if (!typeCompleted && filters->GetMimeTypes(i, &array) == 0) {
for (NSString* ext in GetNSArrayOfStringsAndRelease(array))
{
UTType* type = [UTType typeWithMIMEType:ext];
if (type && ![file_uttype_array containsObject:type]) {
[file_uttype_array addObject:type];
typeCompleted = true;
}
}
}
[file_uttype_lists addObject:file_uttype_array];
} else {
NSMutableArray<NSString*>* file_type_array = [NSMutableArray array];
if (filters->IsAnyType(i)) {
[file_type_array addObject:@"*.*"];
}
else if (filters->GetExtensions(i, &array) == 0) {
for (NSString* ext in GetNSArrayOfStringsAndRelease(array))
{
if (![file_type_array containsObject:ext]) {
[file_type_array addObject:ext];
}
}
}
[file_type_lists addObject:file_type_array];
}
}
if ([file_uttype_lists count] == 0 && [file_type_lists count] == 0)
return;
if (@available(macOS 11, *))
_extension_dropdown_handler = [[ExtensionDropdownHandler alloc] initWithDialog:panel
fileUTTypeLists:file_uttype_lists];
else
_extension_dropdown_handler = [[ExtensionDropdownHandler alloc] initWithDialog:panel
fileTypeLists:file_type_lists];
[popup setTarget: _extension_dropdown_handler];
[popup setAction: @selector(popupAction:)];
if (default_extension_index != -1) {
[popup selectItemAtIndex:default_extension_index];
} else {
// Select the first item.
[popup selectItemAtIndex:0];
}
[_extension_dropdown_handler popupAction:popup];
if (popup.numberOfItems > 0) {
panel.accessoryView = accessory_view;
}
};