mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-03 12:37:36 +01:00
- 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:
parent
da1ac7dde5
commit
6f63f5d4f8
@ -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
|
||||
|
@ -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_
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user