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 "chrome/browser/ui/select_file_dialog.h" | 5 #include "chrome/browser/ui/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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
47 // NSSavePanel delegate method | 47 // NSSavePanel delegate method |
48 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename; | 48 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename; |
49 | 49 |
50 @end | 50 @end |
51 | 51 |
52 // Implementation of SelectFileDialog that shows Cocoa dialogs for choosing a | 52 // Implementation of SelectFileDialog that shows Cocoa dialogs for choosing a |
53 // file or folder. | 53 // file or folder. |
54 class SelectFileDialogImpl : public SelectFileDialog { | 54 class SelectFileDialogImpl : public SelectFileDialog { |
55 public: | 55 public: |
56 explicit SelectFileDialogImpl(Listener* listener); | 56 explicit SelectFileDialogImpl(Listener* listener); |
57 virtual ~SelectFileDialogImpl(); | |
58 | 57 |
59 // BaseShellDialog implementation. | 58 // BaseShellDialog implementation. |
60 virtual bool IsRunning(gfx::NativeWindow parent_window) const; | 59 virtual bool IsRunning(gfx::NativeWindow parent_window) const; |
61 virtual void ListenerDestroyed(); | 60 virtual void ListenerDestroyed(); |
62 | 61 |
63 // Callback from ObjC bridge. | 62 // Callback from ObjC bridge. |
64 void FileWasSelected(NSSavePanel* dialog, | 63 void FileWasSelected(NSSavePanel* dialog, |
65 NSWindow* parent_window, | 64 NSWindow* parent_window, |
66 bool was_cancelled, | 65 bool was_cancelled, |
67 bool is_multi, | 66 bool is_multi, |
(...skipping 10 matching lines...) Expand all Loading... |
78 protected: | 77 protected: |
79 // SelectFileDialog implementation. | 78 // SelectFileDialog implementation. |
80 // |params| is user data we pass back via the Listener interface. | 79 // |params| is user data we pass back via the Listener interface. |
81 virtual void SelectFileImpl(Type type, | 80 virtual void SelectFileImpl(Type type, |
82 const string16& title, | 81 const string16& title, |
83 const FilePath& default_path, | 82 const FilePath& default_path, |
84 const FileTypeInfo* file_types, | 83 const FileTypeInfo* file_types, |
85 int file_type_index, | 84 int file_type_index, |
86 const FilePath::StringType& default_extension, | 85 const FilePath::StringType& default_extension, |
87 gfx::NativeWindow owning_window, | 86 gfx::NativeWindow owning_window, |
88 void* params); | 87 void* params) OVERRIDE; |
89 | 88 |
90 private: | 89 private: |
| 90 virtual ~SelectFileDialogImpl(); |
| 91 |
91 // Gets the accessory view for the save dialog. | 92 // Gets the accessory view for the save dialog. |
92 NSView* GetAccessoryView(const FileTypeInfo* file_types, | 93 NSView* GetAccessoryView(const FileTypeInfo* file_types, |
93 int file_type_index); | 94 int file_type_index); |
94 | 95 |
95 virtual bool HasMultipleFileTypeChoicesImpl(); | 96 virtual bool HasMultipleFileTypeChoicesImpl(); |
96 | 97 |
97 // The bridge for results from Cocoa to return to us. | 98 // The bridge for results from Cocoa to return to us. |
98 scoped_nsobject<SelectFileDialogBridge> bridge_; | 99 scoped_nsobject<SelectFileDialogBridge> bridge_; |
99 | 100 |
100 // A map from file dialogs to the |params| user data associated with them. | 101 // A map from file dialogs to the |params| user data associated with them. |
(...skipping 14 matching lines...) Expand all Loading... |
115 SelectFileDialog* SelectFileDialog::Create(Listener* listener) { | 116 SelectFileDialog* SelectFileDialog::Create(Listener* listener) { |
116 return new SelectFileDialogImpl(listener); | 117 return new SelectFileDialogImpl(listener); |
117 } | 118 } |
118 | 119 |
119 SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener) | 120 SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener) |
120 : SelectFileDialog(listener), | 121 : SelectFileDialog(listener), |
121 bridge_([[SelectFileDialogBridge alloc] | 122 bridge_([[SelectFileDialogBridge alloc] |
122 initWithSelectFileDialogImpl:this]) { | 123 initWithSelectFileDialogImpl:this]) { |
123 } | 124 } |
124 | 125 |
125 SelectFileDialogImpl::~SelectFileDialogImpl() { | |
126 // Walk through the open dialogs and close them all. Use a temporary vector | |
127 // to hold the pointers, since we can't delete from the map as we're iterating | |
128 // through it. | |
129 std::vector<NSSavePanel*> panels; | |
130 for (std::map<NSSavePanel*, void*>::iterator it = params_map_.begin(); | |
131 it != params_map_.end(); ++it) { | |
132 panels.push_back(it->first); | |
133 } | |
134 | |
135 for (std::vector<NSSavePanel*>::iterator it = panels.begin(); | |
136 it != panels.end(); ++it) { | |
137 [*it cancel:*it]; | |
138 } | |
139 } | |
140 | |
141 bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const { | 126 bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const { |
142 return parents_.find(parent_window) != parents_.end(); | 127 return parents_.find(parent_window) != parents_.end(); |
143 } | 128 } |
144 | 129 |
145 void SelectFileDialogImpl::ListenerDestroyed() { | 130 void SelectFileDialogImpl::ListenerDestroyed() { |
146 listener_ = NULL; | 131 listener_ = NULL; |
147 } | 132 } |
148 | 133 |
| 134 void SelectFileDialogImpl::FileWasSelected(NSSavePanel* dialog, |
| 135 NSWindow* parent_window, |
| 136 bool was_cancelled, |
| 137 bool is_multi, |
| 138 const std::vector<FilePath>& files, |
| 139 int index) { |
| 140 void* params = params_map_[dialog]; |
| 141 params_map_.erase(dialog); |
| 142 parents_.erase(parent_window); |
| 143 type_map_.erase(dialog); |
| 144 |
| 145 [dialog setDelegate:nil]; |
| 146 |
| 147 if (!listener_) |
| 148 return; |
| 149 |
| 150 if (was_cancelled) { |
| 151 listener_->FileSelectionCanceled(params); |
| 152 } else { |
| 153 if (is_multi) { |
| 154 listener_->MultiFilesSelected(files, params); |
| 155 } else { |
| 156 listener_->FileSelected(files[0], index, params); |
| 157 } |
| 158 } |
| 159 } |
| 160 |
| 161 bool SelectFileDialogImpl::ShouldEnableFilename(NSSavePanel* dialog, |
| 162 NSString* filename) { |
| 163 // If this is a single open file dialog, disable selecting packages. |
| 164 if (type_map_[dialog] != SELECT_OPEN_FILE) |
| 165 return true; |
| 166 |
| 167 return ![[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename]; |
| 168 } |
| 169 |
149 void SelectFileDialogImpl::SelectFileImpl( | 170 void SelectFileDialogImpl::SelectFileImpl( |
150 Type type, | 171 Type type, |
151 const string16& title, | 172 const string16& title, |
152 const FilePath& default_path, | 173 const FilePath& default_path, |
153 const FileTypeInfo* file_types, | 174 const FileTypeInfo* file_types, |
154 int file_type_index, | 175 int file_type_index, |
155 const FilePath::StringType& default_extension, | 176 const FilePath::StringType& default_extension, |
156 gfx::NativeWindow owning_window, | 177 gfx::NativeWindow owning_window, |
157 void* params) { | 178 void* params) { |
158 DCHECK(type == SELECT_FOLDER || | 179 DCHECK(type == SELECT_FOLDER || |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 [open_dialog beginSheetForDirectory:default_dir | 284 [open_dialog beginSheetForDirectory:default_dir |
264 file:default_filename | 285 file:default_filename |
265 types:allowed_file_types | 286 types:allowed_file_types |
266 modalForWindow:owning_window | 287 modalForWindow:owning_window |
267 modalDelegate:bridge_.get() | 288 modalDelegate:bridge_.get() |
268 didEndSelector:@selector(endedPanel:withReturn:context:) | 289 didEndSelector:@selector(endedPanel:withReturn:context:) |
269 contextInfo:context]; | 290 contextInfo:context]; |
270 } | 291 } |
271 } | 292 } |
272 | 293 |
273 void SelectFileDialogImpl::FileWasSelected(NSSavePanel* dialog, | 294 SelectFileDialogImpl::~SelectFileDialogImpl() { |
274 NSWindow* parent_window, | 295 // Walk through the open dialogs and close them all. Use a temporary vector |
275 bool was_cancelled, | 296 // to hold the pointers, since we can't delete from the map as we're iterating |
276 bool is_multi, | 297 // through it. |
277 const std::vector<FilePath>& files, | 298 std::vector<NSSavePanel*> panels; |
278 int index) { | 299 for (std::map<NSSavePanel*, void*>::iterator it = params_map_.begin(); |
279 void* params = params_map_[dialog]; | 300 it != params_map_.end(); ++it) { |
280 params_map_.erase(dialog); | 301 panels.push_back(it->first); |
281 parents_.erase(parent_window); | 302 } |
282 type_map_.erase(dialog); | |
283 | 303 |
284 [dialog setDelegate:nil]; | 304 for (std::vector<NSSavePanel*>::iterator it = panels.begin(); |
285 | 305 it != panels.end(); ++it) { |
286 if (!listener_) | 306 [*it cancel:*it]; |
287 return; | |
288 | |
289 if (was_cancelled) { | |
290 listener_->FileSelectionCanceled(params); | |
291 } else { | |
292 if (is_multi) { | |
293 listener_->MultiFilesSelected(files, params); | |
294 } else { | |
295 listener_->FileSelected(files[0], index, params); | |
296 } | |
297 } | 307 } |
298 } | 308 } |
299 | 309 |
300 NSView* SelectFileDialogImpl::GetAccessoryView(const FileTypeInfo* file_types, | 310 NSView* SelectFileDialogImpl::GetAccessoryView(const FileTypeInfo* file_types, |
301 int file_type_index) { | 311 int file_type_index) { |
302 DCHECK(file_types); | 312 DCHECK(file_types); |
303 NSView* accessory_view = ui::GetViewFromNib(@"SaveAccessoryView"); | 313 NSView* accessory_view = ui::GetViewFromNib(@"SaveAccessoryView"); |
304 if (!accessory_view) | 314 if (!accessory_view) |
305 return nil; | 315 return nil; |
306 | 316 |
(...skipping 21 matching lines...) Expand all Loading... |
328 type_description = | 338 type_description = |
329 [NSString stringWithString:(NSString*)description.get()]; | 339 [NSString stringWithString:(NSString*)description.get()]; |
330 } | 340 } |
331 [popup addItemWithTitle:type_description]; | 341 [popup addItemWithTitle:type_description]; |
332 } | 342 } |
333 | 343 |
334 [popup selectItemAtIndex:file_type_index-1]; // 1-based | 344 [popup selectItemAtIndex:file_type_index-1]; // 1-based |
335 return accessory_view; | 345 return accessory_view; |
336 } | 346 } |
337 | 347 |
338 bool SelectFileDialogImpl::ShouldEnableFilename(NSSavePanel* dialog, | |
339 NSString* filename) { | |
340 // If this is a single open file dialog, disable selecting packages. | |
341 if (type_map_[dialog] != SELECT_OPEN_FILE) | |
342 return true; | |
343 | |
344 return ![[NSWorkspace sharedWorkspace] isFilePackageAtPath:filename]; | |
345 } | |
346 | |
347 bool SelectFileDialogImpl::HasMultipleFileTypeChoicesImpl() { | 348 bool SelectFileDialogImpl::HasMultipleFileTypeChoicesImpl() { |
348 return hasMultipleFileTypeChoices_; | 349 return hasMultipleFileTypeChoices_; |
349 } | 350 } |
350 | 351 |
351 @implementation SelectFileDialogBridge | 352 @implementation SelectFileDialogBridge |
352 | 353 |
353 - (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s { | 354 - (id)initWithSelectFileDialogImpl:(SelectFileDialogImpl*)s { |
354 self = [super init]; | 355 self = [super init]; |
355 if (self != nil) { | 356 if (self != nil) { |
356 selectFileDialogImpl_ = s; | 357 selectFileDialogImpl_ = s; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 paths, | 408 paths, |
408 index); | 409 index); |
409 [panel release]; | 410 [panel release]; |
410 } | 411 } |
411 | 412 |
412 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { | 413 - (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename { |
413 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename); | 414 return selectFileDialogImpl_->ShouldEnableFilename(sender, filename); |
414 } | 415 } |
415 | 416 |
416 @end | 417 @end |
OLD | NEW |