Mac: Add dialogs for input type="file" (issue #632).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@688 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2012-06-11 19:48:55 +00:00
parent 61e9bc6007
commit 1161d18c82
5 changed files with 141 additions and 4 deletions

View File

@ -6,6 +6,7 @@
#include "libcef/browser/browser_host_impl.h"
#include <string>
#include <utility>
#include "libcef/browser/browser_context.h"
#include "libcef/browser/context.h"
@ -29,6 +30,8 @@
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/resource_request_info.h"
#include "content/public/common/file_chooser_params.h"
#include "content/public/common/selected_file_info.h"
namespace {
@ -259,7 +262,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserByChildID(
content::RenderProcessHost::FromID(render_process_id);
if (!render_process_host)
return NULL;
content::RenderProcessHost::RenderWidgetHostsIterator iter(
render_process_host->GetRenderWidgetHostsIterator());
if (!iter.IsAtEnd()) {
@ -276,7 +279,7 @@ CefRefPtr<CefBrowserHostImpl> CefBrowserHostImpl::GetBrowserByChildID(
const_cast<content::RenderWidgetHost*>(widget)));
}
}
return NULL;
} else {
// Use the thread-safe approach.
@ -1020,7 +1023,35 @@ content::JavaScriptDialogCreator*
void CefBrowserHostImpl::RunFileChooser(
content::WebContents* tab,
const content::FileChooserParams& params) {
// TODO(cef): Implement this method to run the file chooser dialog.
content::RenderViewHost* render_view_host = tab->GetRenderViewHost();
if (!render_view_host)
return;
if (params.mode != content::FileChooserParams::Open &&
params.mode != content::FileChooserParams::OpenMultiple) {
NOTREACHED() << "unsupported file chooser mode requested";
return;
}
std::vector<FilePath> fileList;
PlatformRunFileChooser(tab, params, fileList);
const int kReadFilePermissions =
base::PLATFORM_FILE_OPEN |
base::PLATFORM_FILE_READ |
base::PLATFORM_FILE_EXCLUSIVE_READ |
base::PLATFORM_FILE_ASYNC;
// Convert FilePath list to SelectedFileInfo list.
std::vector<content::SelectedFileInfo> selected_files;
for (size_t i = 0; i < fileList.size(); ++i) {
selected_files.push_back(
content::SelectedFileInfo(fileList[i], FilePath::StringType()));
}
// Notify our RenderViewHost in all cases.
render_view_host->FilesSelectedInChooser(selected_files,
kReadFilePermissions);
}
void CefBrowserHostImpl::UpdatePreferredSize(content::WebContents* source,

View File

@ -312,6 +312,11 @@ class CefBrowserHostImpl : public CefBrowserHost,
// processing of shortcut keys.
void PlatformHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event);
// Invoke platform specific file open chooser.
void PlatformRunFileChooser(
content::WebContents* contents,
const content::FileChooserParams& params,
std::vector<FilePath>& files);
void OnAddressChange(CefRefPtr<CefFrame> frame,
const GURL& url);

View File

@ -131,3 +131,10 @@ void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
const content::NativeWebKeyboardEvent& event) {
// TODO(cef): Is something required here to handle shortcut keys?
}
void CefBrowserHostImpl::PlatformRunFileChooser(
content::WebContents* contents,
const content::FileChooserParams& params,
std::vector<FilePath>& files) {
NOTIMPLEMENTED();
}

View File

@ -6,10 +6,18 @@
#include "libcef/browser/browser_host_impl.h"
#import <Cocoa/Cocoa.h>
#import <CoreServices/CoreServices.h>
#include "base/file_util.h"
#include "base/mac/mac_util.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/native_web_keyboard_event.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
#include "content/public/common/file_chooser_params.h"
#import "ui/base/cocoa/underlay_opengl_hosting_window.h"
#include "ui/gfx/rect.h"
@ -50,6 +58,32 @@
@end
namespace {
// Accept-types to file-types helper.
NSMutableArray* GetFileTypesFromAcceptTypes(
const std::vector<string16>& accept_types) {
NSMutableArray* acceptArray = [[NSMutableArray alloc] init];
for (size_t i=0; i<accept_types.size(); i++) {
std::string ascii_type = UTF16ToASCII(accept_types[i]);
if (ascii_type.length()) {
// Just treat as extension if contains '.' as the first character.
if (ascii_type[0] == '.') {
[acceptArray addObject:base::SysUTF8ToNSString(ascii_type)];
} else {
// Otherwise convert mime to UTI.
NSString* mimeType = base::SysUTF8ToNSString(ascii_type);
NSString* UTI = [NSMakeCollectable(
UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
(CFStringRef) mimeType, NULL)) autorelease];
[acceptArray addObject:UTI];
}
}
}
return acceptArray;
}
} // namespace
bool CefBrowserHostImpl::PlatformViewText(const std::string& text) {
NOTIMPLEMENTED();
@ -143,3 +177,56 @@ void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
if ([event.os_event type] == NSKeyDown)
[[NSApp mainMenu] performKeyEquivalent:event.os_event];
}
void CefBrowserHostImpl::PlatformRunFileChooser(
content::WebContents* contents,
const content::FileChooserParams& params,
std::vector<FilePath>& files) {
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
if (!params.title.empty())
[openPanel setTitle:base::SysUTF16ToNSString(params.title)];
// Consider default file name if any.
FilePath default_file_name(params.default_file_name);
if (!default_file_name.empty()) {
if (!default_file_name.BaseName().empty()) {
NSString* defaultName = base::SysUTF8ToNSString(
default_file_name.BaseName().value());
[openPanel setNameFieldStringValue:defaultName];
}
if (!default_file_name.DirName().empty()) {
NSString* defaultDir = base::SysUTF8ToNSString(
default_file_name.DirName().value());
[openPanel setDirectoryURL:[NSURL fileURLWithPath:defaultDir]];
}
}
// Consider supported file types
if (!params.accept_types.empty()) {
[openPanel setAllowedFileTypes:GetFileTypesFromAcceptTypes(
params.accept_types)];
}
// Further panel configuration.
[openPanel setAllowsOtherFileTypes:YES];
[openPanel setAllowsMultipleSelection:
(params.mode == content::FileChooserParams::OpenMultiple)];
[openPanel setCanChooseFiles:YES];
[openPanel setCanChooseDirectories:NO];
// Show panel.
NSView* view = contents->GetNativeView();
[openPanel beginSheetModalForWindow:[view window] completionHandler:nil];
if ([openPanel runModal] == NSFileHandlingPanelOKButton) {
NSArray *urls = [openPanel URLs];
int i, count = [urls count];
for (i=0; i<count; i++) {
NSURL* url = [urls objectAtIndex:i];
if ([url isFileURL])
files.push_back(FilePath(base::SysNSStringToUTF8([url path])));
}
}
[NSApp endSheet:openPanel];
}

View File

@ -260,3 +260,10 @@ void CefBrowserHostImpl::PlatformHandleKeyboardEvent(
DefWindowProc(event.os_event.hwnd, event.os_event.message,
event.os_event.wParam, event.os_event.lParam);
}
void CefBrowserHostImpl::PlatformRunFileChooser(
content::WebContents* contents,
const content::FileChooserParams& params,
std::vector<FilePath>& files) {
NOTIMPLEMENTED();
}