Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(282)

Side by Side Diff: chrome/browser/ui/cocoa/select_file_dialog_mac.mm

Issue 10388145: Fix acceptance of multiple mime types in the Mac file picker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: helper function Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/select_file_dialog.h" 5 #include "chrome/browser/ui/select_file_dialog.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 9
10 #include <map> 10 #include <map>
(...skipping 11 matching lines...) Expand all
22 #include "base/sys_string_conversions.h" 22 #include "base/sys_string_conversions.h"
23 #include "base/threading/thread_restrictions.h" 23 #include "base/threading/thread_restrictions.h"
24 #include "grit/generated_resources.h" 24 #include "grit/generated_resources.h"
25 #import "ui/base/cocoa/nib_loading.h" 25 #import "ui/base/cocoa/nib_loading.h"
26 #include "ui/base/l10n/l10n_util_mac.h" 26 #include "ui/base/l10n/l10n_util_mac.h"
27 27
28 namespace { 28 namespace {
29 29
30 const int kFileTypePopupTag = 1234; 30 const int kFileTypePopupTag = 1234;
31 31
32 CFStringRef CreateUTIFromExtensionList( 32 CFStringRef CreateUTIFromExtension(const FilePath::StringType& ext) {
33 const std::vector<FilePath::StringType>& ext_list) { 33 base::mac::ScopedCFTypeRef<CFStringRef> ext_cf(
34 // The extensions specified in FileTypeInfo contains a list of lists; the 34 base::SysUTF8ToCFStringRef(ext));
35 // example given there is: 35 return UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
36 // { { "htm", "html" }, { "txt" } } 36 ext_cf.get(),
37 // In that case, each extension list holds synonym extensions for the same 37 NULL);
38 // file type. With Uniform Type Identifiers there is one identifier that
39 // covers all those extensions, so if they are all synonymous anyway, just
40 // make a UTI from the first.
41 DCHECK(!ext_list.empty());
42 base::mac::ScopedCFTypeRef<CFStringRef> type_extension(
43 base::SysUTF8ToCFStringRef(ext_list[0]));
44 return UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension,
45 type_extension.get(),
46 NULL);
47 } 38 }
48 39
49 } // namespace 40 } // namespace
50 41
51 class SelectFileDialogImpl; 42 class SelectFileDialogImpl;
52 43
53 // A bridge class to act as the modal delegate to the save/open sheet and send 44 // A bridge class to act as the modal delegate to the save/open sheet and send
54 // the results to the C++ class. 45 // the results to the C++ class.
55 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> { 46 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> {
56 @private 47 @private
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 base::ThreadRestrictions::ScopedAllowIO allow_io; 210 base::ThreadRestrictions::ScopedAllowIO allow_io;
220 if (file_util::DirectoryExists(default_path)) { 211 if (file_util::DirectoryExists(default_path)) {
221 default_dir = base::SysUTF8ToNSString(default_path.value()); 212 default_dir = base::SysUTF8ToNSString(default_path.value());
222 } else { 213 } else {
223 default_dir = base::SysUTF8ToNSString(default_path.DirName().value()); 214 default_dir = base::SysUTF8ToNSString(default_path.DirName().value());
224 default_filename = 215 default_filename =
225 base::SysUTF8ToNSString(default_path.BaseName().value()); 216 base::SysUTF8ToNSString(default_path.BaseName().value());
226 } 217 }
227 } 218 }
228 219
229 NSMutableArray* allowed_file_types = nil; 220 NSArray* allowed_file_types = nil;
230 if (file_types) { 221 if (file_types) {
231 if (!file_types->extensions.empty()) { 222 if (!file_types->extensions.empty()) {
232 allowed_file_types = [NSMutableArray array]; 223 // While the example given in the header for FileTypeInfo lists an example
224 // |file_types->extensions| value as
225 // { { "htm", "html" }, { "txt" } }
226 // it is not always the case that the given extensions in one of the sub-
227 // lists are all synonyms. In fact, in the case of a <select> element with
228 // multiple "accept" types, all the extensions allowed for all the types
229 // will be part of one list. To be safe, allow the types of all the
230 // specified extensions.
231 NSMutableSet* file_type_set = [NSMutableSet set];
233 for (size_t i = 0; i < file_types->extensions.size(); ++i) { 232 for (size_t i = 0; i < file_types->extensions.size(); ++i) {
234 base::mac::ScopedCFTypeRef<CFStringRef> uti( 233 const std::vector<FilePath::StringType>& ext_list =
235 CreateUTIFromExtensionList(file_types->extensions[i])); 234 file_types->extensions[i];
236 [allowed_file_types addObject:base::mac::CFToNSCast(uti.get())]; 235 for (size_t j = 0; j < ext_list.size(); ++j) {
236 base::mac::ScopedCFTypeRef<CFStringRef> uti(
237 CreateUTIFromExtension(ext_list[j]));
238 [file_type_set addObject:base::mac::CFToNSCast(uti.get())];
239 }
237 } 240 }
241 allowed_file_types = [file_type_set allObjects];
238 } 242 }
239 if (type == SELECT_SAVEAS_FILE) 243 if (type == SELECT_SAVEAS_FILE)
240 [dialog setAllowedFileTypes:allowed_file_types]; 244 [dialog setAllowedFileTypes:allowed_file_types];
241 // else we'll pass it in when we run the open panel 245 // else we'll pass it in when we run the open panel
242 246
243 if (file_types->include_all_files) 247 if (file_types->include_all_files)
244 [dialog setAllowsOtherFileTypes:YES]; 248 [dialog setAllowsOtherFileTypes:YES];
245 249
246 if (file_types->extension_description_overrides.size() > 1) { 250 if (file_types->extension_description_overrides.size() > 1) {
247 NSView* accessory_view = GetAccessoryView(file_types, file_type_index); 251 NSView* accessory_view = GetAccessoryView(file_types, file_type_index);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 NSPopUpButton* popup = [accessory_view viewWithTag:kFileTypePopupTag]; 337 NSPopUpButton* popup = [accessory_view viewWithTag:kFileTypePopupTag];
334 DCHECK(popup); 338 DCHECK(popup);
335 339
336 size_t type_count = file_types->extensions.size(); 340 size_t type_count = file_types->extensions.size();
337 for (size_t type = 0; type < type_count; ++type) { 341 for (size_t type = 0; type < type_count; ++type) {
338 NSString* type_description; 342 NSString* type_description;
339 if (type < file_types->extension_description_overrides.size()) { 343 if (type < file_types->extension_description_overrides.size()) {
340 type_description = base::SysUTF16ToNSString( 344 type_description = base::SysUTF16ToNSString(
341 file_types->extension_description_overrides[type]); 345 file_types->extension_description_overrides[type]);
342 } else { 346 } else {
347 // No description given for a list of extensions; pick the first one from
348 // the list (arbitrarily) and use its description.
349 const std::vector<FilePath::StringType>& ext_list =
350 file_types->extensions[type];
351 DCHECK(!ext_list.empty());
343 base::mac::ScopedCFTypeRef<CFStringRef> uti( 352 base::mac::ScopedCFTypeRef<CFStringRef> uti(
344 CreateUTIFromExtensionList(file_types->extensions[type])); 353 CreateUTIFromExtension(ext_list[0]));
345 base::mac::ScopedCFTypeRef<CFStringRef> description( 354 base::mac::ScopedCFTypeRef<CFStringRef> description(
346 UTTypeCopyDescription(uti.get())); 355 UTTypeCopyDescription(uti.get()));
347 356
348 type_description = 357 type_description =
349 [[base::mac::CFToNSCast(description.get()) retain] autorelease]; 358 [[base::mac::CFToNSCast(description.get()) retain] autorelease];
350 } 359 }
351 [popup addItemWithTitle:type_description]; 360 [popup addItemWithTitle:type_description];
352 } 361 }
353 362
354 [popup selectItemAtIndex:file_type_index - 1]; // 1-based 363 [popup selectItemAtIndex:file_type_index - 1]; // 1-based
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 paths, 427 paths,
419 index); 428 index);
420 [panel release]; 429 [panel release];
421 } 430 }
422 431
423 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { 432 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename {
424 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename); 433 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename);
425 } 434 }
426 435
427 @end 436 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698