| 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/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/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 FilePathListToSelectedFileInfoList(entry->results_); | 238 FilePathListToSelectedFileInfoList(entry->results_); |
| 239 | 239 |
| 240 if (id == kFileSelectEnumerationId) | 240 if (id == kFileSelectEnumerationId) |
| 241 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_type_); | 241 NotifyRenderViewHost(entry->rvh_, selected_files, dialog_type_); |
| 242 else | 242 else |
| 243 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); | 243 entry->rvh_->DirectoryEnumerationFinished(id, entry->results_); |
| 244 | 244 |
| 245 EnumerateDirectoryEnd(); | 245 EnumerateDirectoryEnd(); |
| 246 } | 246 } |
| 247 | 247 |
| 248 ui::SelectFileDialog::FileTypeInfo* | 248 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> |
| 249 FileSelectHelper::GetFileTypesFromAcceptType( | 249 FileSelectHelper::GetFileTypesFromAcceptType( |
| 250 const std::vector<string16>& accept_types) { | 250 const std::vector<string16>& accept_types) { |
| 251 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> base_file_type( |
| 252 new ui::SelectFileDialog::FileTypeInfo()); |
| 253 base_file_type->support_gdata = true; |
| 251 if (accept_types.empty()) | 254 if (accept_types.empty()) |
| 252 return NULL; | 255 return base_file_type.Pass(); |
| 253 | 256 |
| 254 // Create FileTypeInfo and pre-allocate for the first extension list. | 257 // Create FileTypeInfo and pre-allocate for the first extension list. |
| 255 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( | 258 scoped_ptr<ui::SelectFileDialog::FileTypeInfo> file_type( |
| 256 new ui::SelectFileDialog::FileTypeInfo()); | 259 new ui::SelectFileDialog::FileTypeInfo(*base_file_type)); |
| 257 file_type->include_all_files = true; | 260 file_type->include_all_files = true; |
| 258 file_type->extensions.resize(1); | 261 file_type->extensions.resize(1); |
| 259 std::vector<FilePath::StringType>* extensions = &file_type->extensions.back(); | 262 std::vector<FilePath::StringType>* extensions = &file_type->extensions.back(); |
| 260 | 263 |
| 261 // Find the corresponding extensions. | 264 // Find the corresponding extensions. |
| 262 int valid_type_count = 0; | 265 int valid_type_count = 0; |
| 263 int description_id = 0; | 266 int description_id = 0; |
| 264 for (size_t i = 0; i < accept_types.size(); ++i) { | 267 for (size_t i = 0; i < accept_types.size(); ++i) { |
| 265 std::string ascii_type = UTF16ToASCII(accept_types[i]); | 268 std::string ascii_type = UTF16ToASCII(accept_types[i]); |
| 266 if (!IsAcceptTypeValid(ascii_type)) | 269 if (!IsAcceptTypeValid(ascii_type)) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 282 | 285 |
| 283 net::GetExtensionsForMimeType(ascii_type, extensions); | 286 net::GetExtensionsForMimeType(ascii_type, extensions); |
| 284 } | 287 } |
| 285 | 288 |
| 286 if (extensions->size() > old_extension_size) | 289 if (extensions->size() > old_extension_size) |
| 287 valid_type_count++; | 290 valid_type_count++; |
| 288 } | 291 } |
| 289 | 292 |
| 290 // If no valid extension is added, bail out. | 293 // If no valid extension is added, bail out. |
| 291 if (valid_type_count == 0) | 294 if (valid_type_count == 0) |
| 292 return NULL; | 295 return base_file_type.Pass(); |
| 293 | 296 |
| 294 // Use a generic description "Custom Files" if either of the following is | 297 // Use a generic description "Custom Files" if either of the following is |
| 295 // true: | 298 // true: |
| 296 // 1) There're multiple types specified, like "audio/*,video/*" | 299 // 1) There're multiple types specified, like "audio/*,video/*" |
| 297 // 2) There're multiple extensions for a MIME type without parameter, like | 300 // 2) There're multiple extensions for a MIME type without parameter, like |
| 298 // "ehtml,shtml,htm,html" for "text/html". On Windows, the select file | 301 // "ehtml,shtml,htm,html" for "text/html". On Windows, the select file |
| 299 // dialog uses the first extension in the list to form the description, | 302 // dialog uses the first extension in the list to form the description, |
| 300 // like "EHTML Files". This is not what we want. | 303 // like "EHTML Files". This is not what we want. |
| 301 if (valid_type_count > 1 || | 304 if (valid_type_count > 1 || |
| 302 (valid_type_count == 1 && description_id == 0 && extensions->size() > 1)) | 305 (valid_type_count == 1 && description_id == 0 && extensions->size() > 1)) |
| 303 description_id = IDS_CUSTOM_FILES; | 306 description_id = IDS_CUSTOM_FILES; |
| 304 | 307 |
| 305 if (description_id) { | 308 if (description_id) { |
| 306 file_type->extension_description_overrides.push_back( | 309 file_type->extension_description_overrides.push_back( |
| 307 l10n_util::GetStringUTF16(description_id)); | 310 l10n_util::GetStringUTF16(description_id)); |
| 308 } | 311 } |
| 309 | 312 |
| 310 return file_type.release(); | 313 return file_type.Pass(); |
| 311 } | 314 } |
| 312 | 315 |
| 313 // static | 316 // static |
| 314 void FileSelectHelper::RunFileChooser(content::WebContents* tab, | 317 void FileSelectHelper::RunFileChooser(content::WebContents* tab, |
| 315 const FileChooserParams& params) { | 318 const FileChooserParams& params) { |
| 316 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); | 319 Profile* profile = Profile::FromBrowserContext(tab->GetBrowserContext()); |
| 317 // FileSelectHelper will keep itself alive until it sends the result message. | 320 // FileSelectHelper will keep itself alive until it sends the result message. |
| 318 scoped_refptr<FileSelectHelper> file_select_helper( | 321 scoped_refptr<FileSelectHelper> file_select_helper( |
| 319 new FileSelectHelper(profile)); | 322 new FileSelectHelper(profile)); |
| 320 file_select_helper->RunFileChooser(tab->GetRenderViewHost(), tab, params); | 323 file_select_helper->RunFileChooser(tab->GetRenderViewHost(), tab, params); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 // Because this class returns notifications to the RenderViewHost, it is | 357 // Because this class returns notifications to the RenderViewHost, it is |
| 355 // difficult for callers to know how long to keep a reference to this | 358 // difficult for callers to know how long to keep a reference to this |
| 356 // instance. We AddRef() here to keep the instance alive after we return | 359 // instance. We AddRef() here to keep the instance alive after we return |
| 357 // to the caller, until the last callback is received from the file dialog. | 360 // to the caller, until the last callback is received from the file dialog. |
| 358 // At that point, we must call RunFileChooserEnd(). | 361 // At that point, we must call RunFileChooserEnd(). |
| 359 AddRef(); | 362 AddRef(); |
| 360 } | 363 } |
| 361 | 364 |
| 362 void FileSelectHelper::RunFileChooserOnFileThread( | 365 void FileSelectHelper::RunFileChooserOnFileThread( |
| 363 const FileChooserParams& params) { | 366 const FileChooserParams& params) { |
| 364 select_file_types_.reset( | 367 select_file_types_ = GetFileTypesFromAcceptType(params.accept_types); |
| 365 GetFileTypesFromAcceptType(params.accept_types)); | |
| 366 | 368 |
| 367 BrowserThread::PostTask( | 369 BrowserThread::PostTask( |
| 368 BrowserThread::UI, FROM_HERE, | 370 BrowserThread::UI, FROM_HERE, |
| 369 base::Bind(&FileSelectHelper::RunFileChooserOnUIThread, this, params)); | 371 base::Bind(&FileSelectHelper::RunFileChooserOnUIThread, this, params)); |
| 370 } | 372 } |
| 371 | 373 |
| 372 void FileSelectHelper::RunFileChooserOnUIThread( | 374 void FileSelectHelper::RunFileChooserOnUIThread( |
| 373 const FileChooserParams& params) { | 375 const FileChooserParams& params) { |
| 374 if (!render_view_host_ || !web_contents_) { | 376 if (!render_view_host_ || !web_contents_) { |
| 375 // If the renderer was destroyed before we started, just cancel the | 377 // If the renderer was destroyed before we started, just cancel the |
| (...skipping 29 matching lines...) Expand all Loading... |
| 405 profile_->last_selected_directory().Append(params.default_file_name); | 407 profile_->last_selected_directory().Append(params.default_file_name); |
| 406 | 408 |
| 407 gfx::NativeWindow owning_window = | 409 gfx::NativeWindow owning_window = |
| 408 platform_util::GetTopLevel(render_view_host_->GetView()->GetNativeView()); | 410 platform_util::GetTopLevel(render_view_host_->GetView()->GetNativeView()); |
| 409 | 411 |
| 410 select_file_dialog_->SelectFile( | 412 select_file_dialog_->SelectFile( |
| 411 dialog_type_, | 413 dialog_type_, |
| 412 params.title, | 414 params.title, |
| 413 default_file_name, | 415 default_file_name, |
| 414 select_file_types_.get(), | 416 select_file_types_.get(), |
| 415 select_file_types_.get() ? 1 : 0, // 1-based index. | 417 select_file_types_.get() && !select_file_types_->extensions.empty() ? |
| 418 1 : 0, // 1-based index of default extension to show. |
| 416 FILE_PATH_LITERAL(""), | 419 FILE_PATH_LITERAL(""), |
| 417 owning_window, | 420 owning_window, |
| 418 #if defined(OS_ANDROID) | 421 #if defined(OS_ANDROID) |
| 419 const_cast<content::FileChooserParams*>(¶ms)); | 422 const_cast<content::FileChooserParams*>(¶ms)); |
| 420 #else | 423 #else |
| 421 NULL); | 424 NULL); |
| 422 #endif | 425 #endif |
| 423 | 426 |
| 424 select_file_types_.reset(); | 427 select_file_types_.reset(); |
| 425 } | 428 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 // A 1 character accept type will always be invalid (either a "." in the case | 484 // A 1 character accept type will always be invalid (either a "." in the case |
| 482 // of an extension or a "/" in the case of a MIME type). | 485 // of an extension or a "/" in the case of a MIME type). |
| 483 std::string unused; | 486 std::string unused; |
| 484 if (accept_type.length() <= 1 || | 487 if (accept_type.length() <= 1 || |
| 485 StringToLowerASCII(accept_type) != accept_type || | 488 StringToLowerASCII(accept_type) != accept_type || |
| 486 TrimWhitespaceASCII(accept_type, TRIM_ALL, &unused) != TRIM_NONE) { | 489 TrimWhitespaceASCII(accept_type, TRIM_ALL, &unused) != TRIM_NONE) { |
| 487 return false; | 490 return false; |
| 488 } | 491 } |
| 489 return true; | 492 return true; |
| 490 } | 493 } |
| OLD | NEW |