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

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

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

Powered by Google App Engine
This is Rietveld 408576698