OLD | NEW |
---|---|
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 "ui/base/dialogs/select_file_dialog.h" | 5 #include "ui/base/dialogs/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 17 matching lines...) Expand all Loading... | |
28 | 28 |
29 const int kFileTypePopupTag = 1234; | 29 const int kFileTypePopupTag = 1234; |
30 | 30 |
31 CFStringRef CreateUTIFromExtension(const FilePath::StringType& ext) { | 31 CFStringRef CreateUTIFromExtension(const FilePath::StringType& ext) { |
32 base::mac::ScopedCFTypeRef<CFStringRef> ext_cf( | 32 base::mac::ScopedCFTypeRef<CFStringRef> ext_cf( |
33 base::SysUTF8ToCFStringRef(ext)); | 33 base::SysUTF8ToCFStringRef(ext)); |
34 return UTTypeCreatePreferredIdentifierForTag( | 34 return UTTypeCreatePreferredIdentifierForTag( |
35 kUTTagClassFilenameExtension, ext_cf.get(), NULL); | 35 kUTTagClassFilenameExtension, ext_cf.get(), NULL); |
36 } | 36 } |
37 | 37 |
38 FilePath::StringType LastExtension(const FilePath::StringType& ext) { | |
39 size_t last_dot = ext.rfind('.'); | |
40 if (last_dot == std::string::npos) | |
41 return ext; | |
42 return ext.substr(last_dot + 1); | |
Avi (use Gerrit)
2012/11/13 20:41:00
Isn't there something on FilePath that would do th
davidben
2012/11/13 20:53:28
There is FilePath::Extension() and friends, but it
| |
43 } | |
44 | |
38 } // namespace | 45 } // namespace |
39 | 46 |
40 class SelectFileDialogImpl; | 47 class SelectFileDialogImpl; |
41 | 48 |
42 // A bridge class to act as the modal delegate to the save/open sheet and send | 49 // A bridge class to act as the modal delegate to the save/open sheet and send |
43 // the results to the C++ class. | 50 // the results to the C++ class. |
44 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> { | 51 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> { |
45 @private | 52 @private |
46 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us | 53 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us |
47 } | 54 } |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 // it is not always the case that the given extensions in one of the sub- | 224 // it is not always the case that the given extensions in one of the sub- |
218 // lists are all synonyms. In fact, in the case of a <select> element with | 225 // lists are all synonyms. In fact, in the case of a <select> element with |
219 // multiple "accept" types, all the extensions allowed for all the types | 226 // multiple "accept" types, all the extensions allowed for all the types |
220 // will be part of one list. To be safe, allow the types of all the | 227 // will be part of one list. To be safe, allow the types of all the |
221 // specified extensions. | 228 // specified extensions. |
222 NSMutableSet* file_type_set = [NSMutableSet set]; | 229 NSMutableSet* file_type_set = [NSMutableSet set]; |
223 for (size_t i = 0; i < file_types->extensions.size(); ++i) { | 230 for (size_t i = 0; i < file_types->extensions.size(); ++i) { |
224 const std::vector<FilePath::StringType>& ext_list = | 231 const std::vector<FilePath::StringType>& ext_list = |
225 file_types->extensions[i]; | 232 file_types->extensions[i]; |
226 for (size_t j = 0; j < ext_list.size(); ++j) { | 233 for (size_t j = 0; j < ext_list.size(); ++j) { |
234 // NSSavePanel cannot handle extensions like tar.gz, so we | |
Avi (use Gerrit)
2012/11/13 20:41:00
It's not an NSSavePanel issue, but a UTI issue; a
| |
235 // remove all but the last component. | |
236 std::string ext = LastExtension(ext_list[j]); | |
227 base::mac::ScopedCFTypeRef<CFStringRef> uti( | 237 base::mac::ScopedCFTypeRef<CFStringRef> uti( |
228 CreateUTIFromExtension(ext_list[j])); | 238 CreateUTIFromExtension(ext)); |
229 [file_type_set addObject:base::mac::CFToNSCast(uti.get())]; | 239 [file_type_set addObject:base::mac::CFToNSCast(uti.get())]; |
230 | 240 |
231 // Always allow the extension itself, in case the UTI doesn't map | 241 // Always allow the extension itself, in case the UTI doesn't map |
232 // back to the original extension correctly. This occurs with dynamic | 242 // back to the original extension correctly. This occurs with dynamic |
233 // UTIs on 10.7 and 10.8. | 243 // UTIs on 10.7 and 10.8. |
234 // See http://crbug.com/148840, http://openradar.me/12316273 | 244 // See http://crbug.com/148840, http://openradar.me/12316273 |
235 base::mac::ScopedCFTypeRef<CFStringRef> ext_cf( | 245 base::mac::ScopedCFTypeRef<CFStringRef> ext_cf( |
236 base::SysUTF8ToCFStringRef(ext_list[j])); | 246 base::SysUTF8ToCFStringRef(ext)); |
237 [file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())]; | 247 [file_type_set addObject:base::mac::CFToNSCast(ext_cf.get())]; |
238 } | 248 } |
239 } | 249 } |
240 allowed_file_types = [file_type_set allObjects]; | 250 allowed_file_types = [file_type_set allObjects]; |
241 } | 251 } |
242 if (type == SELECT_SAVEAS_FILE) | 252 if (type == SELECT_SAVEAS_FILE) |
243 [dialog setAllowedFileTypes:allowed_file_types]; | 253 [dialog setAllowedFileTypes:allowed_file_types]; |
244 // else we'll pass it in when we run the open panel | 254 // else we'll pass it in when we run the open panel |
245 | 255 |
246 if (file_types->include_all_files || file_types->extensions.empty()) | 256 if (file_types->include_all_files || file_types->extensions.empty()) |
247 [dialog setAllowsOtherFileTypes:YES]; | 257 [dialog setAllowsOtherFileTypes:YES]; |
248 | 258 |
249 if (file_types->extension_description_overrides.size() > 1) { | 259 if (file_types->extension_description_overrides.size() > 1) { |
250 NSView* accessory_view = GetAccessoryView(file_types, file_type_index); | 260 NSView* accessory_view = GetAccessoryView(file_types, file_type_index); |
251 [dialog setAccessoryView:accessory_view]; | 261 [dialog setAccessoryView:accessory_view]; |
252 } | 262 } |
253 } else { | 263 } else { |
254 // If no type info is specified, anything goes. | 264 // If no type info is specified, anything goes. |
255 [dialog setAllowsOtherFileTypes:YES]; | 265 [dialog setAllowsOtherFileTypes:YES]; |
256 } | 266 } |
257 hasMultipleFileTypeChoices_ = | 267 hasMultipleFileTypeChoices_ = |
258 file_types ? file_types->extensions.size() > 1 : true; | 268 file_types ? file_types->extensions.size() > 1 : true; |
259 | 269 |
260 if (!default_extension.empty()) | 270 if (!default_extension.empty()) |
261 [dialog setAllowedFileTypes:@[base::SysUTF8ToNSString(default_extension)]]; | 271 [dialog setAllowedFileTypes:@[base::SysUTF8ToNSString( |
272 LastExtension(default_extension))]]; | |
262 | 273 |
263 params_map_[dialog] = params; | 274 params_map_[dialog] = params; |
264 type_map_[dialog] = type; | 275 type_map_[dialog] = type; |
265 | 276 |
266 if (type == SELECT_SAVEAS_FILE) { | 277 if (type == SELECT_SAVEAS_FILE) { |
267 [dialog setCanSelectHiddenExtension:YES]; | 278 [dialog setCanSelectHiddenExtension:YES]; |
268 } else { | 279 } else { |
269 NSOpenPanel* open_dialog = (NSOpenPanel*)dialog; | 280 NSOpenPanel* open_dialog = (NSOpenPanel*)dialog; |
270 | 281 |
271 if (type == SELECT_OPEN_MULTI_FILE) | 282 if (type == SELECT_OPEN_MULTI_FILE) |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
415 | 426 |
416 namespace ui { | 427 namespace ui { |
417 | 428 |
418 SelectFileDialog* CreateMacSelectFileDialog( | 429 SelectFileDialog* CreateMacSelectFileDialog( |
419 SelectFileDialog::Listener* listener, | 430 SelectFileDialog::Listener* listener, |
420 SelectFilePolicy* policy) { | 431 SelectFilePolicy* policy) { |
421 return new SelectFileDialogImpl(listener, policy); | 432 return new SelectFileDialogImpl(listener, policy); |
422 } | 433 } |
423 | 434 |
424 } // namespace ui | 435 } // namespace ui |
OLD | NEW |