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/shell_dialogs/select_file_dialog.h" | 5 #include "ui/shell_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 10 matching lines...) Expand all Loading... |
21 #include "base/sys_string_conversions.h" | 21 #include "base/sys_string_conversions.h" |
22 #include "base/threading/thread_restrictions.h" | 22 #include "base/threading/thread_restrictions.h" |
23 #include "grit/ui_strings.h" | 23 #include "grit/ui_strings.h" |
24 #import "ui/base/cocoa/nib_loading.h" | 24 #import "ui/base/cocoa/nib_loading.h" |
25 #include "ui/base/l10n/l10n_util_mac.h" | 25 #include "ui/base/l10n/l10n_util_mac.h" |
26 | 26 |
27 namespace { | 27 namespace { |
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 base::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 } // namespace | 38 } // namespace |
39 | 39 |
40 class SelectFileDialogImpl; | 40 class SelectFileDialogImpl; |
41 | 41 |
(...skipping 24 matching lines...) Expand all Loading... |
66 | 66 |
67 // BaseShellDialog implementation. | 67 // BaseShellDialog implementation. |
68 virtual bool IsRunning(gfx::NativeWindow parent_window) const; | 68 virtual bool IsRunning(gfx::NativeWindow parent_window) const; |
69 virtual void ListenerDestroyed(); | 69 virtual void ListenerDestroyed(); |
70 | 70 |
71 // Callback from ObjC bridge. | 71 // Callback from ObjC bridge. |
72 void FileWasSelected(NSSavePanel* dialog, | 72 void FileWasSelected(NSSavePanel* dialog, |
73 NSWindow* parent_window, | 73 NSWindow* parent_window, |
74 bool was_cancelled, | 74 bool was_cancelled, |
75 bool is_multi, | 75 bool is_multi, |
76 const std::vector<FilePath>& files, | 76 const std::vector<base::FilePath>& files, |
77 int index); | 77 int index); |
78 | 78 |
79 bool ShouldEnableFilename(NSSavePanel* dialog, NSString* filename); | 79 bool ShouldEnableFilename(NSSavePanel* dialog, NSString* filename); |
80 | 80 |
81 protected: | 81 protected: |
82 // SelectFileDialog implementation. | 82 // SelectFileDialog implementation. |
83 // |params| is user data we pass back via the Listener interface. | 83 // |params| is user data we pass back via the Listener interface. |
84 virtual void SelectFileImpl(Type type, | 84 virtual void SelectFileImpl( |
85 const string16& title, | 85 Type type, |
86 const FilePath& default_path, | 86 const string16& title, |
87 const FileTypeInfo* file_types, | 87 const base::FilePath& default_path, |
88 int file_type_index, | 88 const FileTypeInfo* file_types, |
89 const FilePath::StringType& default_extension, | 89 int file_type_index, |
90 gfx::NativeWindow owning_window, | 90 const base::FilePath::StringType& default_extension, |
91 void* params) OVERRIDE; | 91 gfx::NativeWindow owning_window, |
| 92 void* params) OVERRIDE; |
92 | 93 |
93 private: | 94 private: |
94 virtual ~SelectFileDialogImpl(); | 95 virtual ~SelectFileDialogImpl(); |
95 | 96 |
96 // Gets the accessory view for the save dialog. | 97 // Gets the accessory view for the save dialog. |
97 NSView* GetAccessoryView(const FileTypeInfo* file_types, | 98 NSView* GetAccessoryView(const FileTypeInfo* file_types, |
98 int file_type_index); | 99 int file_type_index); |
99 | 100 |
100 virtual bool HasMultipleFileTypeChoicesImpl(); | 101 virtual bool HasMultipleFileTypeChoicesImpl(); |
101 | 102 |
(...skipping 22 matching lines...) Expand all Loading... |
124 } | 125 } |
125 | 126 |
126 bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const { | 127 bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const { |
127 return parents_.find(parent_window) != parents_.end(); | 128 return parents_.find(parent_window) != parents_.end(); |
128 } | 129 } |
129 | 130 |
130 void SelectFileDialogImpl::ListenerDestroyed() { | 131 void SelectFileDialogImpl::ListenerDestroyed() { |
131 listener_ = NULL; | 132 listener_ = NULL; |
132 } | 133 } |
133 | 134 |
134 void SelectFileDialogImpl::FileWasSelected(NSSavePanel* dialog, | 135 void SelectFileDialogImpl::FileWasSelected( |
135 NSWindow* parent_window, | 136 NSSavePanel* dialog, |
136 bool was_cancelled, | 137 NSWindow* parent_window, |
137 bool is_multi, | 138 bool was_cancelled, |
138 const std::vector<FilePath>& files, | 139 bool is_multi, |
139 int index) { | 140 const std::vector<base::FilePath>& files, |
| 141 int index) { |
140 void* params = params_map_[dialog]; | 142 void* params = params_map_[dialog]; |
141 params_map_.erase(dialog); | 143 params_map_.erase(dialog); |
142 parents_.erase(parent_window); | 144 parents_.erase(parent_window); |
143 type_map_.erase(dialog); | 145 type_map_.erase(dialog); |
144 | 146 |
145 [dialog setDelegate:nil]; | 147 [dialog setDelegate:nil]; |
146 | 148 |
147 if (!listener_) | 149 if (!listener_) |
148 return; | 150 return; |
149 | 151 |
(...skipping 13 matching lines...) Expand all Loading... |
163 // If this is a single open file dialog, disable selecting packages. | 165 // If this is a single open file dialog, disable selecting packages. |
164 if (type_map_[dialog] != SELECT_OPEN_FILE) | 166 if (type_map_[dialog] != SELECT_OPEN_FILE) |
165 return true; | 167 return true; |
166 | 168 |
167 return ![[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename]; | 169 return ![[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename]; |
168 } | 170 } |
169 | 171 |
170 void SelectFileDialogImpl::SelectFileImpl( | 172 void SelectFileDialogImpl::SelectFileImpl( |
171 Type type, | 173 Type type, |
172 const string16& title, | 174 const string16& title, |
173 const FilePath& default_path, | 175 const base::FilePath& default_path, |
174 const FileTypeInfo* file_types, | 176 const FileTypeInfo* file_types, |
175 int file_type_index, | 177 int file_type_index, |
176 const FilePath::StringType& default_extension, | 178 const base::FilePath::StringType& default_extension, |
177 gfx::NativeWindow owning_window, | 179 gfx::NativeWindow owning_window, |
178 void* params) { | 180 void* params) { |
179 DCHECK(type == SELECT_FOLDER || | 181 DCHECK(type == SELECT_FOLDER || |
180 type == SELECT_OPEN_FILE || | 182 type == SELECT_OPEN_FILE || |
181 type == SELECT_OPEN_MULTI_FILE || | 183 type == SELECT_OPEN_MULTI_FILE || |
182 type == SELECT_SAVEAS_FILE); | 184 type == SELECT_SAVEAS_FILE); |
183 parents_.insert(owning_window); | 185 parents_.insert(owning_window); |
184 | 186 |
185 // Note: we need to retain the dialog as owning_window can be null. | 187 // Note: we need to retain the dialog as owning_window can be null. |
186 // (See http://crbug.com/29213 .) | 188 // (See http://crbug.com/29213 .) |
(...skipping 27 matching lines...) Expand all Loading... |
214 // While the example given in the header for FileTypeInfo lists an example | 216 // While the example given in the header for FileTypeInfo lists an example |
215 // |file_types->extensions| value as | 217 // |file_types->extensions| value as |
216 // { { "htm", "html" }, { "txt" } } | 218 // { { "htm", "html" }, { "txt" } } |
217 // it is not always the case that the given extensions in one of the sub- | 219 // 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 | 220 // 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 | 221 // 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 | 222 // will be part of one list. To be safe, allow the types of all the |
221 // specified extensions. | 223 // specified extensions. |
222 NSMutableSet* file_type_set = [NSMutableSet set]; | 224 NSMutableSet* file_type_set = [NSMutableSet set]; |
223 for (size_t i = 0; i < file_types->extensions.size(); ++i) { | 225 for (size_t i = 0; i < file_types->extensions.size(); ++i) { |
224 const std::vector<FilePath::StringType>& ext_list = | 226 const std::vector<base::FilePath::StringType>& ext_list = |
225 file_types->extensions[i]; | 227 file_types->extensions[i]; |
226 for (size_t j = 0; j < ext_list.size(); ++j) { | 228 for (size_t j = 0; j < ext_list.size(); ++j) { |
227 base::mac::ScopedCFTypeRef<CFStringRef> uti( | 229 base::mac::ScopedCFTypeRef<CFStringRef> uti( |
228 CreateUTIFromExtension(ext_list[j])); | 230 CreateUTIFromExtension(ext_list[j])); |
229 [file_type_set addObject:base::mac::CFToNSCast(uti.get())]; | 231 [file_type_set addObject:base::mac::CFToNSCast(uti.get())]; |
230 | 232 |
231 // Always allow the extension itself, in case the UTI doesn't map | 233 // Always allow the extension itself, in case the UTI doesn't map |
232 // back to the original extension correctly. This occurs with dynamic | 234 // back to the original extension correctly. This occurs with dynamic |
233 // UTIs on 10.7 and 10.8. | 235 // UTIs on 10.7 and 10.8. |
234 // See http://crbug.com/148840, http://openradar.me/12316273 | 236 // See http://crbug.com/148840, http://openradar.me/12316273 |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 | 330 |
329 size_t type_count = file_types->extensions.size(); | 331 size_t type_count = file_types->extensions.size(); |
330 for (size_t type = 0; type < type_count; ++type) { | 332 for (size_t type = 0; type < type_count; ++type) { |
331 NSString* type_description; | 333 NSString* type_description; |
332 if (type < file_types->extension_description_overrides.size()) { | 334 if (type < file_types->extension_description_overrides.size()) { |
333 type_description = base::SysUTF16ToNSString( | 335 type_description = base::SysUTF16ToNSString( |
334 file_types->extension_description_overrides[type]); | 336 file_types->extension_description_overrides[type]); |
335 } else { | 337 } else { |
336 // No description given for a list of extensions; pick the first one from | 338 // No description given for a list of extensions; pick the first one from |
337 // the list (arbitrarily) and use its description. | 339 // the list (arbitrarily) and use its description. |
338 const std::vector<FilePath::StringType>& ext_list = | 340 const std::vector<base::FilePath::StringType>& ext_list = |
339 file_types->extensions[type]; | 341 file_types->extensions[type]; |
340 DCHECK(!ext_list.empty()); | 342 DCHECK(!ext_list.empty()); |
341 base::mac::ScopedCFTypeRef<CFStringRef> uti( | 343 base::mac::ScopedCFTypeRef<CFStringRef> uti( |
342 CreateUTIFromExtension(ext_list[0])); | 344 CreateUTIFromExtension(ext_list[0])); |
343 base::mac::ScopedCFTypeRef<CFStringRef> description( | 345 base::mac::ScopedCFTypeRef<CFStringRef> description( |
344 UTTypeCopyDescription(uti.get())); | 346 UTTypeCopyDescription(uti.get())); |
345 | 347 |
346 type_description = | 348 type_description = |
347 [[base::mac::CFToNSCast(description.get()) retain] autorelease]; | 349 [[base::mac::CFToNSCast(description.get()) retain] autorelease]; |
348 } | 350 } |
(...skipping 16 matching lines...) Expand all Loading... |
365 selectFileDialogImpl_ = s; | 367 selectFileDialogImpl_ = s; |
366 } | 368 } |
367 return self; | 369 return self; |
368 } | 370 } |
369 | 371 |
370 - (void)endedPanel:(NSSavePanel*)panel | 372 - (void)endedPanel:(NSSavePanel*)panel |
371 didCancel:(bool)did_cancel | 373 didCancel:(bool)did_cancel |
372 type:(ui::SelectFileDialog::Type)type | 374 type:(ui::SelectFileDialog::Type)type |
373 parentWindow:(NSWindow*)parentWindow { | 375 parentWindow:(NSWindow*)parentWindow { |
374 int index = 0; | 376 int index = 0; |
375 std::vector<FilePath> paths; | 377 std::vector<base::FilePath> paths; |
376 if (!did_cancel) { | 378 if (!did_cancel) { |
377 if (type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) { | 379 if (type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) { |
378 if ([[panel URL] isFileURL]) | 380 if ([[panel URL] isFileURL]) { |
379 paths.push_back(FilePath(base::SysNSStringToUTF8([[panel URL] path]))); | 381 paths.push_back(base::FilePath( |
| 382 base::SysNSStringToUTF8([[panel URL] path]))); |
| 383 } |
380 | 384 |
381 NSView* accessoryView = [panel accessoryView]; | 385 NSView* accessoryView = [panel accessoryView]; |
382 if (accessoryView) { | 386 if (accessoryView) { |
383 NSPopUpButton* popup = [accessoryView viewWithTag:kFileTypePopupTag]; | 387 NSPopUpButton* popup = [accessoryView viewWithTag:kFileTypePopupTag]; |
384 if (popup) { | 388 if (popup) { |
385 // File type indexes are 1-based. | 389 // File type indexes are 1-based. |
386 index = [popup indexOfSelectedItem] + 1; | 390 index = [popup indexOfSelectedItem] + 1; |
387 } | 391 } |
388 } else { | 392 } else { |
389 index = 1; | 393 index = 1; |
390 } | 394 } |
391 } else { | 395 } else { |
392 CHECK([panel isKindOfClass:[NSOpenPanel class]]); | 396 CHECK([panel isKindOfClass:[NSOpenPanel class]]); |
393 NSArray* urls = [static_cast<NSOpenPanel*>(panel) URLs]; | 397 NSArray* urls = [static_cast<NSOpenPanel*>(panel) URLs]; |
394 for (NSURL* url in urls) | 398 for (NSURL* url in urls) |
395 if ([url isFileURL]) | 399 if ([url isFileURL]) |
396 paths.push_back(FilePath(base::SysNSStringToUTF8([url path]))); | 400 paths.push_back(base::FilePath(base::SysNSStringToUTF8([url path]))); |
397 } | 401 } |
398 } | 402 } |
399 | 403 |
400 bool isMulti = type == ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; | 404 bool isMulti = type == ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE; |
401 selectFileDialogImpl_->FileWasSelected(panel, | 405 selectFileDialogImpl_->FileWasSelected(panel, |
402 parentWindow, | 406 parentWindow, |
403 did_cancel, | 407 did_cancel, |
404 isMulti, | 408 isMulti, |
405 paths, | 409 paths, |
406 index); | 410 index); |
407 [panel release]; | 411 [panel release]; |
408 } | 412 } |
409 | 413 |
410 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { | 414 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { |
411 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename); | 415 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename); |
412 } | 416 } |
413 | 417 |
414 @end | 418 @end |
415 | 419 |
416 namespace ui { | 420 namespace ui { |
417 | 421 |
418 SelectFileDialog* CreateMacSelectFileDialog( | 422 SelectFileDialog* CreateMacSelectFileDialog( |
419 SelectFileDialog::Listener* listener, | 423 SelectFileDialog::Listener* listener, |
420 SelectFilePolicy* policy) { | 424 SelectFilePolicy* policy) { |
421 return new SelectFileDialogImpl(listener, policy); | 425 return new SelectFileDialogImpl(listener, policy); |
422 } | 426 } |
423 | 427 |
424 } // namespace ui | 428 } // namespace ui |
OLD | NEW |