summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-13 23:54:57 +0000
committerzork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-13 23:54:57 +0000
commitb62d1a8c6795a9feefe4a2e688463c56ce46a6bd (patch)
tree229f2d9bd915151f13642b5841c58603b0819690
parent10dd1a30fbaee0315e78d1752cbf1fa8e22c99e4 (diff)
downloadchromium_src-b62d1a8c6795a9feefe4a2e688463c56ce46a6bd.zip
chromium_src-b62d1a8c6795a9feefe4a2e688463c56ce46a6bd.tar.gz
chromium_src-b62d1a8c6795a9feefe4a2e688463c56ce46a6bd.tar.bz2
Updating so that Gears can spawn file selectors when running in the renderer process
Review URL: http://codereview.chromium.org/14907 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@7986 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_plugin_host.cc13
-rw-r--r--chrome/browser/render_view_host.cc23
-rw-r--r--chrome/browser/render_view_host.h9
-rw-r--r--chrome/browser/render_view_host_delegate.h5
-rw-r--r--chrome/browser/resource_message_filter.h5
-rw-r--r--chrome/browser/shell_dialogs.h8
-rw-r--r--chrome/browser/views/shell_dialogs.cc79
-rw-r--r--chrome/browser/web_contents.cc23
-rw-r--r--chrome/browser/web_contents.h7
-rw-r--r--chrome/common/chrome_plugin_api.h20
-rw-r--r--chrome/common/render_messages_internal.h9
-rw-r--r--chrome/plugin/chrome_plugin_host.cc13
-rw-r--r--chrome/renderer/chrome_plugin_host.cc55
-rw-r--r--chrome/renderer/render_view.cc13
-rw-r--r--chrome/renderer/render_view.h7
-rw-r--r--webkit/glue/chrome_client_impl.cc13
-rw-r--r--webkit/glue/webview_delegate.h7
17 files changed, 281 insertions, 28 deletions
diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc
index 008a7fe..55f1dd1 100644
--- a/chrome/browser/chrome_plugin_host.cc
+++ b/chrome/browser/chrome_plugin_host.cc
@@ -694,6 +694,18 @@ CPError STDCALL CPB_PluginThreadAsyncCall(CPID id,
return CPERR_SUCCESS;
}
+CPError STDCALL CPB_OpenFileDialog(CPID id,
+ CPBrowsingContext context,
+ bool multiple_files,
+ const char *title,
+ const char *filter,
+ void *user_data) {
+ NOTREACHED() <<
+ "Open file dialog should only be called from the renderer process.";
+
+ return CPERR_FAILURE;
+}
+
}
CPBrowserFuncs* GetCPBrowserFuncsForBrowser() {
@@ -727,6 +739,7 @@ CPBrowserFuncs* GetCPBrowserFuncsForBrowser() {
browser_funcs.response_funcs = &response_funcs;
browser_funcs.send_sync_message = CPB_SendSyncMessage;
browser_funcs.plugin_thread_async_call = CPB_PluginThreadAsyncCall;
+ browser_funcs.open_file_dialog = CPB_OpenFileDialog;
request_funcs.size = sizeof(request_funcs);
request_funcs.start_request = CPR_StartRequest;
diff --git a/chrome/browser/render_view_host.cc b/chrome/browser/render_view_host.cc
index 0d43757..6fa62b8 100644
--- a/chrome/browser/render_view_host.cc
+++ b/chrome/browser/render_view_host.cc
@@ -600,7 +600,19 @@ void RenderViewHost::InstallMissingPlugin() {
void RenderViewHost::FileSelected(const std::wstring& path) {
RendererSecurityPolicy::GetInstance()->GrantUploadFile(process()->host_id(),
path);
- Send(new ViewMsg_RunFileChooserResponse(routing_id_, path));
+ std::vector<std::wstring> files;
+ files.push_back(path);
+ Send(new ViewMsg_RunFileChooserResponse(routing_id_, files));
+}
+
+void RenderViewHost::MultiFilesSelected(
+ const std::vector<std::wstring>& files) {
+ for (std::vector<std::wstring>::const_iterator file = files.begin();
+ file != files.end(); ++file) {
+ RendererSecurityPolicy::GetInstance()->GrantUploadFile(
+ process()->host_id(), *file);
+ }
+ Send(new ViewMsg_RunFileChooserResponse(routing_id_, files));
}
void RenderViewHost::LoadStateChanged(const GURL& url,
@@ -1057,8 +1069,13 @@ void RenderViewHost::OnMsgSetTooltipText(const std::wstring& tooltip_text) {
}
}
-void RenderViewHost::OnMsgRunFileChooser(const std::wstring& default_file) {
- delegate_->RunFileChooser(default_file);
+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);
}
void RenderViewHost::OnMsgRunJavaScriptMessage(
diff --git a/chrome/browser/render_view_host.h b/chrome/browser/render_view_host.h
index 0dec873..f95720e 100644
--- a/chrome/browser/render_view_host.h
+++ b/chrome/browser/render_view_host.h
@@ -365,6 +365,10 @@ class RenderViewHost : public RenderWidgetHost {
// an Open File dialog for the form.
void FileSelected(const std::wstring& path);
+ // Notifies the Listener that many files have been chosen by the user from
+ // an Open File dialog for the form.
+ void MultiFilesSelected(const std::vector<std::wstring>& files);
+
// Notifies the RenderViewHost that its load state changed.
void LoadStateChanged(const GURL& url, net::LoadState load_state);
@@ -469,7 +473,10 @@ class RenderViewHost : public RenderWidgetHost {
#endif
void OnMsgGoToEntryAtOffset(int offset);
void OnMsgSetTooltipText(const std::wstring& tooltip_text);
- void OnMsgRunFileChooser(const std::wstring& default_file);
+ void OnMsgRunFileChooser(bool multiple_files,
+ const std::wstring& title,
+ const std::wstring& default_file,
+ const std::wstring& filter);
void OnMsgRunJavaScriptMessage(const std::wstring& message,
const std::wstring& default_prompt,
const int flags,
diff --git a/chrome/browser/render_view_host_delegate.h b/chrome/browser/render_view_host_delegate.h
index 91cc531..1fd0c41 100644
--- a/chrome/browser/render_view_host_delegate.h
+++ b/chrome/browser/render_view_host_delegate.h
@@ -259,7 +259,10 @@ class RenderViewHostDelegate {
int* forward_list_count) { }
// A file chooser should be shown.
- virtual void RunFileChooser(const std::wstring& default_file) { }
+ virtual void RunFileChooser(bool multiple_files,
+ const std::wstring& title,
+ const std::wstring& default_file,
+ const std::wstring& filter) { }
// A javascript message, confirmation or prompt should be shown.
virtual void RunJavaScriptMessage(const std::wstring& message,
diff --git a/chrome/browser/resource_message_filter.h b/chrome/browser/resource_message_filter.h
index badf7b4..640b138 100644
--- a/chrome/browser/resource_message_filter.h
+++ b/chrome/browser/resource_message_filter.h
@@ -98,6 +98,11 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
void OnPluginSyncMessage(const FilePath& plugin_path,
const std::vector<uint8>& message,
std::vector<uint8> *retval);
+ void OnPluginFileDialog(const IPC::Message& msg,
+ bool multiple_files,
+ const std::wstring& title,
+ const std::wstring& filter,
+ uint32 user_data);
// Cache fonts for the renderer. See ResourceMessageFilter::OnLoadFont
// implementation for more details
diff --git a/chrome/browser/shell_dialogs.h b/chrome/browser/shell_dialogs.h
index 183081dc..54f601c 100644
--- a/chrome/browser/shell_dialogs.h
+++ b/chrome/browser/shell_dialogs.h
@@ -37,7 +37,8 @@ class SelectFileDialog
enum Type {
SELECT_FOLDER,
SELECT_SAVEAS_FILE,
- SELECT_OPEN_FILE
+ SELECT_OPEN_FILE,
+ SELECT_OPEN_MULTI_FILE
};
virtual ~SelectFileDialog() {}
@@ -52,6 +53,11 @@ class SelectFileDialog
// SelectFile.
virtual void FileSelected(const std::wstring& path, void* params) = 0;
+ // Notifies the Listener that many files have been selected. The
+ // files are in |files|. |params| is contextual passed to SelectFile.
+ virtual void MultiFilesSelected(
+ const std::vector<std::wstring>& files, void* params) {};
+
// Notifies the Listener that the file/folder selection was aborted (via
// the user canceling or closing the selection dialog box, for example).
// |params| is contextual passed to SelectFile.
diff --git a/chrome/browser/views/shell_dialogs.cc b/chrome/browser/views/shell_dialogs.cc
index e38d81f..ab85d0a 100644
--- a/chrome/browser/views/shell_dialogs.cc
+++ b/chrome/browser/views/shell_dialogs.cc
@@ -215,6 +215,10 @@ class SelectFileDialogImpl : public SelectFileDialog,
// Notifies the listener that a folder was chosen. Run on the ui thread.
void FileSelected(const std::wstring& path, void* params, RunState run_state);
+ // Notifies listener that multiple files were chosen. Run on the ui thread.
+ void MultiFilesSelected(const std::vector<std::wstring>& paths, void* params,
+ RunState run_state);
+
// Notifies the listener that no file was chosen (the action was canceled).
// Run on the ui thread.
void FileNotSelected(void* params, RunState run_state);
@@ -235,6 +239,13 @@ class SelectFileDialogImpl : public SelectFileDialog,
HWND owner,
std::wstring* path);
+ // Runs an Open file dialog box that supports multi-select, with similar
+ // semantics for input paramaters as RunOpenFileDialog.
+ bool RunOpenMultiFileDialog(const std::wstring& title,
+ const std::wstring& filter,
+ HWND owner,
+ std::vector<std::wstring>* paths);
+
// The callback function for when the select folder dialog is opened.
static int CALLBACK BrowseCallbackProc(HWND window, UINT message,
LPARAM parameter,
@@ -297,6 +308,13 @@ void SelectFileDialogImpl::ExecuteSelectFile(
DisableOwner(run_state.owner);
} else if (type == SELECT_OPEN_FILE) {
success = RunOpenFileDialog(title, filter, run_state.owner, &path);
+ } else if (type == SELECT_OPEN_MULTI_FILE) {
+ std::vector<std::wstring> paths;
+ if (RunOpenMultiFileDialog(title, filter, run_state.owner, &paths)) {
+ ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
+ &SelectFileDialogImpl::MultiFilesSelected, paths, params, run_state));
+ return;
+ }
}
if (success) {
@@ -316,6 +334,15 @@ void SelectFileDialogImpl::FileSelected(const std::wstring& selected_folder,
EndRun(run_state);
}
+void SelectFileDialogImpl::MultiFilesSelected(
+ const std::vector<std::wstring>& selected_files,
+ void* params,
+ RunState run_state) {
+ if (listener_)
+ listener_->MultiFilesSelected(selected_files, params);
+ EndRun(run_state);
+}
+
void SelectFileDialogImpl::FileNotSelected(void* params, RunState run_state) {
if (listener_)
listener_->FileSelectionCanceled(params);
@@ -419,6 +446,58 @@ bool SelectFileDialogImpl::RunOpenFileDialog(
return success;
}
+bool SelectFileDialogImpl::RunOpenMultiFileDialog(
+ const std::wstring& title,
+ const std::wstring& filter,
+ HWND owner,
+ std::vector<std::wstring>* paths) {
+ OPENFILENAME ofn;
+ // We must do this otherwise the ofn's FlagsEx may be initialized to random
+ // junk in release builds which can cause the Places Bar not to show up!
+ ZeroMemory(&ofn, sizeof(ofn));
+ ofn.lStructSize = sizeof(ofn);
+ ofn.hwndOwner = owner;
+
+ wchar_t filename[MAX_PATH] = L"";
+
+ ofn.lpstrFile = filename;
+ ofn.nMaxFile = MAX_PATH;
+ // We use OFN_NOCHANGEDIR so that the user can rename or delete the directory
+ // without having to close Chrome first.
+ ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_EXPLORER
+ | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT;
+
+ if (!filter.empty()) {
+ ofn.lpstrFilter = filter.c_str();
+ }
+ bool success = !!GetOpenFileName(&ofn);
+ DisableOwner(owner);
+ if (success) {
+ std::vector<std::wstring> files;
+ const wchar_t* selection = ofn.lpstrFile;
+ while (*selection) { // Empty string indicates end of list.
+ files.push_back(selection);
+ // Skip over filename and null-terminator.
+ selection += files.back().length() + 1;
+ }
+ if (files.empty()) {
+ success = false;
+ } else if (files.size() == 1) {
+ // When there is one file, it contains the path and filename.
+ paths->swap(files);
+ } else {
+ // Otherwise, the first string is the path, and the remainder are
+ // filenames.
+ std::vector<std::wstring>::iterator path = files.begin();
+ for (std::vector<std::wstring>::iterator file = path + 1;
+ file != files.end(); ++file) {
+ paths->push_back(*path + L'\\' + *file);
+ }
+ }
+ }
+ return success;
+}
+
// static
SelectFileDialog* SelectFileDialog::Create(Listener* listener) {
return new SelectFileDialogImpl(listener);
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index d8c6e42..90f6491 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -993,12 +993,17 @@ void WebContents::GetHistoryListCount(int* back_list_count,
}
}
-void WebContents::RunFileChooser(const std::wstring& default_file) {
+void WebContents::RunFileChooser(bool multiple_files,
+ const std::wstring& title,
+ const std::wstring& default_file,
+ const std::wstring& filter) {
HWND toplevel_hwnd = GetAncestor(GetContainerHWND(), GA_ROOT);
if (!select_file_dialog_.get())
select_file_dialog_ = SelectFileDialog::Create(this);
- select_file_dialog_->SelectFile(SelectFileDialog::SELECT_OPEN_FILE,
- std::wstring(), default_file, std::wstring(),
+ 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,
std::wstring(), toplevel_hwnd, NULL);
}
@@ -1352,10 +1357,16 @@ void WebContents::FileSelected(const std::wstring& path, void* params) {
render_view_host()->FileSelected(path);
}
+void WebContents::MultiFilesSelected(const std::vector<std::wstring>& files,
+ void* params) {
+ render_view_host()->MultiFilesSelected(files);
+}
+
+
void WebContents::FileSelectionCanceled(void* params) {
- // If the user cancels choosing a file to upload we need to pass back the
- // empty string.
- render_view_host()->FileSelected(std::wstring());
+ // If the user cancels choosing a file to upload we pass back an
+ // empty vector.
+ render_view_host()->MultiFilesSelected(std::vector<std::wstring>());
}
void WebContents::BeforeUnloadFiredFromRenderManager(
diff --git a/chrome/browser/web_contents.h b/chrome/browser/web_contents.h
index b7bb356..1ac6a56 100644
--- a/chrome/browser/web_contents.h
+++ b/chrome/browser/web_contents.h
@@ -269,7 +269,10 @@ class WebContents : public TabContents,
virtual void GoToEntryAtOffset(int offset);
virtual void GetHistoryListCount(int* back_list_count,
int* forward_list_count);
- virtual void RunFileChooser(const std::wstring& default_file);
+ virtual void RunFileChooser(bool multiple_files,
+ const std::wstring& title,
+ const std::wstring& default_file,
+ const std::wstring& filter);
virtual void RunJavaScriptMessage(const std::wstring& message,
const std::wstring& default_prompt,
const int flags,
@@ -320,6 +323,8 @@ class WebContents : public TabContents,
// SelectFileDialog::Listener ------------------------------------------------
virtual void FileSelected(const std::wstring& path, void* params);
+ virtual void MultiFilesSelected(const std::vector<std::wstring>& files,
+ void* params);
virtual void FileSelectionCanceled(void* params);
// RenderViewHostManager::Delegate -------------------------------------------
diff --git a/chrome/common/chrome_plugin_api.h b/chrome/common/chrome_plugin_api.h
index 14a54e5..039dac8 100644
--- a/chrome/common/chrome_plugin_api.h
+++ b/chrome/common/chrome_plugin_api.h
@@ -30,7 +30,7 @@ extern "C" {
// The current version of the API, used by the 'version' field of CPPluginFuncs
// and CPBrowserFuncs.
#define CP_MAJOR_VERSION 0
-#define CP_MINOR_VERSION 8
+#define CP_MINOR_VERSION 9
#define CP_VERSION ((CP_MAJOR_VERSION << 8) | (CP_MINOR_VERSION))
#define CP_GET_MAJOR_VERSION(version) ((version & 0xff00) >> 8)
@@ -390,6 +390,16 @@ typedef CPError (STDCALL *CPB_PluginThreadAsyncCallFunc)(CPID id,
void (*func)(void *),
void *user_data);
+// This function creates an open file dialog. The process is granted access
+// to any files that are selected. |multiple_files| determines if more than
+// one file can be selected.
+typedef CPError (STDCALL *CPB_OpenFileDialogFunc)(CPID id,
+ CPBrowsingContext context,
+ bool multiple_files,
+ const char *title,
+ const char *filter,
+ void *user_data);
+
// Informs the plugin of raw data having been sent from another process.
typedef void (STDCALL *CPP_OnMessageFunc)(void *data, uint32 data_len);
@@ -397,6 +407,12 @@ typedef void (STDCALL *CPP_OnMessageFunc)(void *data, uint32 data_len);
typedef void (STDCALL *CPP_OnSyncMessageFunc)(void *data, uint32 data_len,
void **retval, uint32 *retval_len);
+// Informs the plugin that the file dialog has completed, and contains the
+// results.
+typedef void (STDCALL *CPP_OnFileDialogResultFunc)(void *data,
+ const char **files,
+ uint32 files_len);
+
// Function table for issuing requests using via the other side's network stack.
// For the plugin, this functions deal with issuing requests through the
// browser. For the browser, these functions deal with allowing the plugin to
@@ -440,6 +456,7 @@ typedef struct _CPPluginFuncs {
CPP_HtmlDialogClosedFunc html_dialog_closed;
CPP_HandleCommandFunc handle_command;
CPP_OnSyncMessageFunc on_sync_message;
+ CPP_OnFileDialogResultFunc on_file_dialog_result;
} CPPluginFuncs;
// Function table CPB functions (functions provided by host to plugin).
@@ -469,6 +486,7 @@ typedef struct _CPBrowserFuncs {
CPB_HandleCommandFunc handle_command;
CPB_SendSyncMessageFunc send_sync_message;
CPB_PluginThreadAsyncCallFunc plugin_thread_async_call;
+ CPB_OpenFileDialogFunc open_file_dialog;
} CPBrowserFuncs;
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 4160da8..a3c3f3d 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -378,7 +378,7 @@ IPC_BEGIN_MESSAGES(View, 1)
IPC_MESSAGE_ROUTED0(ViewMsg_InstallMissingPlugin)
IPC_MESSAGE_ROUTED1(ViewMsg_RunFileChooserResponse,
- std::wstring /* file_name */)
+ std::vector<std::wstring> /* selected files */)
// Used to instruct the RenderView to go into "view source" mode.
IPC_MESSAGE_ROUTED0(ViewMsg_EnableViewSourceMode)
@@ -852,8 +852,11 @@ IPC_BEGIN_MESSAGES(ViewHost, 2)
// Asks the browser to display the file chooser. The result is returned in a
// ViewHost_RunFileChooserResponse message.
- IPC_MESSAGE_ROUTED1(ViewHostMsg_RunFileChooser,
- std::wstring /* Default file name */)
+ IPC_MESSAGE_ROUTED4(ViewHostMsg_RunFileChooser,
+ bool /* multiple_files */,
+ std::wstring /* title */,
+ std::wstring /* Default file name */,
+ std::wstring /* filter */)
// Notification that password forms have been seen that are candidates for
// filling/submitting by the password manager
diff --git a/chrome/plugin/chrome_plugin_host.cc b/chrome/plugin/chrome_plugin_host.cc
index 677404f..2002fa90 100644
--- a/chrome/plugin/chrome_plugin_host.cc
+++ b/chrome/plugin/chrome_plugin_host.cc
@@ -544,6 +544,18 @@ CPError STDCALL CPB_PluginThreadAsyncCall(CPID id,
return CPERR_SUCCESS;
}
+CPError STDCALL CPB_OpenFileDialog(CPID id,
+ CPBrowsingContext context,
+ bool multiple_files,
+ const char *title,
+ const char *filter,
+ void *user_data) {
+ NOTREACHED() <<
+ "Open file dialog should only be called from the renderer process.";
+
+ return CPERR_FAILURE;
+}
+
} // namespace
CPBrowserFuncs* GetCPBrowserFuncsForPlugin() {
@@ -574,6 +586,7 @@ CPBrowserFuncs* GetCPBrowserFuncsForPlugin() {
browser_funcs.handle_command = CPB_HandleCommand;
browser_funcs.send_sync_message = CPB_SendSyncMessage;
browser_funcs.plugin_thread_async_call = CPB_PluginThreadAsyncCall;
+ browser_funcs.open_file_dialog = CPB_OpenFileDialog;
browser_funcs.request_funcs = &request_funcs;
browser_funcs.response_funcs = &response_funcs;
diff --git a/chrome/renderer/chrome_plugin_host.cc b/chrome/renderer/chrome_plugin_host.cc
index bd84b26..ae7dd86 100644
--- a/chrome/renderer/chrome_plugin_host.cc
+++ b/chrome/renderer/chrome_plugin_host.cc
@@ -534,6 +534,60 @@ CPError STDCALL CPB_PluginThreadAsyncCall(CPID id,
return CPERR_SUCCESS;
}
+class PluginOpenFileDialogListener : public WebFileChooserCallback {
+ public:
+ PluginOpenFileDialogListener(CPID cpid, void *user_data)
+ : cpid_(cpid), user_data_(user_data) {
+ }
+ virtual void OnFileChoose(const std::vector<std::wstring>& file_names) {
+ ChromePluginLib *chrome_plugin = ChromePluginLib::FromCPID(cpid_);
+ if (chrome_plugin) {
+ if (!file_names.empty()) {
+ std::vector<std::string> utf8_files;
+ std::vector<const char *> ret_files;
+ for (std::vector<std::wstring>::const_iterator ix = file_names.begin();
+ ix != file_names.end(); ++ix) {
+ utf8_files.push_back(WideToUTF8(*ix));
+ ret_files.push_back(utf8_files.back().c_str());
+ }
+
+ chrome_plugin->functions().on_file_dialog_result(user_data_,
+ &ret_files.at(0),
+ ret_files.size());
+ } else {
+ chrome_plugin->functions().on_file_dialog_result(user_data_, 0, 0);
+ }
+ }
+ }
+
+ private:
+ CPID cpid_;
+ void *user_data_;
+};
+
+CPError STDCALL CPB_OpenFileDialog(CPID id,
+ CPBrowsingContext context,
+ bool multiple_files,
+ const char *title,
+ const char *filter,
+ void *user_data) {
+ CHECK(ChromePluginLib::IsPluginThread());
+
+ WebPlugin* webplugin = WebPluginFromContext(context);
+ WebFrame* webframe = webplugin->GetWebFrame();
+ WebView* webview = webframe->GetView();
+ WebViewDelegate* webviewdelegate = webview->GetDelegate();
+
+ PluginOpenFileDialogListener *listener =
+ new PluginOpenFileDialogListener(id, user_data);
+
+ webviewdelegate->RunFileChooser(multiple_files, UTF8ToWide(title),
+ std::wstring(), UTF8ToWide(filter),
+ listener);
+
+ return CPERR_SUCCESS;
+}
+
} // namespace
CPBrowserFuncs* GetCPBrowserFuncsForRenderer() {
@@ -564,6 +618,7 @@ CPBrowserFuncs* GetCPBrowserFuncsForRenderer() {
browser_funcs.handle_command = CPB_HandleCommand;
browser_funcs.send_sync_message = CPB_SendSyncMessage;
browser_funcs.plugin_thread_async_call = CPB_PluginThreadAsyncCall;
+ browser_funcs.open_file_dialog = CPB_OpenFileDialog;
browser_funcs.request_funcs = &request_funcs;
browser_funcs.response_funcs = &response_funcs;
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 5b328c3..708453f 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1744,7 +1744,10 @@ void RenderView::UpdateTargetURL(WebView* webview, const GURL& url) {
}
}
-void RenderView::RunFileChooser(const std::wstring& default_filename,
+void RenderView::RunFileChooser(bool multi_select,
+ const std::wstring& title,
+ const std::wstring& default_filename,
+ const std::wstring& filter,
WebFileChooserCallback* file_chooser) {
if (file_chooser_.get()) {
// TODO(brettw): bug 1235154: This should be a synchronous message to deal
@@ -1757,7 +1760,8 @@ void RenderView::RunFileChooser(const std::wstring& default_filename,
return;
}
file_chooser_.reset(file_chooser);
- Send(new ViewHostMsg_RunFileChooser(routing_id_, default_filename));
+ Send(new ViewHostMsg_RunFileChooser(routing_id_, multi_select, title,
+ default_filename, filter));
}
void RenderView::AddMessageToConsole(WebView* webview,
@@ -2569,8 +2573,9 @@ void RenderView::OnInstallMissingPlugin() {
first_default_plugin_->InstallMissingPlugin();
}
-void RenderView::OnFileChooserResponse(const std::wstring& file_name) {
- file_chooser_->OnFileChoose(file_name);
+void RenderView::OnFileChooserResponse(
+ const std::vector<std::wstring>& file_names) {
+ file_chooser_->OnFileChoose(file_names);
file_chooser_.reset();
}
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 76e8e0e..ef0307d 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -136,7 +136,10 @@ class RenderView : public RenderWidget,
int64 node_id);
virtual void UpdateTargetURL(WebView* webview,
const GURL& url);
- virtual void RunFileChooser(const std::wstring& default_filename,
+ virtual void RunFileChooser(bool multi_select,
+ const std::wstring& title,
+ const std::wstring& initial_filename,
+ const std::wstring& filter,
WebFileChooserCallback* file_chooser);
virtual void AddMessageToConsole(WebView* webview,
const std::wstring& message,
@@ -457,7 +460,7 @@ class RenderView : public RenderWidget,
int client_x, int client_y, int screen_x, int screen_y, bool ended);
void OnDragSourceSystemDragEnded();
void OnInstallMissingPlugin();
- void OnFileChooserResponse(const std::wstring& file_name);
+ void OnFileChooserResponse(const std::vector<std::wstring>& file_names);
void OnEnableViewSourceMode();
void OnUpdateBackForwardListCount(int back_list_count,
int forward_list_count);
diff --git a/webkit/glue/chrome_client_impl.cc b/webkit/glue/chrome_client_impl.cc
index 278134b..d19c28c 100644
--- a/webkit/glue/chrome_client_impl.cc
+++ b/webkit/glue/chrome_client_impl.cc
@@ -42,8 +42,14 @@ class WebFileChooserCallbackImpl : public WebFileChooserCallback {
: file_chooser_(file_chooser) {
}
- void OnFileChoose(const std::wstring& file_name) {
- file_chooser_->chooseFile(webkit_glue::StdWStringToString(file_name));
+ void OnFileChoose(const std::vector<std::wstring>& file_names) {
+ assert(file_names.size() <= 1);
+ if (file_names.empty()) {
+ file_chooser_->chooseFile(webkit_glue::StdWStringToString(L""));
+ } else {
+ file_chooser_->chooseFile(
+ webkit_glue::StdWStringToString(file_names.front().c_str()));
+ }
}
private:
@@ -457,7 +463,8 @@ void ChromeClientImpl::runOpenPanel(WebCore::Frame* frame,
suggestion = webkit_glue::StringToStdWString(fileChooser->filenames()[0]);
WebFileChooserCallbackImpl* chooser = new WebFileChooserCallbackImpl(fileChooser);
- delegate->RunFileChooser(suggestion, chooser);
+ delegate->RunFileChooser(false, std::wstring(), suggestion,
+ std::wstring(), chooser);
}
void ChromeClientImpl::popupOpened(WebCore::FramelessScrollView* popup_view,
diff --git a/webkit/glue/webview_delegate.h b/webkit/glue/webview_delegate.h
index b2fca89..09abc68 100644
--- a/webkit/glue/webview_delegate.h
+++ b/webkit/glue/webview_delegate.h
@@ -90,7 +90,7 @@ class WebFileChooserCallback {
public:
WebFileChooserCallback() {}
virtual ~WebFileChooserCallback() {}
- virtual void OnFileChoose(const std::wstring& file_name) { }
+ virtual void OnFileChoose(const std::vector<std::wstring>& file_names) { }
private:
DISALLOW_EVIL_CONSTRUCTORS(WebFileChooserCallback);
@@ -538,7 +538,10 @@ class WebViewDelegate : virtual public WebWidgetDelegate {
// populated with the given initial_filename string. The WebViewDelegate
// will own the WebFileChooserCallback object and is responsible for
// freeing it.
- virtual void RunFileChooser(const std::wstring& initial_filename,
+ virtual void RunFileChooser(bool multi_select,
+ const std::wstring& title,
+ const std::wstring& initial_filename,
+ const std::wstring& filter,
WebFileChooserCallback* file_chooser) {
delete file_chooser;
}