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

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: 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(
33 const std::vector<FilePath::StringType>& ext_list) {
34 // The extensions specified in FileTypeInfo contains a list of lists; the
35 // example given there is:
36 // { { "htm", "html" }, { "txt" } }
37 // In that case, each extension list holds synonym extensions for the same
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 }
48
49 } // namespace 32 } // namespace
50 33
51 class SelectFileDialogImpl; 34 class SelectFileDialogImpl;
52 35
53 // A bridge class to act as the modal delegate to the save/open sheet and send 36 // A bridge class to act as the modal delegate to the save/open sheet and send
54 // the results to the C++ class. 37 // the results to the C++ class.
55 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> { 38 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> {
56 @private 39 @private
57 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us 40 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us
58 } 41 }
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 base::ThreadRestrictions::ScopedAllowIO allow_io; 202 base::ThreadRestrictions::ScopedAllowIO allow_io;
220 if (file_util::DirectoryExists(default_path)) { 203 if (file_util::DirectoryExists(default_path)) {
221 default_dir = base::SysUTF8ToNSString(default_path.value()); 204 default_dir = base::SysUTF8ToNSString(default_path.value());
222 } else { 205 } else {
223 default_dir = base::SysUTF8ToNSString(default_path.DirName().value()); 206 default_dir = base::SysUTF8ToNSString(default_path.DirName().value());
224 default_filename = 207 default_filename =
225 base::SysUTF8ToNSString(default_path.BaseName().value()); 208 base::SysUTF8ToNSString(default_path.BaseName().value());
226 } 209 }
227 } 210 }
228 211
229 NSMutableArray* allowed_file_types = nil; 212 NSArray* allowed_file_types = nil;
230 if (file_types) { 213 if (file_types) {
231 if (!file_types->extensions.empty()) { 214 if (!file_types->extensions.empty()) {
232 allowed_file_types = [NSMutableArray array]; 215 // While the example given in the header for FileTypeInfo lists an example
216 // |file_types->extensions| value as
217 // { { "htm", "html" }, { "txt" } }
218 // it is not always the case that the given extensions in one of the sub-
219 // lists are all synonyms. In fact, in the case of a <select> element with
220 // multiple "accept" types, all the extensions allowed for all the types
221 // will be part of one list. To be safe, allow the types of all the
222 // specified extensions.
223 NSMutableSet* file_type_set = [NSMutableSet set];
233 for (size_t i = 0; i < file_types->extensions.size(); ++i) { 224 for (size_t i = 0; i < file_types->extensions.size(); ++i) {
234 base::mac::ScopedCFTypeRef<CFStringRef> uti( 225 const std::vector<FilePath::StringType>& ext_list =
235 CreateUTIFromExtensionList(file_types->extensions[i])); 226 file_types->extensions[i];
236 [allowed_file_types addObject:base::mac::CFToNSCast(uti.get())]; 227 for (size_t j = 0; j < ext_list.size(); ++j) {
228 NSString* type_extension = base::SysUTF8ToNSString(ext_list[j]);
Nico 2012/05/15 15:38:50 nit: it might be worth it to have a function that
Avi (use Gerrit) 2012/05/15 15:54:13 Done.
229 base::mac::ScopedCFTypeRef<CFStringRef> uti(
230 UTTypeCreatePreferredIdentifierForTag(
231 kUTTagClassFilenameExtension,
232 base::mac::NSToCFCast(type_extension),
233 NULL));
234 [file_type_set addObject:base::mac::CFToNSCast(uti.get())];
235 }
237 } 236 }
237 allowed_file_types = [file_type_set allObjects];
238 } 238 }
239 if (type == SELECT_SAVEAS_FILE) 239 if (type == SELECT_SAVEAS_FILE)
240 [dialog setAllowedFileTypes:allowed_file_types]; 240 [dialog setAllowedFileTypes:allowed_file_types];
241 // else we'll pass it in when we run the open panel 241 // else we'll pass it in when we run the open panel
242 242
243 if (file_types->include_all_files) 243 if (file_types->include_all_files)
244 [dialog setAllowsOtherFileTypes:YES]; 244 [dialog setAllowsOtherFileTypes:YES];
245 245
246 if (file_types->extension_description_overrides.size() > 1) { 246 if (file_types->extension_description_overrides.size() > 1) {
247 NSView* accessory_view = GetAccessoryView(file_types, file_type_index); 247 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]; 333 NSPopUpButton* popup = [accessory_view viewWithTag:kFileTypePopupTag];
334 DCHECK(popup); 334 DCHECK(popup);
335 335
336 size_t type_count = file_types->extensions.size(); 336 size_t type_count = file_types->extensions.size();
337 for (size_t type = 0; type < type_count; ++type) { 337 for (size_t type = 0; type < type_count; ++type) {
338 NSString* type_description; 338 NSString* type_description;
339 if (type < file_types->extension_description_overrides.size()) { 339 if (type < file_types->extension_description_overrides.size()) {
340 type_description = base::SysUTF16ToNSString( 340 type_description = base::SysUTF16ToNSString(
341 file_types->extension_description_overrides[type]); 341 file_types->extension_description_overrides[type]);
342 } else { 342 } else {
343 // No description given for a list of extensions; pick the first one from
344 // the list (arbitrarily) and use its description.
345 const std::vector<FilePath::StringType>& ext_list =
346 file_types->extensions[type];
347 DCHECK(!ext_list.empty());
348 NSString* type_extension = base::SysUTF8ToNSString(ext_list[0]);
343 base::mac::ScopedCFTypeRef<CFStringRef> uti( 349 base::mac::ScopedCFTypeRef<CFStringRef> uti(
344 CreateUTIFromExtensionList(file_types->extensions[type])); 350 UTTypeCreatePreferredIdentifierForTag(
351 kUTTagClassFilenameExtension,
352 base::mac::NSToCFCast(type_extension),
353 NULL));
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