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

Unified Diff: chrome/browser/extensions/api/file_system/file_system_api.cc

Issue 10692105: Updates file type selector for fileSystem API (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: All code now inside file_system_api.cc Created 8 years, 5 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/extensions/api/file_system/file_system_api.cc
diff --git a/chrome/browser/extensions/api/file_system/file_system_api.cc b/chrome/browser/extensions/api/file_system/file_system_api.cc
index eb20c11c664c083d42ddf839fe2100ff43944ae2..a874c4243010597f780b023210b82671099cc6df 100644
--- a/chrome/browser/extensions/api/file_system/file_system_api.cc
+++ b/chrome/browser/extensions/api/file_system/file_system_api.cc
@@ -9,6 +9,8 @@
#include "base/file_util.h"
#include "base/logging.h"
#include "base/path_service.h"
+#include "base/string_split.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/extensions/shell_window_registry.h"
#include "chrome/browser/platform_util.h"
@@ -16,12 +18,15 @@
#include "chrome/browser/ui/extensions/shell_window.h"
#include "chrome/common/extensions/api/file_system.h"
#include "chrome/common/extensions/permissions/api_permission.h"
+#include "grit/generated_resources.h"
+#include "net/base/mime_util.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/isolated_context.h"
+#include "ui/base/l10n/l10n_util.h"
using fileapi::IsolatedContext;
@@ -131,6 +136,93 @@ bool DoCheckWritableFile(const FilePath& path) {
error == base::PLATFORM_FILE_ERROR_EXISTS;
}
+std::vector<std::string> ParseAcceptValue(const std::string& accept_types) {
+ // NOTE: Mostly stolen from ppb_file_chooser_impl.cc
+ std::vector<std::string> type_list;
+ if (accept_types.empty())
+ return type_list;
+ base::SplitString(accept_types, ',', &type_list);
+ std::vector<std::string> normalized_type_list;
+ normalized_type_list.reserve(type_list.size());
+
+ for (std::vector<std::string>::const_iterator iter = type_list.begin();
+ iter != type_list.end(); ++iter) {
+ std::string type;
+ TrimWhitespaceASCII(*iter, TRIM_ALL, &type);
+
+ if (type.empty())
+ continue;
+
+ StringToLowerASCII(&type);
+ normalized_type_list.push_back(type);
benwells 2012/07/24 06:01:27 Could this be made simpler by 1) converting accept
+ }
+
+ return normalized_type_list;
+}
+
+bool GetFileTypesFromAcceptType(const std::string& accept_type,
+ std::vector<FilePath::StringType>* extensions,
+ string16 *description) {
+ std::vector<std::string> type_list = ParseAcceptValue(accept_type);
+
+ int description_id = 0;
+ int valid_type_count = 0;
+ size_t old_extension_size = extensions->size();
+ for (std::vector<std::string>::const_iterator iter = type_list.begin();
+ iter != type_list.end(); ++iter) {
+
+ if ((*iter)[0] == '.') {
+ // Assume this is a file extension, and add it to its own place insie
benwells 2012/07/24 06:01:27 insie->inside
thorogood 2012/07/25 05:02:58 Done.
+ // the list.
+ FilePath::StringType ext(iter->begin(), iter->end());
+ extensions->push_back(ext.substr(1));
+ } else if (*iter == "image/*") {
+ description_id = IDS_IMAGE_FILES;
+ net::GetImageExtensions(extensions);
+ } else if (*iter == "audio/*") {
+ description_id = IDS_AUDIO_FILES;
+ net::GetAudioExtensions(extensions);
+ } else if (*iter == "video/*") {
+ description_id = IDS_VIDEO_FILES;
benwells 2012/07/24 06:01:27 This will overwrite description if it is already s
thorogood 2012/07/25 05:02:59 Yes. This isn't actually what we want, but the val
+ net::GetVideoExtensions(extensions);
+ } else {
+ net::GetExtensionsForMimeType(*iter, extensions);
+ }
+ // TODO(thorogood): It's possible to add the same extension multiple times.
benwells 2012/07/24 06:01:27 Are you planning on fixing this? Depending on what
thorogood 2012/07/25 05:02:59 I'm not sure. It either means modifying the net::G
+
+ if (extensions->size() > old_extension_size)
+ valid_type_count++;
+ }
+
+ if (valid_type_count == 0)
+ return false;
+
+ if (valid_type_count > 1 ||
+ (valid_type_count == 1 && description_id == 0 && extensions->size() > 1))
+ description_id = 0;
+
+ if (description_id) {
+ *description = l10n_util::GetStringUTF16(description_id);
+ } else {
+ // We don't have a description ID; generate a string like
+ // ".ext1, .ext2, .other-ext".
benwells 2012/07/24 06:01:27 Would be nicer to have "*.ext1, *.ext2..."
thorogood 2012/07/25 05:02:59 Done.
+ *description = string16();
+ for (std::vector<FilePath::StringType>::const_iterator iter
+ = extensions->begin(); iter != extensions->end(); ++iter) {
+ if (!description->empty())
+ description->append(UTF8ToUTF16(", "));
+ description->append(UTF8ToUTF16("."));
+#if defined(OS_WIN) // FilePath::StringType is already string16.
+ description->append(*iter);
+#else
+ description->append(UTF8ToUTF16(*iter));
+#endif
+ }
+ }
+
+ return true;
+}
+
} // namespace
namespace extensions {
@@ -263,6 +355,7 @@ class FileSystemChooseFileFunction::FilePicker
FilePicker(FileSystemChooseFileFunction* function,
content::WebContents* web_contents,
const FilePath& suggested_name,
+ const SelectFileDialog::FileTypeInfo& file_type_info,
SelectFileDialog::Type picker_type,
EntryType entry_type)
: suggested_name_(suggested_name),
@@ -270,14 +363,6 @@ class FileSystemChooseFileFunction::FilePicker
function_(function) {
select_file_dialog_ = SelectFileDialog::Create(
this, new ChromeSelectFilePolicy(web_contents));
- SelectFileDialog::FileTypeInfo file_type_info;
- FilePath::StringType extension = suggested_name.Extension();
- if (!extension.empty()) {
- extension.erase(extension.begin()); // drop the .
- file_type_info.extensions.resize(1);
- file_type_info.extensions[0].push_back(extension);
- }
- file_type_info.include_all_files = true;
gfx::NativeWindow owning_window = web_contents ?
platform_util::GetTopLevel(web_contents->GetNativeView()) : NULL;
@@ -333,6 +418,7 @@ class FileSystemChooseFileFunction::FilePicker
bool FileSystemChooseFileFunction::ShowPicker(
const FilePath& suggested_name,
+ const SelectFileDialog::FileTypeInfo& file_type_info,
SelectFileDialog::Type picker_type,
EntryType entry_type) {
ShellWindowRegistry* registry = ShellWindowRegistry::Get(profile());
@@ -349,7 +435,7 @@ bool FileSystemChooseFileFunction::ShowPicker(
// user has selected a file or cancelled the picker. At that point, the picker
// will delete itself, which will also free the function instance.
new FilePicker(this, shell_window->web_contents(), suggested_name,
- picker_type, entry_type);
+ file_type_info, picker_type, entry_type);
return true;
}
@@ -394,6 +480,8 @@ bool FileSystemChooseFileFunction::RunImpl() {
EXTENSION_FUNCTION_VALIDATE(params.get());
FilePath suggested_name;
+ scoped_ptr<SelectFileDialog::FileTypeInfo> file_type_info(
+ new SelectFileDialog::FileTypeInfo());
EntryType entry_type = READ_ONLY;
SelectFileDialog::Type picker_type = SelectFileDialog::SELECT_OPEN_FILE;
@@ -411,6 +499,7 @@ bool FileSystemChooseFileFunction::RunImpl() {
}
}
+ FilePath::StringType suggested_extension;
if (options->suggested_name.get()) {
suggested_name = FilePath::FromUTF8Unsafe(
*options->suggested_name.get());
@@ -422,6 +511,34 @@ bool FileSystemChooseFileFunction::RunImpl() {
if (suggested_name.IsAbsolute()) {
suggested_name = FilePath();
}
+ suggested_extension = suggested_name.Extension();
+ if (!suggested_extension.empty()) {
+ suggested_extension.erase(suggested_extension.begin()); // drop the .
+ }
+ }
+
+ if (options->accepts.get()) {
+ std::vector<std::string>* raw = options->accepts.get();
+ for (std::vector<std::string>::const_iterator iter = raw->begin();
+ iter != raw->end(); ++iter) {
+ string16 description;
+ std::vector<FilePath::StringType> extensions;
+ if (GetFileTypesFromAcceptType(*iter, &extensions, &description)) {
+ file_type_info->extensions.push_back(extensions);
+ file_type_info->extension_description_overrides.push_back(description);
+ }
+ // TODO(thorogood): If suggested_extension is non-empty, ensure that
+ // at least once of our extensions list includes it.
+ }
+ }
+
+ if (options->accepts_all_types.get() &&
+ !file_type_info->extensions.empty()) {
+ file_type_info->include_all_files = *options->accepts_all_types.get();
+ } else {
+ // There's nothing in our accepted extension list; default to accepting
+ // all types.
+ file_type_info->include_all_files = true;
}
}
@@ -430,7 +547,7 @@ bool FileSystemChooseFileFunction::RunImpl() {
return false;
}
- return ShowPicker(suggested_name, picker_type, entry_type);
+ return ShowPicker(suggested_name, *file_type_info, picker_type, entry_type);
}
} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698