- Linux: cefclient: Add a GTK implementation of CefDialogHandler (issue #1258).

- Add new CefGetExtensionsForMimeType function.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1761 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2014-07-09 18:03:43 +00:00
parent da1ac7dde5
commit 6f63f5d4f8
8 changed files with 294 additions and 0 deletions

View File

@ -68,6 +68,13 @@ CEF_EXPORT int cef_create_url(const struct _cef_urlparts_t* parts,
CEF_EXPORT cef_string_userfree_t cef_get_mime_type(
const cef_string_t* extension);
// Get the extensions associated with the given mime type. This should be passed
// in lower case. There could be multiple extensions for a given mime type, like
// "html,htm" for "text/html", or "txt,text,html,..." for "text/*". Any existing
// elements in the provided vector will not be erased.
CEF_EXPORT void cef_get_extensions_for_mime_type(const cef_string_t* mime_type,
cef_string_list_t extensions);
#ifdef __cplusplus
}
#endif

View File

@ -38,6 +38,8 @@
#define CEF_INCLUDE_CEF_URL_H_
#pragma once
#include <vector>
#include "include/cef_base.h"
///
@ -64,4 +66,12 @@ bool CefCreateURL(const CefURLParts& parts,
/*--cef()--*/
CefString CefGetMimeType(const CefString& extension);
// Get the extensions associated with the given mime type. This should be passed
// in lower case. There could be multiple extensions for a given mime type, like
// "html,htm" for "text/html", or "txt,text,html,..." for "text/*". Any existing
// elements in the provided vector will not be erased.
/*--cef()--*/
void CefGetExtensionsForMimeType(const CefString& mime_type,
std::vector<CefString>& extensions);
#endif // CEF_INCLUDE_CEF_URL_H_

View File

@ -74,3 +74,14 @@ CefString CefGetMimeType(const CefString& extension) {
net::GetMimeTypeFromExtension(extension, &mime_type);
return mime_type;
}
void CefGetExtensionsForMimeType(const CefString& mime_type,
std::vector<CefString>& extensions) {
typedef std::vector<base::FilePath::StringType> VectorType;
VectorType ext;
net::GetExtensionsForMimeType(mime_type, &ext);
VectorType::const_iterator it = ext.begin();
for (; it != ext.end(); ++it)
extensions.push_back(*it);
}

View File

@ -104,6 +104,7 @@
#include "libcef_dll/ctocpp/web_plugin_info_visitor_ctocpp.h"
#include "libcef_dll/ctocpp/web_plugin_unstable_callback_ctocpp.h"
#include "libcef_dll/ctocpp/write_handler_ctocpp.h"
#include "libcef_dll/transfer_util.h"
// GLOBAL FUNCTIONS - Body may be edited by hand.
@ -593,6 +594,33 @@ CEF_EXPORT cef_string_userfree_t cef_get_mime_type(
return _retval.DetachToUserFree();
}
CEF_EXPORT void cef_get_extensions_for_mime_type(const cef_string_t* mime_type,
cef_string_list_t extensions) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: mime_type; type: string_byref_const
DCHECK(mime_type);
if (!mime_type)
return;
// Verify param: extensions; type: string_vec_byref
DCHECK(extensions);
if (!extensions)
return;
// Translate param: extensions; type: string_vec_byref
std::vector<CefString> extensionsList;
transfer_string_list_contents(extensions, extensionsList);
// Execute
CefGetExtensionsForMimeType(
CefString(mime_type),
extensionsList);
// Restore param: extensions; type: string_vec_byref
cef_string_list_clear(extensions);
transfer_string_list_contents(extensionsList, extensions);
}
CEF_EXPORT int cef_register_extension(const cef_string_t* extension_name,
const cef_string_t* javascript_code, struct _cef_v8handler_t* handler) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -105,6 +105,7 @@
#include "libcef_dll/ctocpp/web_plugin_info_ctocpp.h"
#include "libcef_dll/ctocpp/xml_reader_ctocpp.h"
#include "libcef_dll/ctocpp/zip_reader_ctocpp.h"
#include "libcef_dll/transfer_util.h"
// Define used to facilitate parsing.
#define CEF_GLOBAL
@ -546,6 +547,34 @@ CEF_GLOBAL CefString CefGetMimeType(const CefString& extension) {
return _retvalStr;
}
CEF_GLOBAL void CefGetExtensionsForMimeType(const CefString& mime_type,
std::vector<CefString>& extensions) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: mime_type; type: string_byref_const
DCHECK(!mime_type.empty());
if (mime_type.empty())
return;
// Translate param: extensions; type: string_vec_byref
cef_string_list_t extensionsList = cef_string_list_alloc();
DCHECK(extensionsList);
if (extensionsList)
transfer_string_list_contents(extensions, extensionsList);
// Execute
cef_get_extensions_for_mime_type(
mime_type.GetStruct(),
extensionsList);
// Restore param:extensions; type: string_vec_byref
if (extensionsList) {
extensions.clear();
transfer_string_list_contents(extensionsList, extensions);
cef_string_list_free(extensionsList);
}
}
CEF_GLOBAL bool CefRegisterExtension(const CefString& extension_name,
const CefString& javascript_code, CefRefPtr<CefV8Handler> handler) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -178,6 +178,19 @@ bool ClientHandler::OnContextMenuCommand(
}
}
#if !defined(OS_LINUX)
bool ClientHandler::OnFileDialog(CefRefPtr<CefBrowser> browser,
FileDialogMode mode,
const CefString& title,
const CefString& default_file_name,
const std::vector<CefString>& accept_types,
CefRefPtr<CefFileDialogCallback> callback) {
return false;
}
#endif // !defined(OS_LINUX)
bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
const CefString& message,
const CefString& source,

View File

@ -29,6 +29,7 @@
// ClientHandler implementation.
class ClientHandler : public CefClient,
public CefContextMenuHandler,
public CefDialogHandler,
public CefDisplayHandler,
public CefDownloadHandler,
public CefDragHandler,
@ -55,6 +56,9 @@ class ClientHandler : public CefClient,
virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefDialogHandler> GetDialogHandler() OVERRIDE {
return this;
}
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
return this;
}
@ -101,6 +105,14 @@ class ClientHandler : public CefClient,
int command_id,
EventFlags event_flags) OVERRIDE;
// CefDialogHandler methods
virtual bool OnFileDialog(CefRefPtr<CefBrowser> browser,
FileDialogMode mode,
const CefString& title,
const CefString& default_file_name,
const std::vector<CefString>& accept_types,
CefRefPtr<CefFileDialogCallback> callback) OVERRIDE;
// CefDisplayHandler methods
virtual void OnAddressChange(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,

View File

@ -3,6 +3,7 @@
// can be found in the LICENSE file.
#include <gtk/gtk.h>
#include <libgen.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#undef Success // Definition conflicts with cef_message_router.h
@ -12,6 +13,7 @@
#include "cefclient/client_handler.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_url.h"
namespace {
@ -27,8 +29,190 @@ std::string GetPromptText(GtkDialog* dialog) {
return std::string();
}
std::string GetDescriptionFromMimeType(const std::string& mime_type) {
// Check for wild card mime types and return an appropriate description.
static const struct {
const char* mime_type;
const char* label;
} kWildCardMimeTypes[] = {
{ "audio", "Audio Files" },
{ "image", "Image Files" },
{ "text", "Text Files" },
{ "video", "Video Files" },
};
for (size_t i = 0;
i < sizeof(kWildCardMimeTypes) / sizeof(kWildCardMimeTypes[0]); ++i) {
if (mime_type == std::string(kWildCardMimeTypes[i].mime_type) + "/*")
return std::string(kWildCardMimeTypes[i].label);
}
return std::string();
}
void AddFiltersForAcceptTypes(GtkFileChooser* chooser,
const std::vector<CefString>& accept_types,
bool include_all_files) {
bool has_filter = false;
for (size_t i = 0; i < accept_types.size(); ++i) {
std::string ascii_type = accept_types[i];
if (ascii_type.length()) {
// Just treat as extension if contains '.' as the first character.
if (ascii_type[0] == '.') {
GtkFileFilter* filter = gtk_file_filter_new();
std::string pattern = "*" + ascii_type;
gtk_file_filter_add_pattern(filter, pattern.c_str());
gtk_file_filter_set_name(filter, pattern.c_str());
gtk_file_chooser_add_filter(chooser, filter);
if (!has_filter)
has_filter = true;
} else {
// Otherwise convert mime type to one or more extensions.
GtkFileFilter* filter = NULL;
std::string description = GetDescriptionFromMimeType(ascii_type);
bool description_from_ext = description.empty();
std::vector<CefString> ext;
CefGetExtensionsForMimeType(ascii_type, ext);
for (size_t x = 0; x < ext.size(); ++x) {
if (!filter)
filter = gtk_file_filter_new();
std::string pattern = "*." + ext[x].ToString();
gtk_file_filter_add_pattern(filter, pattern.c_str());
if (description_from_ext) {
if (x != 0)
description += ";";
description += pattern;
}
}
if (filter) {
gtk_file_filter_set_name(filter, description.c_str());
gtk_file_chooser_add_filter(chooser, filter);
if (!has_filter)
has_filter = true;
}
}
}
}
// Add the *.* filter, but only if we have added other filters (otherwise it
// is implied).
if (include_all_files && has_filter) {
GtkFileFilter* filter = gtk_file_filter_new();
gtk_file_filter_add_pattern(filter, "*");
gtk_file_filter_set_name(filter, "All Files");
gtk_file_chooser_add_filter(chooser, filter);
}
}
} // namespace
bool ClientHandler::OnFileDialog(CefRefPtr<CefBrowser> browser,
FileDialogMode mode,
const CefString& title,
const CefString& default_file_name,
const std::vector<CefString>& accept_types,
CefRefPtr<CefFileDialogCallback> callback) {
std::vector<CefString> files;
GtkFileChooserAction action;
const gchar* accept_button;
if (mode == FILE_DIALOG_OPEN || mode == FILE_DIALOG_OPEN_MULTIPLE) {
action = GTK_FILE_CHOOSER_ACTION_OPEN;
accept_button = GTK_STOCK_OPEN;
} else if (mode == FILE_DIALOG_SAVE) {
action = GTK_FILE_CHOOSER_ACTION_SAVE;
accept_button = GTK_STOCK_SAVE;
} else {
ASSERT(false); // Not reached
return false;
}
std::string base_name;
if (!default_file_name.empty()) {
base_name =
basename(const_cast<char*>(default_file_name.ToString().c_str()));
}
std::string title_str;
if (!title.empty()) {
title_str = title;
} else {
switch (mode) {
case FILE_DIALOG_OPEN:
title_str = "Open File";
break;
case FILE_DIALOG_OPEN_MULTIPLE:
title_str = "Open Files";
break;
case FILE_DIALOG_SAVE:
title_str = "Save File";
break;
default:
break;
}
}
GtkWidget* window =
gtk_widget_get_ancestor(GTK_WIDGET(GetMainHwnd()), GTK_TYPE_WINDOW);
GtkWidget* dialog = gtk_file_chooser_dialog_new(
title_str.c_str(),
GTK_WINDOW(window),
action,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
accept_button, GTK_RESPONSE_ACCEPT,
NULL);
if (mode == FILE_DIALOG_OPEN_MULTIPLE) {
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
} else if (mode == FILE_DIALOG_SAVE) {
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog),
TRUE);
}
if (mode == FILE_DIALOG_SAVE && !base_name.empty()) {
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
base_name.c_str());
}
AddFiltersForAcceptTypes(GTK_FILE_CHOOSER(dialog), accept_types, true);
bool success = false;
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
if (mode == FILE_DIALOG_OPEN || mode == FILE_DIALOG_SAVE) {
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
files.push_back(std::string(filename));
success = true;
} else if (mode == FILE_DIALOG_OPEN_MULTIPLE) {
GSList* filenames =
gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
if (filenames) {
for (GSList* iter = filenames; iter != NULL;
iter = g_slist_next(iter)) {
std::string path(static_cast<char*>(iter->data));
g_free(iter->data);
files.push_back(path);
}
g_slist_free(filenames);
success = true;
}
}
}
gtk_widget_destroy(dialog);
if (success)
callback->Continue(files);
else
callback->Cancel();
return true;
}
void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefString& url) {