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

Side by Side Diff: chrome/browser/file_select_helper.cc

Issue 6623015: Add a path for a web page to request the enumeration of a directory. This, t... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/file_select_helper.h" 5 #include "chrome/browser/file_select_helper.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/file_util.h" 9 #include "base/file_util.h"
10 #include "base/string_split.h" 10 #include "base/string_split.h"
11 #include "base/string_util.h" 11 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "net/base/mime_util.h" 13 #include "net/base/mime_util.h"
14 #include "chrome/browser/platform_util.h" 14 #include "chrome/browser/platform_util.h"
15 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/notification_details.h" 16 #include "chrome/common/notification_details.h"
17 #include "chrome/common/notification_source.h" 17 #include "chrome/common/notification_source.h"
18 #include "chrome/common/render_messages_params.h" 18 #include "chrome/common/render_messages_params.h"
19 #include "content/browser/renderer_host/render_view_host.h" 19 #include "content/browser/renderer_host/render_view_host.h"
20 #include "content/browser/renderer_host/render_widget_host_view.h" 20 #include "content/browser/renderer_host/render_widget_host_view.h"
21 #include "grit/generated_resources.h" 21 #include "grit/generated_resources.h"
22 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
23 23
24 namespace {
25
26 // There is only one file-selection happening at any given time,
27 // so we allocate an enumeration ID for that purpose. All IDs from
28 // the renderer must start at 0 and increase.
29 static const int kFileSelectEnumerationId = -1;
30
31 }
32
24 FileSelectHelper::FileSelectHelper(Profile* profile) 33 FileSelectHelper::FileSelectHelper(Profile* profile)
25 : profile_(profile), 34 : profile_(profile),
26 render_view_host_(NULL), 35 render_view_host_(NULL),
27 select_file_dialog_(), 36 select_file_dialog_(),
28 dialog_type_(SelectFileDialog::SELECT_OPEN_FILE) { 37 dialog_type_(SelectFileDialog::SELECT_OPEN_FILE) {
29 } 38 }
30 39
31 FileSelectHelper::~FileSelectHelper() { 40 FileSelectHelper::~FileSelectHelper() {
32 // There may be pending file dialogs, we need to tell them that we've gone 41 // There may be pending file dialogs, we need to tell them that we've gone
33 // away so they don't try and call back to us. 42 // away so they don't try and call back to us.
34 if (select_file_dialog_.get()) 43 if (select_file_dialog_.get())
35 select_file_dialog_->ListenerDestroyed(); 44 select_file_dialog_->ListenerDestroyed();
36 45
37 // Stop any pending directory enumeration and prevent a callback. 46 // Stop any pending directory enumeration, prevent a callback, and free
38 if (directory_lister_.get()) { 47 // allocated memory.
39 directory_lister_->set_delegate(NULL); 48 std::map<int, ActiveDirectoryEnumeration*>::iterator iter;
40 directory_lister_->Cancel(); 49 for (iter = directory_enumerations_.begin();
50 iter != directory_enumerations_.end();
51 ++iter) {
52 if (iter->second->lister_.get()) {
53 iter->second->lister_->set_delegate(NULL);
54 iter->second->lister_->Cancel();
55 }
56 delete iter->second;
41 } 57 }
42 } 58 }
43 59
44 void FileSelectHelper::FileSelected(const FilePath& path, 60 void FileSelectHelper::FileSelected(const FilePath& path,
45 int index, void* params) { 61 int index, void* params) {
46 if (!render_view_host_) 62 if (!render_view_host_)
47 return; 63 return;
48 64
49 profile_->set_last_selected_directory(path.DirName()); 65 profile_->set_last_selected_directory(path.DirName());
50 66
51 if (dialog_type_ == SelectFileDialog::SELECT_FOLDER) { 67 if (dialog_type_ == SelectFileDialog::SELECT_FOLDER) {
52 DirectorySelected(path); 68 StartNewEnumeration(path, kFileSelectEnumerationId, render_view_host_);
53 return; 69 return;
54 } 70 }
55 71
56 std::vector<FilePath> files; 72 std::vector<FilePath> files;
57 files.push_back(path); 73 files.push_back(path);
58 render_view_host_->FilesSelectedInChooser(files); 74 render_view_host_->FilesSelectedInChooser(files);
59 // We are done with this showing of the dialog. 75 // We are done with this showing of the dialog.
60 render_view_host_ = NULL; 76 render_view_host_ = NULL;
61 } 77 }
62 78
(...skipping 14 matching lines...) Expand all
77 return; 93 return;
78 94
79 // If the user cancels choosing a file to upload we pass back an 95 // If the user cancels choosing a file to upload we pass back an
80 // empty vector. 96 // empty vector.
81 render_view_host_->FilesSelectedInChooser(std::vector<FilePath>()); 97 render_view_host_->FilesSelectedInChooser(std::vector<FilePath>());
82 98
83 // We are done with this showing of the dialog. 99 // We are done with this showing of the dialog.
84 render_view_host_ = NULL; 100 render_view_host_ = NULL;
85 } 101 }
86 102
87 void FileSelectHelper::DirectorySelected(const FilePath& path) { 103 void FileSelectHelper::StartNewEnumeration(const FilePath& path,
88 directory_lister_ = new net::DirectoryLister(path, 104 int request_id,
89 true, 105 RenderViewHost* render_view_host) {
90 net::DirectoryLister::NO_SORT, 106 scoped_ptr<ActiveDirectoryEnumeration> entry(new ActiveDirectoryEnumeration);
91 this); 107 entry->rvh_ = render_view_host;
92 if (!directory_lister_->Start()) 108 entry->delegate_.reset(new DirectoryListerDispatchDelegate(this, request_id));
93 FileSelectionCanceled(NULL); 109 entry->lister_ = new net::DirectoryLister(path,
110 true,
111 net::DirectoryLister::NO_SORT,
112 entry->delegate_.get());
113 if (!entry->lister_->Start()) {
114 if (request_id == kFileSelectEnumerationId)
115 FileSelectionCanceled(NULL);
116 else
117 render_view_host->DirectoryEnumerationFinished(request_id,
118 entry->results_);
119 } else {
120 directory_enumerations_[request_id] = entry.release();
121 }
94 } 122 }
95 123
96 void FileSelectHelper::OnListFile( 124 void FileSelectHelper::OnListFile(
125 int id,
97 const net::DirectoryLister::DirectoryListerData& data) { 126 const net::DirectoryLister::DirectoryListerData& data) {
127 ActiveDirectoryEnumeration* entry = directory_enumerations_[id];
128
98 // Directory upload returns directories via a "." file, so that 129 // Directory upload returns directories via a "." file, so that
99 // empty directories are included. This util call just checks 130 // empty directories are included. This util call just checks
100 // the flags in the structure; there's no file I/O going on. 131 // the flags in the structure; there's no file I/O going on.
101 if (file_util::FileEnumerator::IsDirectory(data.info)) 132 if (file_util::FileEnumerator::IsDirectory(data.info))
102 directory_lister_results_.push_back( 133 entry->results_.push_back(data.path.Append(FILE_PATH_LITERAL(".")));
103 data.path.Append(FILE_PATH_LITERAL(".")));
104 else 134 else
105 directory_lister_results_.push_back(data.path); 135 entry->results_.push_back(data.path);
106 } 136 }
107 137
108 void FileSelectHelper::OnListDone(int error) { 138 void FileSelectHelper::OnListDone(int id, int error) {
109 if (!render_view_host_) 139 // This entry needs to be cleaned up when this function is done.
140 scoped_ptr<ActiveDirectoryEnumeration> entry(directory_enumerations_[id]);
141 directory_enumerations_.erase(id);
142 if (!entry->rvh_)
110 return; 143 return;
111
112 if (error) { 144 if (error) {
113 FileSelectionCanceled(NULL); 145 FileSelectionCanceled(NULL);
114 return; 146 return;
115 } 147 }
116 148 if (id == kFileSelectEnumerationId)
117 render_view_host_->FilesSelectedInChooser(directory_lister_results_); 149 entry->rvh_->FilesSelectedInChooser(entry->results_);
118 render_view_host_ = NULL; 150 else
119 directory_lister_ = NULL; 151 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_);
120 directory_lister_results_.clear();
121 } 152 }
122 153
123 SelectFileDialog::FileTypeInfo* FileSelectHelper::GetFileTypesFromAcceptType( 154 SelectFileDialog::FileTypeInfo* FileSelectHelper::GetFileTypesFromAcceptType(
124 const string16& accept_types) { 155 const string16& accept_types) {
125 if (accept_types.empty()) 156 if (accept_types.empty())
126 return NULL; 157 return NULL;
127 158
128 // Split the accept-type string on commas. 159 // Split the accept-type string on commas.
129 std::vector<string16> mime_types; 160 std::vector<string16> mime_types;
130 base::SplitStringUsingSubstr(accept_types, ASCIIToUTF16(","), &mime_types); 161 base::SplitStringUsingSubstr(accept_types, ASCIIToUTF16(","), &mime_types);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 select_file_dialog_->SelectFile(dialog_type_, 262 select_file_dialog_->SelectFile(dialog_type_,
232 params.title, 263 params.title,
233 default_file_name, 264 default_file_name,
234 file_types.get(), 265 file_types.get(),
235 file_types.get() ? 1 : 0, // 1-based index. 266 file_types.get() ? 1 : 0, // 1-based index.
236 FILE_PATH_LITERAL(""), 267 FILE_PATH_LITERAL(""),
237 owning_window, 268 owning_window,
238 NULL); 269 NULL);
239 } 270 }
240 271
272 void FileSelectHelper::EnumerateDirectory(int request_id,
273 RenderViewHost* render_view_host,
274 const FilePath& path) {
275 DCHECK_NE(kFileSelectEnumerationId, request_id);
276 StartNewEnumeration(path, request_id, render_view_host);
277 }
278
241 void FileSelectHelper::Observe(NotificationType type, 279 void FileSelectHelper::Observe(NotificationType type,
242 const NotificationSource& source, 280 const NotificationSource& source,
243 const NotificationDetails& details) { 281 const NotificationDetails& details) {
244 DCHECK(type == NotificationType::RENDER_WIDGET_HOST_DESTROYED); 282 DCHECK(type == NotificationType::RENDER_WIDGET_HOST_DESTROYED);
245 DCHECK(Details<RenderViewHost>(details).ptr() == render_view_host_); 283 DCHECK(Details<RenderViewHost>(details).ptr() == render_view_host_);
246 render_view_host_ = NULL; 284 render_view_host_ = NULL;
247 } 285 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698