Show file filter name for accessory view of file dialog

- Respect filters option of dialog.showOpenDialog() and
  dialog.showSaveDialog(). (#10335)
- Show "All Files" for <input> apart from "accept" attribute. (#11456)
This commit is contained in:
Yuya Ochiai 2018-02-19 22:40:07 +09:00 committed by Cheng Zhao
parent 4c51c03779
commit 2131dc839a

View file

@ -16,17 +16,17 @@
@interface PopUpButtonHandler : NSObject @interface PopUpButtonHandler : NSObject
@property (nonatomic, strong) NSSavePanel *savePanel; @property (nonatomic, strong) NSSavePanel *savePanel;
@property (nonatomic, strong) NSArray *fileTypes; @property (nonatomic, strong) NSArray *fileTypesList;
- (instancetype)initWithPanel:(NSSavePanel *)panel andTypes:(NSArray *)types; - (instancetype)initWithPanel:(NSSavePanel *)panel andTypesList:(NSArray *)typesList;
- (void)selectFormat:(id)sender; - (void)selectFormat:(id)sender;
@end @end
@implementation PopUpButtonHandler @implementation PopUpButtonHandler
- (instancetype)initWithPanel:(NSSavePanel *)panel andTypes:(NSArray *)types { - (instancetype)initWithPanel:(NSSavePanel *)panel andTypesList:(NSArray *)typesList {
self = [super init]; self = [super init];
if (self) { if (self) {
_savePanel = panel; _savePanel = panel;
_fileTypes = types; _fileTypesList = typesList;
} }
return self; return self;
} }
@ -34,13 +34,16 @@
- (void)selectFormat:(id)sender { - (void)selectFormat:(id)sender {
NSPopUpButton *button = (NSPopUpButton *)sender; NSPopUpButton *button = (NSPopUpButton *)sender;
NSInteger selectedItemIndex = [button indexOfSelectedItem]; NSInteger selectedItemIndex = [button indexOfSelectedItem];
NSString *nameFieldString = [[self savePanel] nameFieldStringValue]; NSArray *list = [self fileTypesList];
NSString *trimmedNameFieldString = [nameFieldString stringByDeletingPathExtension]; NSArray *fileTypes = [list objectAtIndex:selectedItemIndex];
NSString *extension = [[self fileTypes] objectAtIndex: selectedItemIndex];
NSString *nameFieldStringWithExt = [NSString stringWithFormat:@"%@.%@", trimmedNameFieldString, extension]; // If we meet a '*' file extension, we allow all the file types and no
[[self savePanel] setNameFieldStringValue:nameFieldStringWithExt]; // need to set the specified file types.
[[self savePanel] setAllowedFileTypes:@[extension]]; if ([fileTypes count] == 0 || [fileTypes containsObject:@"*"]) {
[[self savePanel] setAllowedFileTypes:nil];
} else {
[[self savePanel] setAllowedFileTypes:fileTypes];
}
} }
@end @end
@ -48,35 +51,39 @@ namespace file_dialog {
namespace { namespace {
static PopUpButtonHandler *popUpButtonHandler;
void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) { void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
NSMutableSet* file_type_set = [NSMutableSet set]; NSMutableArray* file_types_list = [NSMutableArray array];
for (size_t i = 0; i < filters.size(); ++i) { NSMutableArray* filter_names = [NSMutableArray array];
const Filter& filter = filters[i];
for (size_t j = 0; j < filter.second.size(); ++j) {
// If we meet a '*' file extension, we allow all the file types and no
// need to set the specified file types.
if (filter.second[j] == "*") { // Create array to keep file types and their name.
[dialog setAllowsOtherFileTypes:YES]; for (size_t i = 0; i < filters.size(); ++i) {
return; NSMutableSet* file_type_set = [NSMutableSet set];
} const Filter& filter = filters[i];
base::ScopedCFTypeRef<CFStringRef> ext_cf( base::ScopedCFTypeRef<CFStringRef> name_cf(base::SysUTF8ToCFStringRef(filter.first));
base::SysUTF8ToCFStringRef(filter.second[j])); [filter_names addObject:base::mac::CFToNSCast(name_cf.get())];
for (size_t j = 0; j < filter.second.size(); ++j) {
base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(filter.second[j]));
[file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())]; [file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())];
} }
[file_types_list addObject:[file_type_set allObjects]];
} }
// Passing empty array to setAllowedFileTypes will cause exception. // Passing empty array to setAllowedFileTypes will cause exception.
NSArray* file_types = nil; NSArray* file_types = nil;
if ([file_type_set count]) NSUInteger count = [file_types_list count];
file_types = [file_type_set allObjects]; if (count > 0) {
file_types = [[file_types_list objectAtIndex:0] allObjects];
// If we meet a '*' file extension, we allow all the file types and no
// need to set the specified file types.
if ([file_types count] == 0 || [file_types containsObject:@"*"]) {
file_types = nil;
}
}
[dialog setAllowedFileTypes:file_types]; [dialog setAllowedFileTypes:file_types];
if (!popUpButtonHandler) if (count <= 1) {
popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog andTypes:file_types]; return; // don't add file format picker
}
// add file format picker // add file format picker
NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
@ -89,7 +96,8 @@ void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
[label setDrawsBackground:NO]; [label setDrawsBackground:NO];
NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
[popupButton addItemsWithTitles:file_types]; PopUpButtonHandler *popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog andTypesList:[file_types_list copy]];
[popupButton addItemsWithTitles:[filter_names copy]];
[popupButton setTarget:popUpButtonHandler]; [popupButton setTarget:popUpButtonHandler];
[popupButton setAction:@selector(selectFormat:)]; [popupButton setAction:@selector(selectFormat:)];