Fix memory leaks in file_dialog_mac.mm

This commit is contained in:
Cheng Zhao 2018-04-09 16:51:25 +09:00
parent 2131dc839a
commit 41134f52d9

View file

@ -15,36 +15,56 @@
#include "base/strings/sys_string_conversions.h" #include "base/strings/sys_string_conversions.h"
@interface PopUpButtonHandler : NSObject @interface PopUpButtonHandler : NSObject
@property (nonatomic, strong) NSSavePanel *savePanel;
@property (nonatomic, strong) NSArray *fileTypesList; @property(nonatomic, assign) NSSavePanel* savePanel;
- (instancetype)initWithPanel:(NSSavePanel *)panel andTypesList:(NSArray *)typesList; @property(nonatomic, strong) NSArray* fileTypesList;
- (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 andTypesList:(NSArray *)typesList {
- (instancetype)initWithPanel:(NSSavePanel*)panel
andTypesList:(NSArray*)typesList {
self = [super init]; self = [super init];
if (self) { if (self) {
_savePanel = panel; [self setSavePanel:panel];
_fileTypesList = typesList; [self setFileTypesList:typesList];
} }
return self; return self;
} }
- (void)selectFormat:(id)sender { - (void)selectFormat:(id)sender {
NSPopUpButton *button = (NSPopUpButton *)sender; NSPopUpButton* button = (NSPopUpButton*)sender;
NSInteger selectedItemIndex = [button indexOfSelectedItem]; NSInteger selectedItemIndex = [button indexOfSelectedItem];
NSArray *list = [self fileTypesList]; NSArray* list = [self fileTypesList];
NSArray *fileTypes = [list objectAtIndex:selectedItemIndex]; NSArray* fileTypes = [list objectAtIndex:selectedItemIndex];
// If we meet a '*' file extension, we allow all the file types and no // If we meet a '*' file extension, we allow all the file types and no
// need to set the specified file types. // need to set the specified file types.
if ([fileTypes count] == 0 || [fileTypes containsObject:@"*"]) { if ([fileTypes count] == 0 || [fileTypes containsObject:@"*"])
[[self savePanel] setAllowedFileTypes:nil]; [[self savePanel] setAllowedFileTypes:nil];
} else { else
[[self savePanel] setAllowedFileTypes:fileTypes]; [[self savePanel] setAllowedFileTypes:fileTypes];
}
} }
@end
// Manages the PopUpButtonHandler.
@interface AtomAccessoryView : NSView
@end
@implementation AtomAccessoryView
- (void)dealloc {
auto* popupButton = static_cast<NSPopUpButton*>([[self subviews] objectAtIndex: 1]);
[[popupButton target] release];
[super dealloc];
}
@end @end
namespace file_dialog { namespace file_dialog {
@ -56,13 +76,13 @@ void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
NSMutableArray* filter_names = [NSMutableArray array]; NSMutableArray* filter_names = [NSMutableArray array];
// Create array to keep file types and their name. // Create array to keep file types and their name.
for (size_t i = 0; i < filters.size(); ++i) { for (const Filter& filter : filters) {
NSMutableSet* file_type_set = [NSMutableSet set]; NSMutableSet* file_type_set = [NSMutableSet set];
const Filter& filter = filters[i]; base::ScopedCFTypeRef<CFStringRef> name_cf(
base::ScopedCFTypeRef<CFStringRef> name_cf(base::SysUTF8ToCFStringRef(filter.first)); base::SysUTF8ToCFStringRef(filter.first));
[filter_names addObject:base::mac::CFToNSCast(name_cf.get())]; [filter_names addObject:base::mac::CFToNSCast(name_cf.get())];
for (size_t j = 0; j < filter.second.size(); ++j) { for (const std::string& ext : filter.second) {
base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(filter.second[j])); base::ScopedCFTypeRef<CFStringRef> ext_cf(base::SysUTF8ToCFStringRef(ext));
[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]]; [file_types_list addObject:[file_type_set allObjects]];
@ -75,19 +95,19 @@ void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
file_types = [[file_types_list objectAtIndex:0] allObjects]; file_types = [[file_types_list objectAtIndex:0] allObjects];
// If we meet a '*' file extension, we allow all the file types and no // If we meet a '*' file extension, we allow all the file types and no
// need to set the specified file types. // need to set the specified file types.
if ([file_types count] == 0 || [file_types containsObject:@"*"]) { if ([file_types count] == 0 || [file_types containsObject:@"*"])
file_types = nil; file_types = nil;
}
} }
[dialog setAllowedFileTypes:file_types]; [dialog setAllowedFileTypes:file_types];
if (count <= 1) { if (count <= 1)
return; // don't add file format picker 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)]; AtomAccessoryView* accessoryView =
NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; [[AtomAccessoryView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
NSTextField* label =
[[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
[label setEditable:NO]; [label setEditable:NO];
[label setStringValue:@"Format:"]; [label setStringValue:@"Format:"];
@ -95,16 +115,18 @@ void SetAllowedFileTypes(NSSavePanel* dialog, const Filters& filters) {
[label setBezeled:NO]; [label setBezeled:NO];
[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)
PopUpButtonHandler *popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog andTypesList:[file_types_list copy]]; pullsDown:NO];
[popupButton addItemsWithTitles:[filter_names copy]]; PopUpButtonHandler* popUpButtonHandler = [[PopUpButtonHandler alloc] initWithPanel:dialog
andTypesList:file_types_list];
[popupButton addItemsWithTitles:filter_names];
[popupButton setTarget:popUpButtonHandler]; [popupButton setTarget:popUpButtonHandler];
[popupButton setAction:@selector(selectFormat:)]; [popupButton setAction:@selector(selectFormat:)];
[accessoryView addSubview:label]; [accessoryView addSubview:[label autorelease]];
[accessoryView addSubview:popupButton]; [accessoryView addSubview:[popupButton autorelease]];
[dialog setAccessoryView:accessoryView]; [dialog setAccessoryView:[accessoryView autorelease]];
} }
void SetupDialog(NSSavePanel* dialog, void SetupDialog(NSSavePanel* dialog,
@ -126,6 +148,7 @@ void SetupDialog(NSSavePanel* dialog,
NSString* default_dir = nil; NSString* default_dir = nil;
NSString* default_filename = nil; NSString* default_filename = nil;
if (!settings.default_path.empty()) { if (!settings.default_path.empty()) {
base::ThreadRestrictions::ScopedAllowIO allow_io;
if (base::DirectoryExists(settings.default_path)) { if (base::DirectoryExists(settings.default_path)) {
default_dir = base::SysUTF8ToNSString(settings.default_path.value()); default_dir = base::SysUTF8ToNSString(settings.default_path.value());
} else { } else {