diff options
author | zork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-13 23:54:57 +0000 |
---|---|---|
committer | zork@google.com <zork@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-01-13 23:54:57 +0000 |
commit | b62d1a8c6795a9feefe4a2e688463c56ce46a6bd (patch) | |
tree | 229f2d9bd915151f13642b5841c58603b0819690 | |
parent | 10dd1a30fbaee0315e78d1752cbf1fa8e22c99e4 (diff) | |
download | chromium_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.cc | 13 | ||||
-rw-r--r-- | chrome/browser/render_view_host.cc | 23 | ||||
-rw-r--r-- | chrome/browser/render_view_host.h | 9 | ||||
-rw-r--r-- | chrome/browser/render_view_host_delegate.h | 5 | ||||
-rw-r--r-- | chrome/browser/resource_message_filter.h | 5 | ||||
-rw-r--r-- | chrome/browser/shell_dialogs.h | 8 | ||||
-rw-r--r-- | chrome/browser/views/shell_dialogs.cc | 79 | ||||
-rw-r--r-- | chrome/browser/web_contents.cc | 23 | ||||
-rw-r--r-- | chrome/browser/web_contents.h | 7 | ||||
-rw-r--r-- | chrome/common/chrome_plugin_api.h | 20 | ||||
-rw-r--r-- | chrome/common/render_messages_internal.h | 9 | ||||
-rw-r--r-- | chrome/plugin/chrome_plugin_host.cc | 13 | ||||
-rw-r--r-- | chrome/renderer/chrome_plugin_host.cc | 55 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 13 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 7 | ||||
-rw-r--r-- | webkit/glue/chrome_client_impl.cc | 13 | ||||
-rw-r--r-- | webkit/glue/webview_delegate.h | 7 |
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; } |