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

Side by Side Diff: chrome/browser/cocoa/shell_dialogs_mac.mm

Issue 459008: Mac: the return of the tab-modal-sheets patch. (Closed)
Patch Set: Merged ToT. Must ... commit ... soon. Created 11 years 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
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2009 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/shell_dialogs.h" 5 #include "chrome/browser/shell_dialogs.h"
6 6
7 #include <CoreServices/CoreServices.h> 7 #include <CoreServices/CoreServices.h>
8 #import <Cocoa/Cocoa.h> 8 #import <Cocoa/Cocoa.h>
9 #include <map> 9 #include <map>
10 #include <set> 10 #include <set>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/mac_util.h" 13 #include "base/mac_util.h"
14 #include "base/scoped_cftyperef.h" 14 #include "base/scoped_cftyperef.h"
15 #import "base/scoped_nsobject.h" 15 #import "base/scoped_nsobject.h"
16 #include "base/sys_string_conversions.h" 16 #include "base/sys_string_conversions.h"
17 #include "chrome/browser/cocoa/constrained_window_mac.h"
18 #include "chrome/browser/tab_contents/tab_contents.h"
17 19
18 static const int kFileTypePopupTag = 1234; 20 static const int kFileTypePopupTag = 1234;
19 21
20 class SelectFileDialogImpl; 22 class SelectFileDialogImpl;
21 23
22 // A bridge class to act as the modal delegate to the save/open sheet and send 24 // A bridge class to act as the modal delegate to the save/open sheet and send
23 // the results to the C++ class. 25 // the results to the C++ class.
24 @interface SelectFileDialogBridge : NSObject { 26 @interface SelectFileDialogBridge : NSObject {
25 @private 27 @private
26 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us 28 SelectFileDialogImpl* selectFileDialogImpl_; // WEAK; owns us
(...skipping 10 matching lines...) Expand all
37 // file or folder. 39 // file or folder.
38 class SelectFileDialogImpl : public SelectFileDialog { 40 class SelectFileDialogImpl : public SelectFileDialog {
39 public: 41 public:
40 explicit SelectFileDialogImpl(Listener* listener); 42 explicit SelectFileDialogImpl(Listener* listener);
41 virtual ~SelectFileDialogImpl(); 43 virtual ~SelectFileDialogImpl();
42 44
43 // BaseShellDialog implementation. 45 // BaseShellDialog implementation.
44 virtual bool IsRunning(gfx::NativeWindow parent_window) const; 46 virtual bool IsRunning(gfx::NativeWindow parent_window) const;
45 virtual void ListenerDestroyed(); 47 virtual void ListenerDestroyed();
46 48
49 // BaseShellDialog override.
50 virtual bool IsRunningInTab(const TabContents* parent_tab) const;
51
47 // SelectFileDialog implementation. 52 // SelectFileDialog implementation.
48 // |params| is user data we pass back via the Listener interface. 53 // |params| is user data we pass back via the Listener interface.
49 virtual void SelectFile(Type type, 54 virtual void SelectFile(Type type,
50 const string16& title, 55 const string16& title,
51 const FilePath& default_path, 56 const FilePath& default_path,
52 const FileTypeInfo* file_types, 57 const FileTypeInfo* file_types,
53 int file_type_index, 58 int file_type_index,
54 const FilePath::StringType& default_extension, 59 const FilePath::StringType& default_extension,
55 gfx::NativeWindow owning_window, 60 gfx::NativeWindow owning_window,
56 void* params); 61 void* params);
57 62
58 // Callback from ObjC bridge. 63 // SelectFileDialog override.
64 // |params| is user data we pass back via the Listener interface.
65 virtual void SelectFileInTab(Type type,
66 const string16& title,
67 const FilePath& default_path,
68 const FileTypeInfo* file_types,
69 int file_type_index,
70 const FilePath::StringType& default_extension,
71 TabContents* owning_tab,
72 void* params);
73
74 // Callbacks from ObjC bridge.
59 void FileWasSelected(NSPanel* dialog, 75 void FileWasSelected(NSPanel* dialog,
60 NSWindow* parent_window, 76 NSWindow* parent_window,
61 bool was_cancelled, 77 bool was_cancelled,
62 bool is_multi, 78 bool is_multi,
63 const std::vector<FilePath>& files, 79 const std::vector<FilePath>& files,
64 int index); 80 int index);
81 void FileWasSelectedInTab(NSPanel* dialog,
82 TabContents* parent_tab,
83 bool was_cancelled,
84 bool was_killed,
85 bool is_multi,
86 const std::vector<FilePath>& files,
87 int index);
65 88
66 struct SheetContext { 89 struct SheetContext {
67 Type type; 90 Type type;
68 NSWindow* owning_window; 91 NSWindow* owning_window; // Only one of |owning_...| should be non-NULL.
92 TabContents* owning_tab;
69 }; 93 };
70 94
71 private: 95 private:
96 void NotifyListenerOfFileSelection(bool was_cancelled,
97 bool is_multi,
98 const std::vector<FilePath>& files,
99 int index,
100 void* params);
101
72 // Gets the accessory view for the save dialog. 102 // Gets the accessory view for the save dialog.
73 NSView* GetAccessoryView(const FileTypeInfo* file_types, 103 NSView* GetAccessoryView(const FileTypeInfo* file_types,
74 int file_type_index); 104 int file_type_index);
75 105
76 // The listener to be notified of selection completion. 106 // The listener to be notified of selection completion.
77 Listener* listener_; 107 Listener* listener_;
78 108
79 // The bridge for results from Cocoa to return to us. 109 // The bridge for results from Cocoa to return to us.
80 scoped_nsobject<SelectFileDialogBridge> bridge_; 110 scoped_nsobject<SelectFileDialogBridge> bridge_;
81 111
82 // A map from file dialogs to the |params| user data associated with them. 112 // A map from file dialogs to the |params| user data associated with them.
83 std::map<NSPanel*, void*> params_map_; 113 std::map<NSPanel*, void*> params_map_;
84 114
115 // A map from dialogs to constrained windows.
116 std::map<NSPanel*, ConstrainedWindow*> window_map_;
117
85 // The set of all parent windows for which we are currently running dialogs. 118 // The set of all parent windows for which we are currently running dialogs.
86 std::set<NSWindow*> parents_; 119 std::set<NSWindow*> parent_windows_;
120
121 // The set of all parent tabs for which we are currently running sheets.
122 std::set<const TabContents*> parent_tabs_;
87 123
88 DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); 124 DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl);
89 }; 125 };
90 126
127 // Class to create a select file sheet as a "constrained window" (i.e., sheet
128 // attached to a tab).
129 class SelectFileInTabDelegate
130 : public ConstrainedWindowMacDelegateSystemSheetParams {
131 public:
132 SelectFileInTabDelegate()
133 : ConstrainedWindowMacDelegateSystemSheetParams(nil) { }
134
135 void InitForSavePanel(NSSavePanel* sheet,
136 SelectFileDialogImpl* s,
137 NSString* directory,
138 NSString* file,
139 void* context) {
140 set_sheet(sheet);
141 // Note: we need NSValue's to guard against |directory|, etc. being nil.
142 NSArray* params = [NSArray arrayWithObjects:
143 [NSValue valueWithPointer:directory],
144 [NSValue valueWithPointer:file],
145 [NSNull null], // window, must be [NSNull null]
146 [[[SelectFileDialogBridge alloc]
147 initWithSelectFileDialogImpl:s] autorelease],
148 [NSValue valueWithPointer:@selector(endedPanel:withReturn:context:)],
149 [NSValue valueWithPointer:context],
150 nil];
151 set_params(params);
152 }
153
154 void InitForOpenPanel(NSOpenPanel* sheet,
155 SelectFileDialogImpl* s,
156 NSString* directory,
157 NSString* file,
158 NSArray* file_types,
159 void* context) {
160 set_sheet(sheet);
161 // Note: we need NSValue's to guard against |directory|, etc. being nil.
162 NSArray* params = [NSArray arrayWithObjects:
163 [NSValue valueWithPointer:directory],
164 [NSValue valueWithPointer:file],
165 [NSValue valueWithPointer:file_types],
166 [NSNull null], // window, must be [NSNull null]
167 [[[SelectFileDialogBridge alloc]
168 initWithSelectFileDialogImpl:s] autorelease],
169 [NSValue valueWithPointer:@selector(endedPanel:withReturn:context:)],
170 [NSValue valueWithPointer:context],
171 nil];
172 set_params(params);
173 }
174
175 // Implementation of method defined in ConstrainedWindowMacDelegate:
176 virtual void DeleteDelegate() {
177 if (is_sheet_open()) {
178 // Close sheet if it's still open; inform the end-sheet routine that it's
179 // being closed by the delegate, so it can avoid calling
180 // |CloseConstrainedWindow()| (which leads to an attempt to delete us
181 // again).
182 [NSApp endSheet:(NSSavePanel*)sheet()
183 returnCode:kClosedByDelegate];
184 }
185 delete this;
186 }
187
188 // Overridden from ConstrainedWindowMacDelegate:
189 virtual bool ParentWillDo(ConstrainedWindow::Event event) {
190 switch(event) {
191 case ConstrainedWindow::kEventNavigate:
192 // We don't want to close! (Note: typically, we *shouldn't* be
193 // navigating during file selection. However, this happens for open file
194 // dialogs run on very new tabs.
195 //TODO(viettrungluu): if we allow navigations, then we should close.
196 return true;
197
198 default:
199 break;
200 }
201 return false;
202 }
203
204 // Return value passed to the end-sheet routine to indicate that the sheet was
205 // ended by |DeleteDelegate()|. This just needs to be some value never used by
206 // Apple as a return value for the sheet.
207 static const int kClosedByDelegate = 658042027;
208 };
209
91 // static 210 // static
92 SelectFileDialog* SelectFileDialog::Create(Listener* listener) { 211 SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
93 return new SelectFileDialogImpl(listener); 212 return new SelectFileDialogImpl(listener);
94 } 213 }
95 214
96 SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener) 215 SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener)
97 : listener_(listener), 216 : listener_(listener),
98 bridge_([[SelectFileDialogBridge alloc] 217 bridge_([[SelectFileDialogBridge alloc]
99 initWithSelectFileDialogImpl:this]) { 218 initWithSelectFileDialogImpl:this]) {
100 } 219 }
101 220
102 SelectFileDialogImpl::~SelectFileDialogImpl() { 221 SelectFileDialogImpl::~SelectFileDialogImpl() {
103 } 222 }
104 223
105 bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const { 224 bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const {
106 return parents_.find(parent_window) != parents_.end(); 225 return (parent_windows_.find(parent_window) != parent_windows_.end());
226 }
227
228 bool SelectFileDialogImpl::IsRunningInTab(const TabContents* parent_tab) const {
229 return (parent_tabs_.find(parent_tab) != parent_tabs_.end());
107 } 230 }
108 231
109 void SelectFileDialogImpl::ListenerDestroyed() { 232 void SelectFileDialogImpl::ListenerDestroyed() {
110 listener_ = NULL; 233 listener_ = NULL;
111 } 234 }
112 235
113 void SelectFileDialogImpl::SelectFile( 236 void SelectFileDialogImpl::SelectFile(
114 Type type, 237 Type type,
115 const string16& title, 238 const string16& title,
116 const FilePath& default_path, 239 const FilePath& default_path,
117 const FileTypeInfo* file_types, 240 const FileTypeInfo* file_types,
118 int file_type_index, 241 int file_type_index,
119 const FilePath::StringType& default_extension, 242 const FilePath::StringType& default_extension,
120 gfx::NativeWindow owning_window, 243 gfx::NativeWindow owning_window,
121 void* params) { 244 void* params) {
122 DCHECK(type == SELECT_FOLDER || 245 DCHECK(type == SELECT_FOLDER ||
123 type == SELECT_OPEN_FILE || 246 type == SELECT_OPEN_FILE ||
124 type == SELECT_OPEN_MULTI_FILE || 247 type == SELECT_OPEN_MULTI_FILE ||
125 type == SELECT_SAVEAS_FILE); 248 type == SELECT_SAVEAS_FILE);
126 parents_.insert(owning_window); 249
250 parent_windows_.insert(owning_window);
127 251
128 // Note: we need to retain the dialog as owning_window can be null. 252 // Note: we need to retain the dialog as owning_window can be null.
129 // (see http://crbug.com/29213) 253 // (see http://crbug.com/29213)
130 NSSavePanel* dialog; 254 NSSavePanel* dialog;
131 if (type == SELECT_SAVEAS_FILE) 255 if (type == SELECT_SAVEAS_FILE)
132 dialog = [[NSSavePanel savePanel] retain]; 256 dialog = [[NSSavePanel savePanel] retain];
133 else 257 else
134 dialog = [[NSOpenPanel openPanel] retain]; 258 dialog = [[NSOpenPanel openPanel] retain];
135 259
136 if (!title.empty()) 260 if (!title.empty())
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 } 296 }
173 297
174 if (!default_extension.empty()) 298 if (!default_extension.empty())
175 [dialog setRequiredFileType:base::SysUTF8ToNSString(default_extension)]; 299 [dialog setRequiredFileType:base::SysUTF8ToNSString(default_extension)];
176 300
177 params_map_[dialog] = params; 301 params_map_[dialog] = params;
178 302
179 SheetContext* context = new SheetContext; 303 SheetContext* context = new SheetContext;
180 context->type = type; 304 context->type = type;
181 context->owning_window = owning_window; 305 context->owning_window = owning_window;
306 context->owning_tab = NULL;
182 307
183 if (type == SELECT_SAVEAS_FILE) { 308 if (type == SELECT_SAVEAS_FILE) {
184 [dialog beginSheetForDirectory:default_dir 309 [dialog beginSheetForDirectory:default_dir
185 file:default_filename 310 file:default_filename
186 modalForWindow:owning_window 311 modalForWindow:owning_window
187 modalDelegate:bridge_.get() 312 modalDelegate:bridge_.get()
188 didEndSelector:@selector(endedPanel:withReturn:context:) 313 didEndSelector:@selector(endedPanel:withReturn:context:)
189 contextInfo:context]; 314 contextInfo:context];
190 } else { 315 } else {
191 NSOpenPanel* open_dialog = (NSOpenPanel*)dialog; 316 NSOpenPanel* open_dialog = (NSOpenPanel*)dialog;
192 317
193 if (type == SELECT_OPEN_MULTI_FILE) 318 if (type == SELECT_OPEN_MULTI_FILE)
194 [open_dialog setAllowsMultipleSelection:YES]; 319 [open_dialog setAllowsMultipleSelection:YES];
195 else 320 else
196 [open_dialog setAllowsMultipleSelection:NO]; 321 [open_dialog setAllowsMultipleSelection:NO];
197 322
198 if (type == SELECT_FOLDER) { 323 if (type == SELECT_FOLDER) {
199 [open_dialog setCanChooseFiles:NO]; 324 [open_dialog setCanChooseFiles:NO];
200 [open_dialog setCanChooseDirectories:YES]; 325 [open_dialog setCanChooseDirectories:YES];
201 } else { 326 } else {
202 [open_dialog setCanChooseFiles:YES]; 327 [open_dialog setCanChooseFiles:YES];
203 [open_dialog setCanChooseDirectories:NO]; 328 [open_dialog setCanChooseDirectories:NO];
204 } 329 }
205 330
206 [open_dialog beginSheetForDirectory:default_dir 331 [open_dialog beginSheetForDirectory:default_dir
207 file:default_filename 332 file:default_filename
208 types:allowed_file_types 333 types:allowed_file_types
209 modalForWindow:owning_window 334 modalForWindow:owning_window
210 modalDelegate:bridge_.get() 335 modalDelegate:bridge_.get()
211 didEndSelector:@selector(endedPanel:withReturn:context:) 336 didEndSelector:@selector(
337 endedPanel:withReturn:context:)
212 contextInfo:context]; 338 contextInfo:context];
213 } 339 }
214 } 340 }
215 341
216 void SelectFileDialogImpl::FileWasSelected(NSPanel* dialog, 342 void SelectFileDialogImpl::SelectFileInTab(
217 NSWindow* parent_window, 343 Type type,
218 bool was_cancelled, 344 const string16& title,
219 bool is_multi, 345 const FilePath& default_path,
220 const std::vector<FilePath>& files, 346 const FileTypeInfo* file_types,
221 int index) { 347 int file_type_index,
348 const FilePath::StringType& default_extension,
349 TabContents* owning_tab,
350 void* params) {
351 // Go modeless if no |owning_tab|.
352 // TODO(viettrungluu): Despite the docs in shell_dialogs.h, we don't support
353 // this (see the TODO in SelectFile()).
354 if (!owning_tab) {
355 SelectFile(type, title, default_path, file_types, file_type_index,
356 default_extension, NULL, params);
357 return;
358 }
359
360 // This shouldn't be needed, but prevents crashing if someone calls us when
361 // there's already a constrained dialog.
362 if (!owning_tab->CanCreateConstrainedDialog()) {
363 // TODO(viettrungluu): This should be a NOTREACHED(), but it's annoying to
364 // have my browser constantly die.
365 LOG(WARNING) << "Not allowed to create constrained dialog.";
366
367 // Make sure the listener doesn't hang.
368 if (listener_)
369 listener_->FileSelectionCanceled(params);
370 return;
371 }
372
373 DCHECK(type == SELECT_FOLDER ||
374 type == SELECT_OPEN_FILE ||
375 type == SELECT_OPEN_MULTI_FILE ||
376 type == SELECT_SAVEAS_FILE);
377 parent_tabs_.insert(owning_tab);
378
379 NSSavePanel* dialog = (type == SELECT_SAVEAS_FILE) ? [NSSavePanel savePanel] :
380 [NSOpenPanel openPanel];
381
382 if (!title.empty())
383 [dialog setTitle:base::SysUTF16ToNSString(title)];
384
385 NSString* default_dir = nil;
386 NSString* default_filename = nil;
387 if (!default_path.empty()) {
388 default_dir = base::SysUTF8ToNSString(default_path.DirName().value());
389 default_filename = base::SysUTF8ToNSString(default_path.BaseName().value());
390 }
391
392 NSMutableArray* allowed_file_types = nil;
393 if (file_types) {
394 if (!file_types->extensions.empty()) {
395 allowed_file_types = [NSMutableArray array];
396 for (size_t i=0; i < file_types->extensions.size(); ++i) {
397 const std::vector<FilePath::StringType>& ext_list =
398 file_types->extensions[i];
399 for (size_t j=0; j < ext_list.size(); ++j) {
400 [allowed_file_types addObject:base::SysUTF8ToNSString(ext_list[j])];
401 }
402 }
403 }
404 if (type == SELECT_SAVEAS_FILE)
405 [dialog setAllowedFileTypes:allowed_file_types];
406 // else we'll pass it in when we run the open panel
407
408 if (file_types->include_all_files)
409 [dialog setAllowsOtherFileTypes:YES];
410
411 if (!file_types->extension_description_overrides.empty()) {
412 NSView* accessory_view = GetAccessoryView(file_types, file_type_index);
413 [dialog setAccessoryView:accessory_view];
414 }
415 } else {
416 // If no type info is specified, anything goes.
417 [dialog setAllowsOtherFileTypes:YES];
418 }
419
420 if (!default_extension.empty())
421 [dialog setRequiredFileType:base::SysUTF8ToNSString(default_extension)];
422
423 params_map_[dialog] = params;
424
425 SheetContext* context = new SheetContext;
426 context->type = type;
427 context->owning_window = NULL;
428 context->owning_tab = owning_tab;
429
430 // It will delete itself when its |DeleteDelegate()| method is called.
431 SelectFileInTabDelegate* delegate = new SelectFileInTabDelegate;
432 DCHECK(delegate);
433
434 if (type == SELECT_SAVEAS_FILE) {
435 delegate->InitForSavePanel(dialog,
436 this,
437 default_dir,
438 default_filename,
439 context);
440 } else {
441 NSOpenPanel* open_dialog = (NSOpenPanel*)dialog;
442
443 if (type == SELECT_OPEN_MULTI_FILE)
444 [open_dialog setAllowsMultipleSelection:YES];
445 else
446 [open_dialog setAllowsMultipleSelection:NO];
447
448 if (type == SELECT_FOLDER) {
449 [open_dialog setCanChooseFiles:NO];
450 [open_dialog setCanChooseDirectories:YES];
451 } else {
452 [open_dialog setCanChooseFiles:YES];
453 [open_dialog setCanChooseDirectories:NO];
454 }
455
456 delegate->InitForOpenPanel(open_dialog,
457 this,
458 default_dir,
459 default_filename,
460 allowed_file_types,
461 context);
462 }
463
464 window_map_[dialog] = owning_tab->CreateConstrainedDialog(delegate);
465 }
466
467 void SelectFileDialogImpl::FileWasSelected(
468 NSPanel* dialog,
469 NSWindow* parent_window,
470 bool was_cancelled,
471 bool is_multi,
472 const std::vector<FilePath>& files,
473 int index) {
222 void* params = params_map_[dialog]; 474 void* params = params_map_[dialog];
223 params_map_.erase(dialog); 475 params_map_.erase(dialog);
224 parents_.erase(parent_window); 476 parent_windows_.erase(parent_window);
225 477
478 NotifyListenerOfFileSelection(was_cancelled, is_multi, files, index, params);
479 }
480
481 // The |was_killed| parameter indicates whether or not we need to call
482 // |CloseConstrainedWindow()|. If the dialog was ended by
483 // |CloseConstrainedWindow()|, the delegate then closes the sheet (leading to
484 // this method being called) and deletes itself.
485 void SelectFileDialogImpl::FileWasSelectedInTab(
486 NSPanel* dialog,
487 TabContents* parent_tab,
488 bool was_cancelled,
489 bool was_killed,
490 bool is_multi,
491 const std::vector<FilePath>& files,
492 int index) {
493 void* params = params_map_[dialog];
494 params_map_.erase(dialog);
495 if (!was_killed) {
496 ConstrainedWindow* window = window_map_[dialog];
497 window->CloseConstrainedWindow();
498 }
499 window_map_.erase(dialog);
500 parent_tabs_.erase(parent_tab);
501
502 NotifyListenerOfFileSelection(was_cancelled, is_multi, files, index, params);
503 }
504
505 void SelectFileDialogImpl::NotifyListenerOfFileSelection(
506 bool was_cancelled,
507 bool is_multi,
508 const std::vector<FilePath>& files,
509 int index,
510 void* params) {
226 if (!listener_) 511 if (!listener_)
227 return; 512 return;
228 513
229 if (was_cancelled) { 514 if (was_cancelled) {
230 listener_->FileSelectionCanceled(params); 515 listener_->FileSelectionCanceled(params);
231 } else { 516 } else {
232 if (is_multi) { 517 if (is_multi) {
233 listener_->MultiFilesSelected(files, params); 518 listener_->MultiFilesSelected(files, params);
234 } else { 519 } else {
235 listener_->FileSelected(files[0], index, params); 520 listener_->FileSelected(files[0], index, params);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 590
306 - (void)endedPanel:(id)panel 591 - (void)endedPanel:(id)panel
307 withReturn:(int)returnCode 592 withReturn:(int)returnCode
308 context:(void *)context { 593 context:(void *)context {
309 int index = 0; 594 int index = 0;
310 SelectFileDialogImpl::SheetContext* context_struct = 595 SelectFileDialogImpl::SheetContext* context_struct =
311 (SelectFileDialogImpl::SheetContext*)context; 596 (SelectFileDialogImpl::SheetContext*)context;
312 597
313 SelectFileDialog::Type type = context_struct->type; 598 SelectFileDialog::Type type = context_struct->type;
314 NSWindow* parentWindow = context_struct->owning_window; 599 NSWindow* parentWindow = context_struct->owning_window;
600 TabContents* parentTab = context_struct->owning_tab;
601 DCHECK(!(parentWindow && parentTab));
315 delete context_struct; 602 delete context_struct;
316 603
317 bool isMulti = type == SelectFileDialog::SELECT_OPEN_MULTI_FILE; 604 bool isMulti = type == SelectFileDialog::SELECT_OPEN_MULTI_FILE;
318 605
319 std::vector<FilePath> paths; 606 std::vector<FilePath> paths;
320 bool did_cancel = returnCode == NSCancelButton; 607 // The negative check for cancellation covers the NSRun...Response codes.
608 bool did_cancel = (returnCode != NSOKButton);
321 if (!did_cancel) { 609 if (!did_cancel) {
322 if (type == SelectFileDialog::SELECT_SAVEAS_FILE) { 610 if (type == SelectFileDialog::SELECT_SAVEAS_FILE) {
323 paths.push_back(FilePath(base::SysNSStringToUTF8([panel filename]))); 611 paths.push_back(FilePath(base::SysNSStringToUTF8([panel filename])));
324 612
325 NSView* accessoryView = [panel accessoryView]; 613 NSView* accessoryView = [panel accessoryView];
326 if (accessoryView) { 614 if (accessoryView) {
327 NSPopUpButton* popup = [accessoryView viewWithTag:kFileTypePopupTag]; 615 NSPopUpButton* popup = [accessoryView viewWithTag:kFileTypePopupTag];
328 if (popup) { 616 if (popup) {
329 // File type indexes are 1-based. 617 // File type indexes are 1-based.
330 index = [popup indexOfSelectedItem] + 1; 618 index = [popup indexOfSelectedItem] + 1;
331 } 619 }
332 } else { 620 } else {
333 index = 1; 621 index = 1;
334 } 622 }
335 } else { 623 } else {
336 NSArray* filenames = [panel filenames]; 624 NSArray* filenames = [panel filenames];
337 for (NSString* filename in filenames) 625 for (NSString* filename in filenames)
338 paths.push_back(FilePath(base::SysNSStringToUTF8(filename))); 626 paths.push_back(FilePath(base::SysNSStringToUTF8(filename)));
339 } 627 }
340 } 628 }
341 629
342 selectFileDialogImpl_->FileWasSelected(panel, 630 // Note that |parentWindow| may be null, so we use |parentTab| to check which
343 parentWindow, 631 // situation we're in.
344 did_cancel, 632 if (!parentTab) {
345 isMulti, 633 selectFileDialogImpl_->FileWasSelected(panel,
346 paths, 634 parentWindow,
347 index); 635 did_cancel,
348 [panel release]; 636 isMulti,
637 paths,
638 index);
639 [panel release];
640 } else {
641 bool was_killed =
642 (returnCode == SelectFileInTabDelegate::kClosedByDelegate);
643 selectFileDialogImpl_->FileWasSelectedInTab(panel,
644 parentTab,
645 did_cancel,
646 was_killed,
647 isMulti,
648 paths,
649 index);
650 }
349 } 651 }
350 652
351 @end 653 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/constrained_window_mac.mm ('k') | chrome/browser/cocoa/tab_strip_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698