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

Side by Side Diff: ui/base/dialogs/select_file_dialog_mac.mm

Issue 10829053: mac: Switch to "new" (10.6) block-based panel apis (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: crash less Created 8 years, 4 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 "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 30 matching lines...) Expand all
41 41
42 // A bridge class to act as the modal delegate to the save/open sheet and send 42 // A bridge class to act as the modal delegate to the save/open sheet and send
43 // the results to the C++ class. 43 // the results to the C++ class.
44 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> { 44 @interface SelectFileDialogBridge : NSObject<NSOpenSavePanelDelegate> {
45 @private 45 @private
46 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us 46 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us
47 } 47 }
48 48
49 - (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s; 49 - (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s;
50 - (void)endedPanel:(NSSavePanel*)panel 50 - (void)endedPanel:(NSSavePanel*)panel
51 withReturn:(int)returnCode 51 didCancel:(bool)did_cancel
52 context:(void*)context; 52 type:(ui::SelectFileDialog::Type)type
53 parentWindow:(NSWindow*)parentWindow;
53 54
54 // NSSavePanel delegate method 55 // NSSavePanel delegate method
55 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename; 56 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename;
56 57
57 @end 58 @end
58 59
59 // Implementation of SelectFileDialog that shows Cocoa dialogs for choosing a 60 // Implementation of SelectFileDialog that shows Cocoa dialogs for choosing a
60 // file or folder. 61 // file or folder.
61 class SelectFileDialogImpl : public ui::SelectFileDialog { 62 class SelectFileDialogImpl : public ui::SelectFileDialog {
62 public: 63 public:
63 explicit SelectFileDialogImpl(Listener* listener, 64 explicit SelectFileDialogImpl(Listener* listener,
64 ui::SelectFilePolicy* policy); 65 ui::SelectFilePolicy* policy);
65 66
66 // BaseShellDialog implementation. 67 // BaseShellDialog implementation.
67 virtual bool IsRunning(gfx::NativeWindow parent_window) const; 68 virtual bool IsRunning(gfx::NativeWindow parent_window) const;
68 virtual void ListenerDestroyed(); 69 virtual void ListenerDestroyed();
69 70
70 // Callback from ObjC bridge. 71 // Callback from ObjC bridge.
71 void FileWasSelected(NSSavePanel* dialog, 72 void FileWasSelected(NSSavePanel* dialog,
72 NSWindow* parent_window, 73 NSWindow* parent_window,
73 bool was_cancelled, 74 bool was_cancelled,
74 bool is_multi, 75 bool is_multi,
75 const std::vector<FilePath>& files, 76 const std::vector<FilePath>& files,
76 int index); 77 int index);
77 78
78 bool ShouldEnableFilename(NSSavePanel* dialog, NSString* filename); 79 bool ShouldEnableFilename(NSSavePanel* dialog, NSString* filename);
79 80
80 struct SheetContext {
81 Type type;
82 NSWindow* owning_window;
83 };
84
85 protected: 81 protected:
86 // SelectFileDialog implementation. 82 // SelectFileDialog implementation.
87 // |params| is user data we pass back via the Listener interface. 83 // |params| is user data we pass back via the Listener interface.
88 virtual void SelectFileImpl(Type type, 84 virtual void SelectFileImpl(Type type,
89 const string16& title, 85 const string16& title,
90 const FilePath& default_path, 86 const FilePath& default_path,
91 const FileTypeInfo* file_types, 87 const FileTypeInfo* file_types,
92 int file_type_index, 88 int file_type_index,
93 const FilePath::StringType& default_extension, 89 const FilePath::StringType& default_extension,
94 gfx::NativeWindow owning_window, 90 gfx::NativeWindow owning_window,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 void* params = params_map_[dialog]; 140 void* params = params_map_[dialog];
145 params_map_.erase(dialog); 141 params_map_.erase(dialog);
146 parents_.erase(parent_window); 142 parents_.erase(parent_window);
147 type_map_.erase(dialog); 143 type_map_.erase(dialog);
148 144
149 [dialog setDelegate:nil]; 145 [dialog setDelegate:nil];
150 146
151 if (!listener_) 147 if (!listener_)
152 return; 148 return;
153 149
154 if (was_cancelled) { 150 if (was_cancelled || files.empty()) {
155 listener_->FileSelectionCanceled(params); 151 listener_->FileSelectionCanceled(params);
156 } else { 152 } else {
157 if (is_multi) { 153 if (is_multi) {
158 listener_->MultiFilesSelected(files, params); 154 listener_->MultiFilesSelected(files, params);
159 } else { 155 } else {
160 listener_->FileSelected(files[0], index, params); 156 listener_->FileSelected(files[0], index, params);
161 } 157 }
162 } 158 }
163 } 159 }
164 160
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 [dialog setAccessoryView:accessory_view]; 243 [dialog setAccessoryView:accessory_view];
248 } 244 }
249 } else { 245 } else {
250 // If no type info is specified, anything goes. 246 // If no type info is specified, anything goes.
251 [dialog setAllowsOtherFileTypes:YES]; 247 [dialog setAllowsOtherFileTypes:YES];
252 } 248 }
253 hasMultipleFileTypeChoices_ = 249 hasMultipleFileTypeChoices_ =
254 file_types ? file_types->extensions.size() > 1 : true; 250 file_types ? file_types->extensions.size() > 1 : true;
255 251
256 if (!default_extension.empty()) 252 if (!default_extension.empty())
257 [dialog setRequiredFileType:base::SysUTF8ToNSString(default_extension)]; 253 [dialog setAllowedFileTypes:@[base::SysUTF8ToNSString(default_extension)]];
258 254
259 params_map_[dialog] = params; 255 params_map_[dialog] = params;
260 type_map_[dialog] = type; 256 type_map_[dialog] = type;
261 257
262 SheetContext* context = new SheetContext;
263
264 // |context| should never be NULL, but we are seeing indications otherwise.
265 // This CHECK is here to confirm if we are actually getting NULL
266 // |context|s. http://crbug.com/58959
267 CHECK(context);
268 context->type = type;
269 context->owning_window = owning_window;
270
271 if (type == SELECT_SAVEAS_FILE) { 258 if (type == SELECT_SAVEAS_FILE) {
272 [dialog setCanSelectHiddenExtension:YES]; 259 [dialog setCanSelectHiddenExtension:YES];
273 [dialog beginSheetForDirectory:default_dir
274 file:default_filename
275 modalForWindow:owning_window
276 modalDelegate:bridge_.get()
277 didEndSelector:@selector(endedPanel:withReturn:context:)
278 contextInfo:context];
279 } else { 260 } else {
280 NSOpenPanel* open_dialog = (NSOpenPanel*)dialog; 261 NSOpenPanel* open_dialog = (NSOpenPanel*)dialog;
281 262
282 if (type == SELECT_OPEN_MULTI_FILE) 263 if (type == SELECT_OPEN_MULTI_FILE)
283 [open_dialog setAllowsMultipleSelection:YES]; 264 [open_dialog setAllowsMultipleSelection:YES];
284 else 265 else
285 [open_dialog setAllowsMultipleSelection:NO]; 266 [open_dialog setAllowsMultipleSelection:NO];
286 267
287 if (type == SELECT_FOLDER) { 268 if (type == SELECT_FOLDER) {
288 [open_dialog setCanChooseFiles:NO]; 269 [open_dialog setCanChooseFiles:NO];
289 [open_dialog setCanChooseDirectories:YES]; 270 [open_dialog setCanChooseDirectories:YES];
290 [open_dialog setCanCreateDirectories:YES]; 271 [open_dialog setCanCreateDirectories:YES];
291 NSString *prompt = l10n_util::GetNSString(IDS_SELECT_FOLDER_BUTTON_TITLE); 272 NSString *prompt = l10n_util::GetNSString(IDS_SELECT_FOLDER_BUTTON_TITLE);
292 [open_dialog setPrompt:prompt]; 273 [open_dialog setPrompt:prompt];
293 } else { 274 } else {
294 [open_dialog setCanChooseFiles:YES]; 275 [open_dialog setCanChooseFiles:YES];
295 [open_dialog setCanChooseDirectories:NO]; 276 [open_dialog setCanChooseDirectories:NO];
296 } 277 }
297 278
298 [open_dialog setDelegate:bridge_.get()]; 279 [open_dialog setDelegate:bridge_.get()];
299 [open_dialog beginSheetForDirectory:default_dir 280 [open_dialog setAllowedFileTypes:allowed_file_types];
300 file:default_filename
301 types:allowed_file_types
302 modalForWindow:owning_window
303 modalDelegate:bridge_.get()
304 didEndSelector:@selector(endedPanel:withReturn:context:)
305 contextInfo:context];
306 } 281 }
282 if (default_dir)
283 [dialog setDirectoryURL:[NSURL fileURLWithPath:default_dir]];
284 if (default_filename)
285 [dialog setNameFieldStringValue:default_filename];
286 [dialog beginSheetModalForWindow:owning_window
287 completionHandler:^(NSInteger result) {
288 [bridge_.get() endedPanel:dialog
289 didCancel:result != NSFileHandlingPanelOKButton
290 type:type
291 parentWindow:owning_window];
292 }];
Avi (use Gerrit) 2012/07/27 15:01:21 Indentation is wrong here; closing braces match th
307 } 293 }
308 294
309 SelectFileDialogImpl::~SelectFileDialogImpl() { 295 SelectFileDialogImpl::~SelectFileDialogImpl() {
310 // Walk through the open dialogs and close them all. Use a temporary vector 296 // Walk through the open dialogs and close them all. Use a temporary vector
311 // to hold the pointers, since we can't delete from the map as we're iterating 297 // to hold the pointers, since we can't delete from the map as we're iterating
312 // through it. 298 // through it.
313 std::vector<NSSavePanel*> panels; 299 std::vector<NSSavePanel*> panels;
314 for (std::map<NSSavePanel*, void*>::iterator it = params_map_.begin(); 300 for (std::map<NSSavePanel*, void*>::iterator it = params_map_.begin();
315 it != params_map_.end(); ++it) { 301 it != params_map_.end(); ++it) {
316 panels.push_back(it->first); 302 panels.push_back(it->first);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 353
368 - (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s { 354 - (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s {
369 self = [super init]; 355 self = [super init];
370 if (self != nil) { 356 if (self != nil) {
371 selectFileDialogImpl_ = s; 357 selectFileDialogImpl_ = s;
372 } 358 }
373 return self; 359 return self;
374 } 360 }
375 361
376 - (void)endedPanel:(NSSavePanel*)panel 362 - (void)endedPanel:(NSSavePanel*)panel
377 withReturn:(int)returnCode 363 didCancel:(bool)did_cancel
378 context:(void*)context { 364 type:(ui::SelectFileDialog::Type)type
379 // |context| should never be NULL, but we are seeing indications otherwise. 365 parentWindow:(NSWindow*)parentWindow {
380 // This CHECK is here to confirm if we are actually getting NULL
381 // |context|s. http://crbug.com/58959
382 CHECK(context);
383
384 int index = 0; 366 int index = 0;
385 SelectFileDialogImpl::SheetContext* context_struct =
386 (SelectFileDialogImpl::SheetContext*)context;
387
388 ui::SelectFileDialog::Type type = context_struct->type;
389 NSWindow* parentWindow = context_struct->owning_window;
390 delete context_struct;
391
392 bool isMulti = type == ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE;
393
394 std::vector<FilePath> paths; 367 std::vector<FilePath> paths;
395 bool did_cancel = returnCode == NSCancelButton;
396 if (!did_cancel) { 368 if (!did_cancel) {
397 if (type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) { 369 if (type == ui::SelectFileDialog::SELECT_SAVEAS_FILE) {
398 paths.push_back(FilePath(base::SysNSStringToUTF8([panel filename]))); 370 if ([[panel URL] isFileURL])
371 paths.push_back(FilePath(base::SysNSStringToUTF8([[panel URL] path])));
399 372
400 NSView* accessoryView = [panel accessoryView]; 373 NSView* accessoryView = [panel accessoryView];
401 if (accessoryView) { 374 if (accessoryView) {
402 NSPopUpButton* popup = [accessoryView viewWithTag:kFileTypePopupTag]; 375 NSPopUpButton* popup = [accessoryView viewWithTag:kFileTypePopupTag];
403 if (popup) { 376 if (popup) {
404 // File type indexes are 1-based. 377 // File type indexes are 1-based.
405 index = [popup indexOfSelectedItem] + 1; 378 index = [popup indexOfSelectedItem] + 1;
406 } 379 }
407 } else { 380 } else {
408 index = 1; 381 index = 1;
409 } 382 }
410 } else { 383 } else {
411 CHECK([panel isKindOfClass:[NSOpenPanel class]]); 384 CHECK([panel isKindOfClass:[NSOpenPanel class]]);
412 NSArray* filenames = [static_cast<NSOpenPanel*>(panel) filenames]; 385 NSArray* urls = [static_cast<NSOpenPanel*>(panel) URLs];
413 for (NSString* filename in filenames) 386 for (NSURL* url in urls)
414 paths.push_back(FilePath(base::SysNSStringToUTF8(filename))); 387 if ([url isFileURL])
388 paths.push_back(FilePath(base::SysNSStringToUTF8([url path])));
415 } 389 }
416 } 390 }
417 391
392 bool isMulti = type == ui::SelectFileDialog::SELECT_OPEN_MULTI_FILE;
418 selectFileDialogImpl_->FileWasSelected(panel, 393 selectFileDialogImpl_->FileWasSelected(panel,
419 parentWindow, 394 parentWindow,
420 did_cancel, 395 did_cancel,
421 isMulti, 396 isMulti,
422 paths, 397 paths,
423 index); 398 index);
424 [panel release]; 399 [panel release];
425 } 400 }
426 401
427 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { 402 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename {
428 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename); 403 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename);
429 } 404 }
430 405
431 @end 406 @end
432 407
433 namespace ui { 408 namespace ui {
434 409
435 SelectFileDialog* CreateMacSelectFileDialog( 410 SelectFileDialog* CreateMacSelectFileDialog(
436 SelectFileDialog::Listener* listener, 411 SelectFileDialog::Listener* listener,
437 SelectFilePolicy* policy) { 412 SelectFilePolicy* policy) {
438 return new SelectFileDialogImpl(listener, policy); 413 return new SelectFileDialogImpl(listener, policy);
439 } 414 }
440 415
441 } // namespace ui 416 } // namespace ui
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