summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-12 20:03:08 +0000
committeravi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-12 20:03:08 +0000
commitb949f1110dea9e220706cbe72ede4118d78308f0 (patch)
tree16627db33014921df4287548a54caac852dd76eb /chrome
parent3e1302168c2b16d744486172b55dc48114baac7e (diff)
downloadchromium_src-b949f1110dea9e220706cbe72ede4118d78308f0.zip
chromium_src-b949f1110dea9e220706cbe72ede4118d78308f0.tar.gz
chromium_src-b949f1110dea9e220706cbe72ede4118d78308f0.tar.bz2
Refactoring; switch the |filter| parameter into something that is more amenable to cross-platform implementation.
BUG=9852 Review URL: http://codereview.chromium.org/63093 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13573 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/generated_resources.grd7
-rw-r--r--chrome/browser/browser.cc2
-rw-r--r--chrome/browser/download/download_manager.cc12
-rw-r--r--chrome/browser/download/save_package.cc34
-rw-r--r--chrome/browser/gtk/dialogs_gtk.cc29
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc9
-rw-r--r--chrome/browser/renderer_host/render_view_host.h5
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h5
-rw-r--r--chrome/browser/shell_dialogs.h49
-rw-r--r--chrome/browser/tab_contents/web_contents.cc5
-rw-r--r--chrome/browser/tab_contents/web_contents.h3
-rw-r--r--chrome/browser/views/bookmark_manager_view.cc21
-rw-r--r--chrome/browser/views/options/content_page_view.cc2
-rw-r--r--chrome/browser/views/shell_dialogs_win.cc77
-rw-r--r--chrome/browser/views/user_data_dir_dialog.cc2
-rw-r--r--chrome/common/render_messages_internal.h7
-rw-r--r--chrome/common/temp_scaffolding_stubs.h7
-rw-r--r--chrome/common/win_util.cc130
-rw-r--r--chrome/common/win_util.h25
-rw-r--r--chrome/renderer/render_view.cc7
-rw-r--r--chrome/renderer/render_view.h5
21 files changed, 227 insertions, 216 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index c28c691..33cbe02 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3288,8 +3288,11 @@ each locale. -->
</message>
<!-- Saving Page-->
- <message name="IDS_SAVE_PAGE_FILTER" desc="Filter string for save page. \0's are required separators and additional two \0's should be appended when using this.">
- Web Page, HTML Only\0*.htm\0Web Page, Complete\0*.htm
+ <message name="IDS_SAVE_PAGE_DESC_HTML_ONLY" desc="In the Save Page dialog, the description of saving only the HTML of a web page.">
+ Web Page, HTML Only
+ </message>
+ <message name="IDS_SAVE_PAGE_DESC_COMPLETE" desc="In the Save Page dialog, the description of saving both the HTML and all shown resources.">
+ Web Page, Complete
</message>
<message name="IDS_SAVE_PAGE_STATUS_COMPLETED" desc="Save page status: completed">
Completed
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 5c5c581..1963361 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -993,7 +993,7 @@ void Browser::OpenFile() {
gfx::NativeWindow parent_window = window_->GetNativeHandle();
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
string16(), FilePath(),
- std::wstring(), 0, FILE_PATH_LITERAL(""),
+ NULL, 0, FILE_PATH_LITERAL(""),
parent_window, NULL);
}
#endif
diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc
index 3b68cfa..43954a7 100644
--- a/chrome/browser/download/download_manager.cc
+++ b/chrome/browser/download/download_manager.cc
@@ -640,18 +640,16 @@ void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
WebContents* contents = tab_util::GetWebContentsByID(
info->render_process_id, info->render_view_id);
-#if defined(OS_WIN)
- std::wstring filter =
- win_util::GetFileFilterFromPath(info->suggested_path.value());
-#elif defined(OS_LINUX)
- std::wstring filter;
-#endif
+ SelectFileDialog::FileTypeInfo file_type_info;
+ file_type_info.extensions.resize(1);
+ file_type_info.extensions[0].push_back(info->suggested_path.Extension());
+ file_type_info.include_all_files = true;
gfx::NativeWindow owning_window =
contents ? platform_util::GetTopLevel(contents->GetNativeView()) : NULL;
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
string16(),
info->suggested_path,
- filter, 0, FILE_PATH_LITERAL(""),
+ &file_type_info, 0, FILE_PATH_LITERAL(""),
owning_window, info);
} else {
// No prompting for download, just continue with the suggested name.
diff --git a/chrome/browser/download/save_package.cc b/chrome/browser/download/save_package.cc
index 23bb704..01a1b26 100644
--- a/chrome/browser/download/save_package.cc
+++ b/chrome/browser/download/save_package.cc
@@ -995,8 +995,8 @@ FilePath SavePackage::GetSuggestNameForSaveAs(PrefService* prefs,
void SavePackage::GetSaveInfo() {
// Use "Web Page, Complete" option as default choice of saving page.
- int filter_index = 2;
- std::wstring filter;
+ int file_type_index = 2;
+ SelectFileDialog::FileTypeInfo file_type_info;
FilePath::StringType default_extension;
FilePath title =
FilePath::FromWStringHack(UTF16ToWideHack(web_contents_->GetTitle()));
@@ -1009,22 +1009,22 @@ void SavePackage::GetSaveInfo() {
// If the contents can not be saved as complete-HTML, do not show the
// file filters.
if (CanSaveAsComplete(save_params->current_tab_mime_type)) {
- filter = l10n_util::GetString(IDS_SAVE_PAGE_FILTER);
- filter.resize(filter.size() + 2);
- filter[filter.size() - 1] = L'\0';
- filter[filter.size() - 2] = L'\0';
+ file_type_info.extensions.resize(2);
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm"));
+ file_type_info.extension_description_overrides.push_back(
+ WideToUTF16(l10n_util::GetString(IDS_SAVE_PAGE_DESC_HTML_ONLY)));
+ file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("htm"));
+ file_type_info.extension_description_overrides.push_back(
+ WideToUTF16(l10n_util::GetString(IDS_SAVE_PAGE_DESC_COMPLETE)));
+ file_type_info.include_all_files = false;
default_extension = FILE_PATH_LITERAL("htm");
} else {
-#if defined(OS_WIN)
- filter = win_util::GetFileFilterFromPath(suggested_path.ToWStringHack());
-#else
- // TODO(port): implement this.
- NOTIMPLEMENTED();
-#endif
- filter_index = 1;
+ file_type_info.extensions.resize(1);
+ file_type_info.extensions[0].push_back(suggested_path.Extension());
+ file_type_info.include_all_files = true;
+ file_type_index = 1;
}
-
#if defined(OS_LINUX) || defined(OS_WIN)
if (g_should_prompt_for_filename) {
if (!select_file_dialog_.get())
@@ -1032,8 +1032,8 @@ void SavePackage::GetSaveInfo() {
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_SAVEAS_FILE,
string16(),
suggested_path,
- filter,
- filter_index,
+ &file_type_info,
+ file_type_index,
default_extension,
platform_util::GetTopLevel(
web_contents_->GetNativeView()),
@@ -1042,7 +1042,7 @@ void SavePackage::GetSaveInfo() {
#endif // defined(OS_LINUX) || defined(OS_WIN)
{
// Just use 'suggested_path' instead of opening the dialog prompt.
- ContinueSave(save_params, suggested_path, filter_index);
+ ContinueSave(save_params, suggested_path, file_type_index);
delete save_params;
}
}
diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc
index d7b6350..113edb2 100644
--- a/chrome/browser/gtk/dialogs_gtk.cc
+++ b/chrome/browser/gtk/dialogs_gtk.cc
@@ -30,12 +30,13 @@ class SelectFileDialogImpl : public SelectFileDialog {
// SelectFileDialog implementation.
// |params| is user data we pass back via the Listener interface.
- virtual void SelectFile(Type type, const string16& title,
+ virtual void SelectFile(Type type,
+ const string16& title,
const FilePath& default_path,
- const std::wstring& filter,
- int filter_index,
+ const FileTypeInfo* file_types,
+ int file_type_index,
const FilePath::StringType& default_extension,
- gfx::NativeWindow parent_window,
+ gfx::NativeWindow owning_window,
void* params);
private:
@@ -114,21 +115,21 @@ void SelectFileDialogImpl::ListenerDestroyed() {
listener_ = NULL;
}
-// We ignore |filter| and |default_extension|.
-// TODO(estade): use |filter|.
+// We ignore |file_types| and |default_extension|.
+// TODO(estade): use |file_types|.
void SelectFileDialogImpl::SelectFile(
Type type,
const string16& title,
const FilePath& default_path,
- const std::wstring& filter,
- int filter_index,
+ const FileTypeInfo* file_types,
+ int file_type_index,
const FilePath::StringType& default_extension,
- gfx::NativeWindow parent_window,
+ gfx::NativeWindow owning_window,
void* params) {
// TODO(estade): on windows, parent_window may be null. But I'm not sure when
// that's used and how to deal with it here. For now, don't allow it.
- DCHECK(parent_window);
- parents_.insert(parent_window);
+ DCHECK(owning_window);
+ parents_.insert(owning_window);
std::string title_string = UTF16ToUTF8(title);
@@ -136,14 +137,14 @@ void SelectFileDialogImpl::SelectFile(
switch (type) {
case SELECT_OPEN_FILE:
DCHECK(default_path.empty());
- dialog = CreateFileOpenDialog(title_string, parent_window);
+ dialog = CreateFileOpenDialog(title_string, owning_window);
break;
case SELECT_OPEN_MULTI_FILE:
DCHECK(default_path.empty());
- dialog = CreateMultiFileOpenDialog(title_string, parent_window);
+ dialog = CreateMultiFileOpenDialog(title_string, owning_window);
break;
case SELECT_SAVEAS_FILE:
- dialog = CreateSaveAsDialog(title_string, default_path, parent_window);
+ dialog = CreateSaveAsDialog(title_string, default_path, owning_window);
break;
default:
NOTIMPLEMENTED() << "Dialog type " << type << " not implemented.";
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index ef6ea8d..e50c032 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -1126,12 +1126,9 @@ void RenderViewHost::OnMsgPasteFromSelectionClipboard() {
}
void RenderViewHost::OnMsgRunFileChooser(bool multiple_files,
- const std::wstring& title,
- const std::wstring& default_file,
- const std::wstring& filter) {
- std::wstring real_filter = filter;
- std::replace(real_filter.begin(), real_filter.end(), '|', '\0');
- delegate_->RunFileChooser(multiple_files, title, default_file, real_filter);
+ const string16& title,
+ const FilePath& default_file) {
+ delegate_->RunFileChooser(multiple_files, title, default_file);
}
void RenderViewHost::OnMsgRunJavaScriptMessage(
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 8d82ba3..e6e7ad11 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -511,9 +511,8 @@ class RenderViewHost : public RenderWidgetHost {
void OnMsgSelectionChanged(const std::string& text);
void OnMsgPasteFromSelectionClipboard();
void OnMsgRunFileChooser(bool multiple_files,
- const std::wstring& title,
- const std::wstring& default_file,
- const std::wstring& filter);
+ const string16& title,
+ const FilePath& default_file);
void OnMsgRunJavaScriptMessage(const std::wstring& message,
const std::wstring& default_prompt,
const GURL& frame_url,
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index 7a9a94b..ebe8df1 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -283,9 +283,8 @@ class RenderViewHostDelegate {
// A file chooser should be shown.
virtual void RunFileChooser(bool multiple_files,
- const std::wstring& title,
- const std::wstring& default_file,
- const std::wstring& filter) { }
+ const string16& title,
+ const FilePath& default_file) { }
// A javascript message, confirmation or prompt should be shown.
virtual void RunJavaScriptMessage(const std::wstring& message,
diff --git a/chrome/browser/shell_dialogs.h b/chrome/browser/shell_dialogs.h
index 4975395..4285364 100644
--- a/chrome/browser/shell_dialogs.h
+++ b/chrome/browser/shell_dialogs.h
@@ -15,9 +15,6 @@
class ChromeFont;
-// Helpers to show certain types of Windows shell dialogs in a way that doesn't
-// block the UI of the entire app.
-
// A base class for shell dialogs.
class BaseShellDialog {
public:
@@ -71,36 +68,50 @@ class SelectFileDialog
// object will have no reference (refcount is 0).
static SelectFileDialog* Create(Listener* listener);
+ // Holds information about allowed extensions on a file save dialog.
+ // |extensions| is a list of allowed extensions. For example, it might be
+ // { { "htm", "html" }, { "txt" } }. Only pass more than one extension
+ // in the inner vector if the extensions are equivalent. Do NOT include
+ // leading periods.
+ // |extension_description_overrides| overrides the system descriptions of the
+ // specified extensions. Entries correspond to |extensions|; if left blank
+ // the system descriptions will be used.
+ // |include_all_files| specifies whether all files (e.g. *.*) will be allowed
+ // in the file filtering.
+ struct FileTypeInfo {
+ std::vector<std::vector<FilePath::StringType> > extensions;
+ std::vector<string16> extension_description_overrides;
+ bool include_all_files;
+ };
+
// Selects a file. This will start displaying the dialog box. This will also
// block the calling window until the dialog box is complete. The listener
// associated with this object will be notified when the selection is
// complete.
// |type| is the type of file dialog to be shown, see Type enumeration above.
// |title| is the title to be displayed in the dialog. If this string is
- // empty, the default title is used.
+ // empty, the default title is used.
// |default_path| is the default path and suggested file name to be shown in
- // the dialog. This only works for SELECT_SAVEAS_FILE and SELECT_OPEN_FILE.
- // Can be an empty string to indicate Windows should choose the default to
- // show.
- // |filter| is a null (\0) separated list of alternating filter description
- // and filters and terminated with two nulls.
- // |filter_index| is the 1-based index into the filter list in |filter|.
- // Specify 0 if you don't need filters, or if you only need the default
- // (first filter) behavior.
- // |owning_window| is the window the dialog is modal to, or NULL for a
- // modeless dialog.
+ // the dialog. This only works for SELECT_SAVEAS_FILE and SELECT_OPEN_FILE.
+ // Can be an empty string to indicate the platform default.
+ // |file_types| holds the infomation about the file types allowed. Pass NULL
+ // to get no special behavior
+ // |file_type_index| is the 1-based index into the file type list in
+ // |file_types|. Specify 0 if you don't need to specify extension behavior.
// |default_extension| is the default extension to add to the file if the
- // user doesn't type one. This should NOT include the '.'. If you specify
- // this you must also specify a filter.
+ // user doesn't type one. This should NOT include the '.'. On Windows, if
+ // you specify this you must also specify |file_types|.
+ // |owning_window| is the window the dialog is modal to, or NULL for a
+ // modeless dialog.
// |params| is data from the calling context which will be passed through to
- // the listener. Can be NULL.
+ // the listener. Can be NULL.
// NOTE: only one instance of any shell dialog can be shown per owning_window
// at a time (for obvious reasons).
virtual void SelectFile(Type type,
const string16& title,
const FilePath& default_path,
- const std::wstring& filter,
- int filter_index,
+ const FileTypeInfo* file_types,
+ int file_type_index,
const FilePath::StringType& default_extension,
gfx::NativeWindow owning_window,
void* params) = 0;
diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc
index eaf181e..b58d7b3 100644
--- a/chrome/browser/tab_contents/web_contents.cc
+++ b/chrome/browser/tab_contents/web_contents.cc
@@ -1145,15 +1145,14 @@ void WebContents::GetHistoryListCount(int* back_list_count,
void WebContents::RunFileChooser(bool multiple_files,
const string16& title,
- const FilePath& default_file,
- const std::wstring& filter) {
+ const FilePath& default_file) {
if (!select_file_dialog_.get())
select_file_dialog_ = SelectFileDialog::Create(this);
SelectFileDialog::Type dialog_type =
multiple_files ? SelectFileDialog::SELECT_OPEN_MULTI_FILE :
SelectFileDialog::SELECT_OPEN_FILE;
select_file_dialog_->SelectFile(dialog_type, title, default_file,
- filter, 0, FILE_PATH_LITERAL(""),
+ NULL, 0, FILE_PATH_LITERAL(""),
view_->GetTopLevelNativeWindow(), NULL);
}
diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h
index be0fe27..6164ddb 100644
--- a/chrome/browser/tab_contents/web_contents.h
+++ b/chrome/browser/tab_contents/web_contents.h
@@ -370,8 +370,7 @@ class WebContents : public TabContents,
int* forward_list_count);
virtual void RunFileChooser(bool multiple_files,
const string16& title,
- const FilePath& default_file,
- const std::wstring& filter);
+ const FilePath& default_file);
virtual void RunJavaScriptMessage(const std::wstring& message,
const std::wstring& default_prompt,
const GURL& frame_url,
diff --git a/chrome/browser/views/bookmark_manager_view.cc b/chrome/browser/views/bookmark_manager_view.cc
index 12150c6..585f6a4 100644
--- a/chrome/browser/views/bookmark_manager_view.cc
+++ b/chrome/browser/views/bookmark_manager_view.cc
@@ -716,14 +716,16 @@ void BookmarkManagerView::ShowImportBookmarksFileChooser() {
if (select_file_dialog_.get())
select_file_dialog_->ListenerDestroyed();
- std::wstring filter_string =
- win_util::GetFileFilterFromExtensions(L"*.html;*.htm", true);
+ SelectFileDialog::FileTypeInfo file_type_info;
+ file_type_info.extensions.resize(1);
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm"));
+ file_type_info.include_all_files = true;
select_file_dialog_ = SelectFileDialog::Create(this);
select_file_dialog_->SelectFile(
SelectFileDialog::SELECT_OPEN_FILE, std::wstring(),
- FilePath(FILE_PATH_LITERAL("bookmarks.html")), filter_string, 0,
- std::wstring(),
- GetWidget()->GetNativeView(),
+ FilePath(FILE_PATH_LITERAL("bookmarks.html")), &file_type_info, 0,
+ std::wstring(), GetWidget()->GetNativeView(),
reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_IMPORT_MENU));
}
@@ -731,11 +733,14 @@ void BookmarkManagerView::ShowExportBookmarksFileChooser() {
if (select_file_dialog_.get())
select_file_dialog_->ListenerDestroyed();
+ SelectFileDialog::FileTypeInfo file_type_info;
+ file_type_info.extensions.resize(1);
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
+ file_type_info.include_all_files = true;
select_file_dialog_ = SelectFileDialog::Create(this);
select_file_dialog_->SelectFile(
SelectFileDialog::SELECT_SAVEAS_FILE, std::wstring(),
- FilePath(FILE_PATH_LITERAL("bookmarks.html")),
- win_util::GetFileFilterFromPath(L"bookmarks.html"), 0, L"html",
- GetWidget()->GetNativeView(),
+ FilePath(FILE_PATH_LITERAL("bookmarks.html")), &file_type_info, 0,
+ L"html", GetWidget()->GetNativeView(),
reinterpret_cast<void*>(IDS_BOOKMARK_MANAGER_EXPORT_MENU));
}
diff --git a/chrome/browser/views/options/content_page_view.cc b/chrome/browser/views/options/content_page_view.cc
index e6966e0..10feabc9 100644
--- a/chrome/browser/views/options/content_page_view.cc
+++ b/chrome/browser/views/options/content_page_view.cc
@@ -217,7 +217,7 @@ void ContentPageView::ButtonPressed(views::Button* sender) {
FilePath::FromWStringHack(
profile()->GetPrefs()->GetString(
prefs::kDownloadDefaultDirectory)),
- std::wstring(), 0, std::wstring(),
+ NULL, 0, std::wstring(),
GetRootWindow(),
NULL);
} else if (sender == download_ask_for_save_location_checkbox_) {
diff --git a/chrome/browser/views/shell_dialogs_win.cc b/chrome/browser/views/shell_dialogs_win.cc
index 0c3abcf..69ee892 100644
--- a/chrome/browser/views/shell_dialogs_win.cc
+++ b/chrome/browser/views/shell_dialogs_win.cc
@@ -22,6 +22,9 @@
#include "chrome/common/win_util.h"
#include "grit/generated_resources.h"
+// Helpers to show certain types of Windows shell dialogs in a way that doesn't
+// block the UI of the entire app.
+
class ShellDialogThread : public base::Thread {
public:
ShellDialogThread() : base::Thread("Chrome_ShellDialogThread") { }
@@ -192,12 +195,13 @@ class SelectFileDialogImpl : public SelectFileDialog,
virtual ~SelectFileDialogImpl();
// SelectFileDialog implementation:
- virtual void SelectFile(Type type, const string16& title,
+ virtual void SelectFile(Type type,
+ const string16& title,
const FilePath& default_path,
- const std::wstring& filter,
- int filter_index,
+ const FileTypeInfo* file_types,
+ int file_type_index,
const FilePath::StringType& default_extension,
- HWND owning_hwnd,
+ gfx::NativeWindow owning_window,
void* params);
virtual bool IsRunning(HWND owning_hwnd) const;
virtual void ListenerDestroyed();
@@ -208,21 +212,31 @@ class SelectFileDialogImpl : public SelectFileDialog,
ExecuteSelectParams(Type type,
const std::wstring& title,
const FilePath& default_path,
- const std::wstring& filter,
- int filter_index,
+ const FileTypeInfo* file_types,
+ int file_type_index,
const std::wstring& default_extension,
RunState run_state,
HWND owner,
void* params)
- : type(type), title(title), default_path(default_path), filter(filter),
- filter_index(filter_index), default_extension(default_extension),
- run_state(run_state), owner(owner), params(params) {
+ : type(type),
+ title(title),
+ default_path(default_path),
+ file_type_index(file_type_index),
+ default_extension(default_extension),
+ run_state(run_state),
+ owner(owner),
+ params(params) {
+ if (file_types) {
+ this->file_types = *file_types;
+ } else {
+ this->file_types.include_all_files = true;
+ }
}
SelectFileDialog::Type type;
std::wstring title;
FilePath default_path;
- std::wstring filter;
- int filter_index;
+ FileTypeInfo file_types;
+ int file_type_index;
std::wstring default_extension;
RunState run_state;
HWND owner;
@@ -291,14 +305,15 @@ void SelectFileDialogImpl::SelectFile(
Type type,
const string16& title,
const FilePath& default_path,
- const std::wstring& filter,
- int filter_index,
+ const FileTypeInfo* file_types,
+ int file_type_index,
const FilePath::StringType& default_extension,
- HWND owner,
+ gfx::NativeWindow owning_window,
void* params) {
ExecuteSelectParams execute_params(type, UTF16ToWide(title), default_path,
- filter, filter_index, default_extension,
- BeginRun(owner), owner, params);
+ file_types, file_type_index,
+ default_extension, BeginRun(owning_window),
+ owning_window, params);
execute_params.run_state.dialog_thread->message_loop()->PostTask(FROM_HERE,
NewRunnableMethod(this, &SelectFileDialogImpl::ExecuteSelectFile,
execute_params));
@@ -316,9 +331,27 @@ void SelectFileDialogImpl::ListenerDestroyed() {
void SelectFileDialogImpl::ExecuteSelectFile(
const ExecuteSelectParams& params) {
+ std::vector<std::wstring> exts;
+ for (size_t i=0; i<params.file_types.extensions.size(); ++i) {
+ const std::vector<std::wstring>& inner_exts =
+ params.file_types.extensions[i];
+ std::wstring ext_string;
+ for (size_t j=0; j<inner_exts.size(); ++j) {
+ if (!ext_string.empty())
+ ext_string.push_back(L';');
+ ext_string.push_back(L'.');
+ ext_string.append(inner_exts[j]);
+ }
+ exts.push_back(ext_string);
+ }
+ std::wstring filter = win_util::FormatFilterForExtensions(
+ exts,
+ params.file_types.extension_description_overrides,
+ params.file_types.include_all_files);
+
FilePath path = params.default_path;
bool success = false;
- unsigned filter_index = params.filter_index;
+ unsigned filter_index = params.file_type_index;
if (params.type == SELECT_FOLDER) {
success = RunSelectFolderDialog(params.title,
params.run_state.owner,
@@ -326,18 +359,18 @@ void SelectFileDialogImpl::ExecuteSelectFile(
} else if (params.type == SELECT_SAVEAS_FILE) {
std::wstring path_as_wstring = path.ToWStringHack();
success = win_util::SaveFileAsWithFilter(params.run_state.owner,
- params.default_path.ToWStringHack(), params.filter,
+ params.default_path.ToWStringHack(), filter,
params.default_extension, false, &filter_index, &path_as_wstring);
if(success) {
path = FilePath::FromWStringHack(path_as_wstring);
}
DisableOwner(params.run_state.owner);
} else if (params.type == SELECT_OPEN_FILE) {
- success = RunOpenFileDialog(params.title, params.filter,
+ success = RunOpenFileDialog(params.title, filter,
params.run_state.owner, &path);
} else if (params.type == SELECT_OPEN_MULTI_FILE) {
std::vector<FilePath> paths;
- if (RunOpenMultiFileDialog(params.title, params.filter,
+ if (RunOpenMultiFileDialog(params.title, filter,
params.run_state.owner, &paths)) {
ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
&SelectFileDialogImpl::MultiFilesSelected,
@@ -425,7 +458,7 @@ bool SelectFileDialogImpl::RunSelectFolderDialog(const std::wstring& title,
HRESULT hr = shell_folder->GetDisplayNameOf(list, SHGDN_FORPARSING,
&out_dir_buffer);
if (SUCCEEDED(hr) && out_dir_buffer.uType == STRRET_WSTR) {
- *path = FilePath::FromWStringHack(out_dir_buffer.pOleStr);
+ *path = FilePath(out_dir_buffer.pOleStr);
CoTaskMemFree(out_dir_buffer.pOleStr);
result = true;
}
@@ -433,7 +466,7 @@ bool SelectFileDialogImpl::RunSelectFolderDialog(const std::wstring& title,
// Use old way if we don't get what we want.
wchar_t old_out_dir_buffer[MAX_PATH + 1];
if (SHGetPathFromIDList(list, old_out_dir_buffer)) {
- *path = FilePath::FromWStringHack(old_out_dir_buffer);
+ *path = FilePath(old_out_dir_buffer);
result = true;
}
}
diff --git a/chrome/browser/views/user_data_dir_dialog.cc b/chrome/browser/views/user_data_dir_dialog.cc
index 958e4ce..3598950 100644
--- a/chrome/browser/views/user_data_dir_dialog.cc
+++ b/chrome/browser/views/user_data_dir_dialog.cc
@@ -73,7 +73,7 @@ bool UserDataDirDialog::Accept() {
HWND owning_hwnd =
GetAncestor(message_box_view_->GetWidget()->GetNativeView(), GA_ROOT);
select_file_dialog_->SelectFile(SelectFileDialog::SELECT_FOLDER,
- dialog_title, FilePath(), std::wstring(),
+ dialog_title, FilePath(), NULL,
0, std::wstring(), owning_hwnd, NULL);
return false;
}
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 6e2b3eb..06170ed 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -928,11 +928,10 @@ IPC_BEGIN_MESSAGES(ViewHost)
// Asks the browser to display the file chooser. The result is returned in a
// ViewHost_RunFileChooserResponse message.
- IPC_MESSAGE_ROUTED4(ViewHostMsg_RunFileChooser,
+ IPC_MESSAGE_ROUTED3(ViewHostMsg_RunFileChooser,
bool /* multiple_files */,
- std::wstring /* title */,
- std::wstring /* Default file name */,
- std::wstring /* filter */)
+ string16 /* title */,
+ FilePath /* Default file name */)
// Notification that password forms have been seen that are candidates for
// filling/submitting by the password manager
diff --git a/chrome/common/temp_scaffolding_stubs.h b/chrome/common/temp_scaffolding_stubs.h
index f73eb3f..69bdbbb 100644
--- a/chrome/common/temp_scaffolding_stubs.h
+++ b/chrome/common/temp_scaffolding_stubs.h
@@ -373,9 +373,14 @@ class SelectFileDialog : public base::RefCountedThreadSafe<SelectFileDialog> {
class Listener {
public:
};
+ struct FileTypeInfo {
+ std::vector<std::vector<FilePath::StringType> > extensions;
+ std::vector<string16> extension_description_overrides;
+ bool include_all_files;
+ };
void ListenerDestroyed() { NOTIMPLEMENTED(); }
void SelectFile(Type, const string16&, const FilePath&,
- const std::wstring&, int, const FilePath::StringType&,
+ const FileTypeInfo*, int, const FilePath::StringType&,
gfx::NativeWindow, void*) { NOTIMPLEMENTED(); }
static SelectFileDialog* Create(WebContents*) {
NOTIMPLEMENTED();
diff --git a/chrome/common/win_util.cc b/chrome/common/win_util.cc
index 62e3015..bf96cfb 100644
--- a/chrome/common/win_util.cc
+++ b/chrome/common/win_util.cc
@@ -219,107 +219,63 @@ static bool GetRegistryDescriptionFromExtension(const std::wstring& file_ext,
return false;
}
-// Set up a filter for a Save/Open dialog, which will consist of 'file_ext'
-// file extension, 'ext_desc' as the text description of the 'file_ext' type,
-// and (optionally) the default 'All Files' view. The purpose of the filter is
-// to show only files of a particular type in a Windows Save/Open dialog box.
-// The resulting filter is stored in 'buffer', which is a vector since multiple
-// NULLs are embedded. The filters created here are:
-// 1. only files that have 'file_ext' as their extension
-// 2. all files (only added if 'include_all_files' is true)
-// Example:
-// file_ext: ".txt"
-// ext_desc: "Text Document"
-// returned (in buffer): "Text Document\0*.txt\0All Files\0*.*\0\0"
-// This is painful to build, as you will soon see.
-static void FormatFilterForExtension(const std::wstring& file_ext,
- const std::wstring& ext_desc,
- bool include_all_files,
- std::vector<wchar_t>* buffer) {
- DCHECK(buffer);
-
- // Force something reasonable to appear in the dialog box if there is no
- // description provided.
- if (file_ext.empty() || ext_desc.empty())
- include_all_files = true;
-
- size_t size;
- size_t offset = 0;
+std::wstring FormatFilterForExtensions(
+ const std::vector<std::wstring>& file_ext,
+ const std::vector<std::wstring>& ext_desc,
+ bool include_all_files) {
const std::wstring all_ext = L"*.*";
const std::wstring all_desc = l10n_util::GetString(IDS_SAVEAS_ALL_FILES);
- // Includes 2 internal NULLs + "*".
- const size_t ext_size = ext_desc.length() + file_ext.length() + 3;
- // Includes 2 internal NULLs.
- const size_t all_size = all_desc.length() + all_ext.length() + 2;
- // Includes double terminating NULL.
- const size_t buf_size = (!ext_desc.empty() ? ext_size : 0) +
- (include_all_files ? all_size : 0) + 1;
- buffer->resize(buf_size);
-
- if (!file_ext.empty() && !ext_desc.empty()) {
- // Copy in the text description ("JPEG Image") + NULL.
- size = ext_desc.length() + 1;
- memcpy(&(*buffer)[offset], ext_desc.c_str(), size * sizeof(wchar_t));
- offset += size;
-
- // Copy in the file type ("*.jpg") + NULL.
- const std::wstring wildcard_ext = L"*" + file_ext;
- size = wildcard_ext.length() + 1;
- memcpy(&(*buffer)[offset], wildcard_ext.c_str(), size * sizeof(wchar_t));
- offset += size;
- }
+ DCHECK(file_ext.size()>=ext_desc.size());
- if (include_all_files) {
- // Copy in the default description ("All Files") + NULL.
- size = all_desc.length() + 1;
- memcpy(&(*buffer)[offset], all_desc.c_str(), size * sizeof(wchar_t));
- offset += size;
-
- // Copy in the default file extension ("*.*") + NULL.
- size = all_ext.length() + 1;
- memcpy(&(*buffer)[offset], all_ext.c_str(), size * sizeof(wchar_t));
- offset += size;
- }
+ std::wstring result;
- (*buffer)[offset] = L'\0'; // Double NULL required.
-}
+ for (size_t i=0; i<file_ext.size(); ++i) {
+ std::wstring ext = file_ext[i];
+ std::wstring desc;
+ if (i<ext_desc.size())
+ desc = ext_desc[i];
+
+ if (ext.empty()) {
+ // Force something reasonable to appear in the dialog box if there is no
+ // extension provided.
+ include_all_files = true;
+ continue;
+ }
-std::wstring GetFileFilterFromPath(const std::wstring& file_name) {
- std::wstring reg_description;
- std::wstring file_ext = file_util::GetFileExtensionFromPath(file_name);
- if (!file_ext.empty()) {
- file_ext = L"." + file_ext;
- GetRegistryDescriptionFromExtension(file_ext, &reg_description);
+ if (desc.empty()) {
+ DCHECK(ext.find(L'.') != std::wstring::npos);
+ std::wstring first_extension = ext.substr(ext.find(L'.'));
+ size_t first_separator_index = first_extension.find(L';');
+ if (first_separator_index != std::wstring::npos)
+ first_extension = first_extension.substr(0, first_separator_index);
+ GetRegistryDescriptionFromExtension(first_extension, &desc);
+ if (desc.empty())
+ desc = L"*." + first_extension;
+ }
+
+ result.append(desc.c_str(), desc.size()+1); // Append NULL too.
+ result.append(ext.c_str(), ext.size()+1);
}
- std::vector<wchar_t> filter;
- FormatFilterForExtension(file_ext, reg_description, true, &filter);
- return std::wstring(&filter[0], filter.size());
-}
+ if (include_all_files) {
+ result.append(all_desc.c_str(), all_desc.size()+1);
+ result.append(all_ext.c_str(), all_ext.size()+1);
+ }
-std::wstring GetFileFilterFromExtensions(const std::wstring& extensions,
- bool include_all_files) {
- DCHECK(extensions.find(L'.') != std::wstring::npos);
- std::wstring first_extension = extensions.substr(extensions.find(L'.'));
- size_t first_separator_index = first_extension.find(L';');
- if (first_separator_index != std::wstring::npos)
- first_extension = first_extension.substr(0, first_separator_index);
-
- std::wstring description;
- GetRegistryDescriptionFromExtension(first_extension, &description);
- if (description.empty())
- description = L"*." + first_extension;
-
- std::vector<wchar_t> filter;
- FormatFilterForExtension(extensions, description, true, &filter);
- return std::wstring(&filter[0], filter.size());
+ result.append(1, '\0'); // Double NULL required.
+ return result;
}
bool SaveFileAs(HWND owner,
const std::wstring& suggested_name,
std::wstring* final_name) {
- std::wstring filter = GetFileFilterFromPath(suggested_name);
+ std::wstring file_ext = file_util::GetFileExtensionFromPath(suggested_name);
+ file_ext.insert(L'.', 0);
+ std::wstring filter = FormatFilterForExtensions(
+ std::vector<std::wstring>(1, file_ext),
+ std::vector<std::wstring>(),
+ true);
unsigned index = 1;
return SaveFileAsWithFilter(owner,
suggested_name,
diff --git a/chrome/common/win_util.h b/chrome/common/win_util.h
index 8884960..b30ef5c 100644
--- a/chrome/common/win_util.h
+++ b/chrome/common/win_util.h
@@ -133,14 +133,23 @@ bool OpenItemViaShellNoZoneCheck(const FilePath& full_path,
// Returns 'true' on successful open, 'false' otherwise.
bool OpenItemWithExternalApp(const std::wstring& full_path);
-std::wstring GetFileFilterFromPath(const std::wstring& file_name);
-
-// Returns a file filter whose description comes from the OS for the first file
-// extension in |extensions|. |extensions| is a semicolon separated list of
-// extensions. Each extension is specified as '*.foo' where foo is the
-// extension.
-std::wstring GetFileFilterFromExtensions(const std::wstring& extensions,
- bool include_all_files);
+// Set up a filter for a Save/Open dialog, which will consist of |file_ext| file
+// extensions (internally separated by semicolons), |ext_desc| as the text
+// descriptions of the |file_ext| types (optional), and (optionally) the default
+// 'All Files' view. The purpose of the filter is to show only files of a
+// particular type in a Windows Save/Open dialog box. The resulting filter is
+// returned. The filters created here are:
+// 1. only files that have 'file_ext' as their extension
+// 2. all files (only added if 'include_all_files' is true)
+// Example:
+// file_ext: { ".txt", ".htm;.html" }
+// ext_desc: { "Text Document" }
+// returned: "Text Document\0*.txt\0HTML Document\0.htm;.html\0"
+// "All Files\0*.*\0\0" (in one big string)
+std::wstring FormatFilterForExtensions(
+ const std::vector<std::wstring>& file_ext,
+ const std::vector<std::wstring>& ext_desc,
+ bool include_all_files);
// Prompt the user for location to save a file. 'suggested_name' is a full path
// that gives the dialog box a hint as to how to initialize itself.
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 5afb9a6..3dd7887 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1781,9 +1781,8 @@ void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
}
void RenderView::RunFileChooser(bool multi_select,
- const std::wstring& title,
- const std::wstring& default_filename,
- const std::wstring& filter,
+ const string16& title,
+ const FilePath& default_filename,
WebFileChooserCallback* file_chooser) {
if (file_chooser_.get()) {
// TODO(brettw): bug 1235154: This should be a synchronous message to deal
@@ -1797,7 +1796,7 @@ void RenderView::RunFileChooser(bool multi_select,
}
file_chooser_.reset(file_chooser);
Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
- default_filename, filter));
+ default_filename));
}
void RenderView::AddMessageToConsole(WebView* webview,
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 409b6ac..dd9b7c6 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -164,9 +164,8 @@ class RenderView : public RenderWidget,
virtual void UpdateTargetURL(WebView* webview,
const GURL& url);
virtual void RunFileChooser(bool multi_select,
- const std::wstring& title,
- const std::wstring& initial_filename,
- const std::wstring& filter,
+ const string16& title,
+ const FilePath& initial_filename,
WebFileChooserCallback* file_chooser);
virtual void AddMessageToConsole(WebView* webview,
const std::wstring& message,