mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-02 20:26:59 +01:00
cefclient: Linux: Move GTK dialog handlers from ClientHandler into a separate class (issue #1500).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1991 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
dfc2dfb0f5
commit
f38c620e28
@ -261,6 +261,8 @@
|
|||||||
'cefclient_sources_linux': [
|
'cefclient_sources_linux': [
|
||||||
'tests/cefclient/cefclient_gtk.cc',
|
'tests/cefclient/cefclient_gtk.cc',
|
||||||
'tests/cefclient/client_handler_gtk.cc',
|
'tests/cefclient/client_handler_gtk.cc',
|
||||||
|
'tests/cefclient/dialog_handler_gtk.cc',
|
||||||
|
'tests/cefclient/dialog_handler_gtk.h',
|
||||||
'tests/cefclient/main_context_impl_posix.cc',
|
'tests/cefclient/main_context_impl_posix.cc',
|
||||||
'tests/cefclient/osr_widget_gtk.h',
|
'tests/cefclient/osr_widget_gtk.h',
|
||||||
'tests/cefclient/osr_widget_gtk.cc',
|
'tests/cefclient/osr_widget_gtk.cc',
|
||||||
|
@ -26,6 +26,10 @@
|
|||||||
#include "cefclient/resource_util.h"
|
#include "cefclient/resource_util.h"
|
||||||
#include "cefclient/test_runner.h"
|
#include "cefclient/test_runner.h"
|
||||||
|
|
||||||
|
#if defined(OS_LINUX)
|
||||||
|
#include "cefclient/dialog_handler_gtk.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
@ -65,12 +69,16 @@ ClientHandler::ClientHandler()
|
|||||||
console_log_file_(MainContext::Get()->GetConsoleLogPath()),
|
console_log_file_(MainContext::Get()->GetConsoleLogPath()),
|
||||||
first_console_message_(true),
|
first_console_message_(true),
|
||||||
focus_on_editable_field_(false) {
|
focus_on_editable_field_(false) {
|
||||||
#if defined(OS_LINUX)
|
|
||||||
gtk_dialog_ = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DCHECK(!console_log_file_.empty());
|
DCHECK(!console_log_file_.empty());
|
||||||
|
|
||||||
|
#if defined(OS_LINUX)
|
||||||
|
// Provide the GTK-based dialog implementation on Linux.
|
||||||
|
CefRefPtr<ClientDialogHandlerGtk> dialog_handler =
|
||||||
|
new ClientDialogHandlerGtk();
|
||||||
|
dialog_handler_ = dialog_handler.get();
|
||||||
|
jsdialog_handler_ = dialog_handler.get();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Read command line settings.
|
// Read command line settings.
|
||||||
CefRefPtr<CefCommandLine> command_line =
|
CefRefPtr<CefCommandLine> command_line =
|
||||||
CefCommandLine::GetGlobalCommandLine();
|
CefCommandLine::GetGlobalCommandLine();
|
||||||
@ -152,22 +160,6 @@ bool ClientHandler::OnContextMenuCommand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(OS_LINUX)
|
|
||||||
|
|
||||||
bool ClientHandler::OnFileDialog(CefRefPtr<CefBrowser> browser,
|
|
||||||
FileDialogMode mode,
|
|
||||||
const CefString& title,
|
|
||||||
const CefString& default_file_path,
|
|
||||||
const std::vector<CefString>& accept_filters,
|
|
||||||
int selected_accept_filter,
|
|
||||||
CefRefPtr<CefFileDialogCallback> callback) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !defined(OS_LINUX)
|
|
||||||
|
|
||||||
bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
|
bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
|
||||||
const CefString& message,
|
const CefString& message,
|
||||||
const CefString& source,
|
const CefString& source,
|
||||||
@ -243,35 +235,6 @@ bool ClientHandler::OnRequestGeolocationPermission(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(OS_LINUX)
|
|
||||||
|
|
||||||
bool ClientHandler::OnJSDialog(CefRefPtr<CefBrowser> browser,
|
|
||||||
const CefString& origin_url,
|
|
||||||
const CefString& accept_lang,
|
|
||||||
JSDialogType dialog_type,
|
|
||||||
const CefString& message_text,
|
|
||||||
const CefString& default_prompt_text,
|
|
||||||
CefRefPtr<CefJSDialogCallback> callback,
|
|
||||||
bool& suppress_message) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientHandler::OnBeforeUnloadDialog(
|
|
||||||
CefRefPtr<CefBrowser> browser,
|
|
||||||
const CefString& message_text,
|
|
||||||
bool is_reload,
|
|
||||||
CefRefPtr<CefJSDialogCallback> callback) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientHandler::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !defined(OS_LINUX)
|
|
||||||
|
|
||||||
bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
|
bool ClientHandler::OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
|
||||||
const CefKeyEvent& event,
|
const CefKeyEvent& event,
|
||||||
CefEventHandle os_event,
|
CefEventHandle os_event,
|
||||||
@ -607,6 +570,12 @@ void ClientHandler::SetMainWindowHandle(ClientWindowHandle handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main_handle_ = handle;
|
main_handle_ = handle;
|
||||||
|
|
||||||
|
#if defined(OS_LINUX)
|
||||||
|
// Associate |handle| with the GTK dialog handler.
|
||||||
|
static_cast<ClientDialogHandlerGtk*>(dialog_handler_.get())->set_parent(
|
||||||
|
handle);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientWindowHandle ClientHandler::GetMainWindowHandle() const {
|
ClientWindowHandle ClientHandler::GetMainWindowHandle() const {
|
||||||
|
@ -33,12 +33,10 @@ namespace client {
|
|||||||
// ClientHandler implementation.
|
// ClientHandler implementation.
|
||||||
class ClientHandler : public CefClient,
|
class ClientHandler : public CefClient,
|
||||||
public CefContextMenuHandler,
|
public CefContextMenuHandler,
|
||||||
public CefDialogHandler,
|
|
||||||
public CefDisplayHandler,
|
public CefDisplayHandler,
|
||||||
public CefDownloadHandler,
|
public CefDownloadHandler,
|
||||||
public CefDragHandler,
|
public CefDragHandler,
|
||||||
public CefGeolocationHandler,
|
public CefGeolocationHandler,
|
||||||
public CefJSDialogHandler,
|
|
||||||
public CefKeyboardHandler,
|
public CefKeyboardHandler,
|
||||||
public CefLifeSpanHandler,
|
public CefLifeSpanHandler,
|
||||||
public CefLoadHandler,
|
public CefLoadHandler,
|
||||||
@ -61,7 +59,7 @@ class ClientHandler : public CefClient,
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
CefRefPtr<CefDialogHandler> GetDialogHandler() OVERRIDE {
|
CefRefPtr<CefDialogHandler> GetDialogHandler() OVERRIDE {
|
||||||
return this;
|
return dialog_handler_;
|
||||||
}
|
}
|
||||||
CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
|
CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE {
|
||||||
return this;
|
return this;
|
||||||
@ -76,7 +74,7 @@ class ClientHandler : public CefClient,
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() OVERRIDE {
|
CefRefPtr<CefJSDialogHandler> GetJSDialogHandler() OVERRIDE {
|
||||||
return this;
|
return jsdialog_handler_;
|
||||||
}
|
}
|
||||||
CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE {
|
CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE {
|
||||||
return this;
|
return this;
|
||||||
@ -108,15 +106,6 @@ class ClientHandler : public CefClient,
|
|||||||
int command_id,
|
int command_id,
|
||||||
EventFlags event_flags) OVERRIDE;
|
EventFlags event_flags) OVERRIDE;
|
||||||
|
|
||||||
// CefDialogHandler methods
|
|
||||||
bool OnFileDialog(CefRefPtr<CefBrowser> browser,
|
|
||||||
FileDialogMode mode,
|
|
||||||
const CefString& title,
|
|
||||||
const CefString& default_file_path,
|
|
||||||
const std::vector<CefString>& accept_filters,
|
|
||||||
int selected_accept_filter,
|
|
||||||
CefRefPtr<CefFileDialogCallback> callback) OVERRIDE;
|
|
||||||
|
|
||||||
// CefDisplayHandler methods
|
// CefDisplayHandler methods
|
||||||
void OnAddressChange(CefRefPtr<CefBrowser> browser,
|
void OnAddressChange(CefRefPtr<CefBrowser> browser,
|
||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
@ -151,22 +140,6 @@ class ClientHandler : public CefClient,
|
|||||||
int request_id,
|
int request_id,
|
||||||
CefRefPtr<CefGeolocationCallback> callback) OVERRIDE;
|
CefRefPtr<CefGeolocationCallback> callback) OVERRIDE;
|
||||||
|
|
||||||
// CefJSDialogHandler methods
|
|
||||||
bool OnJSDialog(CefRefPtr<CefBrowser> browser,
|
|
||||||
const CefString& origin_url,
|
|
||||||
const CefString& accept_lang,
|
|
||||||
JSDialogType dialog_type,
|
|
||||||
const CefString& message_text,
|
|
||||||
const CefString& default_prompt_text,
|
|
||||||
CefRefPtr<CefJSDialogCallback> callback,
|
|
||||||
bool& suppress_message) OVERRIDE;
|
|
||||||
bool OnBeforeUnloadDialog(
|
|
||||||
CefRefPtr<CefBrowser> browser,
|
|
||||||
const CefString& message_text,
|
|
||||||
bool is_reload,
|
|
||||||
CefRefPtr<CefJSDialogCallback> callback) OVERRIDE;
|
|
||||||
void OnResetDialogState(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
|
||||||
|
|
||||||
// CefKeyboardHandler methods
|
// CefKeyboardHandler methods
|
||||||
bool OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
|
bool OnPreKeyEvent(CefRefPtr<CefBrowser> browser,
|
||||||
const CefKeyEvent& event,
|
const CefKeyEvent& event,
|
||||||
@ -302,6 +275,9 @@ class ClientHandler : public CefClient,
|
|||||||
|
|
||||||
// True if mouse cursor change is disabled.
|
// True if mouse cursor change is disabled.
|
||||||
bool mouse_cursor_change_disabled_;
|
bool mouse_cursor_change_disabled_;
|
||||||
|
|
||||||
|
CefRefPtr<CefDialogHandler> dialog_handler_;
|
||||||
|
CefRefPtr<CefJSDialogHandler> jsdialog_handler_;
|
||||||
// END THREAD SAFE MEMBERS
|
// END THREAD SAFE MEMBERS
|
||||||
|
|
||||||
// Lock used to protect members accessed on multiple threads. Make it mutable
|
// Lock used to protect members accessed on multiple threads. Make it mutable
|
||||||
@ -362,14 +338,6 @@ class ClientHandler : public CefClient,
|
|||||||
// when the number of windows reaches 0.
|
// when the number of windows reaches 0.
|
||||||
static int browser_count_;
|
static int browser_count_;
|
||||||
|
|
||||||
#if defined(OS_LINUX)
|
|
||||||
// Linux-only implementation of GTK-based dialog boxes.
|
|
||||||
static void OnDialogResponse(GtkDialog *dialog,
|
|
||||||
gint response_id,
|
|
||||||
ClientHandler* handler);
|
|
||||||
GtkWidget* gtk_dialog_;
|
|
||||||
CefRefPtr<CefJSDialogCallback> js_dialog_callback_;
|
|
||||||
#endif
|
|
||||||
// END UI THREAD ACCESS ONLY MEMBERS
|
// END UI THREAD ACCESS ONLY MEMBERS
|
||||||
|
|
||||||
// Include the default reference counting implementation.
|
// Include the default reference counting implementation.
|
||||||
|
@ -13,261 +13,9 @@
|
|||||||
#include "cefclient/client_handler.h"
|
#include "cefclient/client_handler.h"
|
||||||
#include "include/cef_browser.h"
|
#include "include/cef_browser.h"
|
||||||
#include "include/cef_frame.h"
|
#include "include/cef_frame.h"
|
||||||
#include "include/cef_url.h"
|
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const char kPromptTextId[] = "cef_prompt_text";
|
|
||||||
|
|
||||||
// If there's a text entry in the dialog, get the text from the first one and
|
|
||||||
// return it.
|
|
||||||
std::string GetPromptText(GtkDialog* dialog) {
|
|
||||||
GtkWidget* widget = static_cast<GtkWidget*>(
|
|
||||||
g_object_get_data(G_OBJECT(dialog), kPromptTextId));
|
|
||||||
if (widget)
|
|
||||||
return gtk_entry_get_text(GTK_ENTRY(widget));
|
|
||||||
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 AddFilters(GtkFileChooser* chooser,
|
|
||||||
const std::vector<CefString>& accept_filters,
|
|
||||||
bool include_all_files,
|
|
||||||
std::vector<GtkFileFilter*>* filters) {
|
|
||||||
bool has_filter = false;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < accept_filters.size(); ++i) {
|
|
||||||
const std::string& filter = accept_filters[i];
|
|
||||||
if (filter.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::vector<std::string> extensions;
|
|
||||||
std::string description;
|
|
||||||
|
|
||||||
size_t sep_index = filter.find('|');
|
|
||||||
if (sep_index != std::string::npos) {
|
|
||||||
// Treat as a filter of the form "Filter Name|.ext1;.ext2;.ext3".
|
|
||||||
description = filter.substr(0, sep_index);
|
|
||||||
|
|
||||||
const std::string& exts = filter.substr(sep_index + 1);
|
|
||||||
size_t last = 0;
|
|
||||||
size_t size = exts.size();
|
|
||||||
for (size_t i = 0; i <= size; ++i) {
|
|
||||||
if (i == size || exts[i] == ';') {
|
|
||||||
std::string ext(exts, last, i - last);
|
|
||||||
if (!ext.empty() && ext[0] == '.')
|
|
||||||
extensions.push_back(ext);
|
|
||||||
last = i + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (filter[0] == '.') {
|
|
||||||
// Treat as an extension beginning with the '.' character.
|
|
||||||
extensions.push_back(filter);
|
|
||||||
} else {
|
|
||||||
// Otherwise convert mime type to one or more extensions.
|
|
||||||
description = GetDescriptionFromMimeType(filter);
|
|
||||||
|
|
||||||
std::vector<CefString> ext;
|
|
||||||
CefGetExtensionsForMimeType(filter, ext);
|
|
||||||
for (size_t x = 0; x < ext.size(); ++x)
|
|
||||||
extensions.push_back("." + ext[x].ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (extensions.empty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
GtkFileFilter* gtk_filter = gtk_file_filter_new();
|
|
||||||
|
|
||||||
std::string ext_str;
|
|
||||||
for (size_t x = 0; x < extensions.size(); ++x) {
|
|
||||||
const std::string& pattern = "*" + extensions[x];
|
|
||||||
if (x != 0)
|
|
||||||
ext_str += ";";
|
|
||||||
ext_str += pattern;
|
|
||||||
gtk_file_filter_add_pattern(gtk_filter, pattern.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (description.empty())
|
|
||||||
description = ext_str;
|
|
||||||
else
|
|
||||||
description += " (" + ext_str + ")";
|
|
||||||
|
|
||||||
gtk_file_filter_set_name(gtk_filter, description.c_str());
|
|
||||||
gtk_file_chooser_add_filter(chooser, gtk_filter);
|
|
||||||
if (!has_filter)
|
|
||||||
has_filter = true;
|
|
||||||
|
|
||||||
filters->push_back(gtk_filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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_path,
|
|
||||||
const std::vector<CefString>& accept_filters,
|
|
||||||
int selected_accept_filter,
|
|
||||||
CefRefPtr<CefFileDialogCallback> callback) {
|
|
||||||
std::vector<CefString> files;
|
|
||||||
|
|
||||||
GtkFileChooserAction action;
|
|
||||||
const gchar* accept_button;
|
|
||||||
|
|
||||||
// Remove any modifier flags.
|
|
||||||
FileDialogMode mode_type =
|
|
||||||
static_cast<FileDialogMode>(mode & FILE_DIALOG_TYPE_MASK);
|
|
||||||
|
|
||||||
if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_MULTIPLE) {
|
|
||||||
action = GTK_FILE_CHOOSER_ACTION_OPEN;
|
|
||||||
accept_button = GTK_STOCK_OPEN;
|
|
||||||
} else if (mode_type == FILE_DIALOG_OPEN_FOLDER) {
|
|
||||||
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
|
|
||||||
accept_button = GTK_STOCK_OPEN;
|
|
||||||
} else if (mode_type == FILE_DIALOG_SAVE) {
|
|
||||||
action = GTK_FILE_CHOOSER_ACTION_SAVE;
|
|
||||||
accept_button = GTK_STOCK_SAVE;
|
|
||||||
} else {
|
|
||||||
NOTREACHED();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_OPEN_FOLDER:
|
|
||||||
title_str = "Open Folder";
|
|
||||||
break;
|
|
||||||
case FILE_DIALOG_SAVE:
|
|
||||||
title_str = "Save File";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget* window = gtk_widget_get_ancestor(
|
|
||||||
GTK_WIDGET(GetMainWindowHandle()), 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_type == FILE_DIALOG_OPEN_MULTIPLE)
|
|
||||||
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
|
|
||||||
|
|
||||||
if (mode_type == FILE_DIALOG_SAVE) {
|
|
||||||
gtk_file_chooser_set_do_overwrite_confirmation(
|
|
||||||
GTK_FILE_CHOOSER(dialog),
|
|
||||||
!!(mode & FILE_DIALOG_OVERWRITEPROMPT_FLAG));
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog),
|
|
||||||
!(mode & FILE_DIALOG_HIDEREADONLY_FLAG));
|
|
||||||
|
|
||||||
if (!default_file_path.empty()) {
|
|
||||||
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
|
|
||||||
default_file_path.ToString().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<GtkFileFilter*> filters;
|
|
||||||
AddFilters(GTK_FILE_CHOOSER(dialog), accept_filters, true, &filters);
|
|
||||||
if (selected_accept_filter < static_cast<int>(filters.size())) {
|
|
||||||
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog),
|
|
||||||
filters[selected_accept_filter]);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
|
|
||||||
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
|
||||||
if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_FOLDER ||
|
|
||||||
mode_type == 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_type == 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int filter_index = selected_accept_filter;
|
|
||||||
if (success) {
|
|
||||||
GtkFileFilter* selected_filter =
|
|
||||||
gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
|
|
||||||
if (selected_filter != NULL) {
|
|
||||||
for (size_t x = 0; x < filters.size(); ++x) {
|
|
||||||
if (filters[x] == selected_filter) {
|
|
||||||
filter_index = x;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_widget_destroy(dialog);
|
|
||||||
|
|
||||||
if (success)
|
|
||||||
callback->Continue(filter_index, files);
|
|
||||||
else
|
|
||||||
callback->Cancel();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
|
void ClientHandler::OnAddressChange(CefRefPtr<CefBrowser> browser,
|
||||||
CefRefPtr<CefFrame> frame,
|
CefRefPtr<CefFrame> frame,
|
||||||
const CefString& url) {
|
const CefString& url) {
|
||||||
@ -330,134 +78,6 @@ void ClientHandler::OnTitleChange(CefRefPtr<CefBrowser> browser,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ClientHandler::OnJSDialog(CefRefPtr<CefBrowser> browser,
|
|
||||||
const CefString& origin_url,
|
|
||||||
const CefString& accept_lang,
|
|
||||||
JSDialogType dialog_type,
|
|
||||||
const CefString& message_text,
|
|
||||||
const CefString& default_prompt_text,
|
|
||||||
CefRefPtr<CefJSDialogCallback> callback,
|
|
||||||
bool& suppress_message) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
|
|
||||||
GtkButtonsType buttons = GTK_BUTTONS_NONE;
|
|
||||||
GtkMessageType gtk_message_type = GTK_MESSAGE_OTHER;
|
|
||||||
std::string title;
|
|
||||||
|
|
||||||
switch (dialog_type) {
|
|
||||||
case JSDIALOGTYPE_ALERT:
|
|
||||||
buttons = GTK_BUTTONS_NONE;
|
|
||||||
gtk_message_type = GTK_MESSAGE_WARNING;
|
|
||||||
title = "JavaScript Alert";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JSDIALOGTYPE_CONFIRM:
|
|
||||||
buttons = GTK_BUTTONS_CANCEL;
|
|
||||||
gtk_message_type = GTK_MESSAGE_QUESTION;
|
|
||||||
title = "JavaScript Confirm";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JSDIALOGTYPE_PROMPT:
|
|
||||||
buttons = GTK_BUTTONS_CANCEL;
|
|
||||||
gtk_message_type = GTK_MESSAGE_QUESTION;
|
|
||||||
title = "JavaScript Prompt";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
js_dialog_callback_ = callback;
|
|
||||||
|
|
||||||
if (!origin_url.empty()) {
|
|
||||||
title += " - ";
|
|
||||||
title += origin_url.ToString();
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkWidget* window = gtk_widget_get_ancestor(
|
|
||||||
GTK_WIDGET(GetMainWindowHandle()), GTK_TYPE_WINDOW);
|
|
||||||
gtk_dialog_ = gtk_message_dialog_new(GTK_WINDOW(window),
|
|
||||||
GTK_DIALOG_MODAL,
|
|
||||||
gtk_message_type,
|
|
||||||
buttons,
|
|
||||||
"%s",
|
|
||||||
message_text.ToString().c_str());
|
|
||||||
g_signal_connect(gtk_dialog_,
|
|
||||||
"delete-event",
|
|
||||||
G_CALLBACK(gtk_widget_hide_on_delete),
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
gtk_window_set_title(GTK_WINDOW(gtk_dialog_), title.c_str());
|
|
||||||
|
|
||||||
GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_),
|
|
||||||
GTK_STOCK_OK,
|
|
||||||
GTK_RESPONSE_OK);
|
|
||||||
|
|
||||||
if (dialog_type != JSDIALOGTYPE_PROMPT)
|
|
||||||
gtk_widget_grab_focus(ok_button);
|
|
||||||
|
|
||||||
if (dialog_type == JSDIALOGTYPE_PROMPT) {
|
|
||||||
GtkWidget* content_area =
|
|
||||||
gtk_dialog_get_content_area(GTK_DIALOG(gtk_dialog_));
|
|
||||||
GtkWidget* text_box = gtk_entry_new();
|
|
||||||
gtk_entry_set_text(GTK_ENTRY(text_box),
|
|
||||||
default_prompt_text.ToString().c_str());
|
|
||||||
gtk_box_pack_start(GTK_BOX(content_area), text_box, TRUE, TRUE, 0);
|
|
||||||
g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box);
|
|
||||||
gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK);
|
|
||||||
g_signal_connect(gtk_dialog_, "response", G_CALLBACK(OnDialogResponse), this);
|
|
||||||
gtk_widget_show_all(GTK_WIDGET(gtk_dialog_));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientHandler::OnBeforeUnloadDialog(
|
|
||||||
CefRefPtr<CefBrowser> browser,
|
|
||||||
const CefString& message_text,
|
|
||||||
bool is_reload,
|
|
||||||
CefRefPtr<CefJSDialogCallback> callback) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
|
|
||||||
const std::string& new_message_text =
|
|
||||||
message_text.ToString() + "\n\nIs it OK to leave/reload this page?";
|
|
||||||
bool suppress_message = false;
|
|
||||||
|
|
||||||
return OnJSDialog(browser, CefString(), CefString(), JSDIALOGTYPE_CONFIRM,
|
|
||||||
new_message_text, CefString(), callback, suppress_message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientHandler::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
|
|
||||||
if (!gtk_dialog_)
|
|
||||||
return;
|
|
||||||
gtk_widget_destroy(gtk_dialog_);
|
|
||||||
gtk_dialog_ = NULL;
|
|
||||||
js_dialog_callback_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
void ClientHandler::OnDialogResponse(GtkDialog* dialog,
|
|
||||||
gint response_id,
|
|
||||||
ClientHandler* handler) {
|
|
||||||
CEF_REQUIRE_UI_THREAD();
|
|
||||||
|
|
||||||
DCHECK_EQ(dialog, GTK_DIALOG(handler->gtk_dialog_));
|
|
||||||
switch (response_id) {
|
|
||||||
case GTK_RESPONSE_OK:
|
|
||||||
handler->js_dialog_callback_->Continue(true, GetPromptText(dialog));
|
|
||||||
break;
|
|
||||||
case GTK_RESPONSE_CANCEL:
|
|
||||||
case GTK_RESPONSE_DELETE_EVENT:
|
|
||||||
handler->js_dialog_callback_->Continue(false, CefString());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NOTREACHED();
|
|
||||||
}
|
|
||||||
|
|
||||||
handler->OnResetDialogState(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClientHandler::SetLoading(bool isLoading) {
|
void ClientHandler::SetLoading(bool isLoading) {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
402
tests/cefclient/dialog_handler_gtk.cc
Normal file
402
tests/cefclient/dialog_handler_gtk.cc
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "cefclient/dialog_handler_gtk.h"
|
||||||
|
#include "include/cef_browser.h"
|
||||||
|
#include "include/cef_url.h"
|
||||||
|
#include "include/wrapper/cef_helpers.h"
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const char kPromptTextId[] = "cef_prompt_text";
|
||||||
|
|
||||||
|
// If there's a text entry in the dialog, get the text from the first one and
|
||||||
|
// return it.
|
||||||
|
std::string GetPromptText(GtkDialog* dialog) {
|
||||||
|
GtkWidget* widget = static_cast<GtkWidget*>(
|
||||||
|
g_object_get_data(G_OBJECT(dialog), kPromptTextId));
|
||||||
|
if (widget)
|
||||||
|
return gtk_entry_get_text(GTK_ENTRY(widget));
|
||||||
|
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 AddFilters(GtkFileChooser* chooser,
|
||||||
|
const std::vector<CefString>& accept_filters,
|
||||||
|
bool include_all_files,
|
||||||
|
std::vector<GtkFileFilter*>* filters) {
|
||||||
|
bool has_filter = false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < accept_filters.size(); ++i) {
|
||||||
|
const std::string& filter = accept_filters[i];
|
||||||
|
if (filter.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::vector<std::string> extensions;
|
||||||
|
std::string description;
|
||||||
|
|
||||||
|
size_t sep_index = filter.find('|');
|
||||||
|
if (sep_index != std::string::npos) {
|
||||||
|
// Treat as a filter of the form "Filter Name|.ext1;.ext2;.ext3".
|
||||||
|
description = filter.substr(0, sep_index);
|
||||||
|
|
||||||
|
const std::string& exts = filter.substr(sep_index + 1);
|
||||||
|
size_t last = 0;
|
||||||
|
size_t size = exts.size();
|
||||||
|
for (size_t i = 0; i <= size; ++i) {
|
||||||
|
if (i == size || exts[i] == ';') {
|
||||||
|
std::string ext(exts, last, i - last);
|
||||||
|
if (!ext.empty() && ext[0] == '.')
|
||||||
|
extensions.push_back(ext);
|
||||||
|
last = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (filter[0] == '.') {
|
||||||
|
// Treat as an extension beginning with the '.' character.
|
||||||
|
extensions.push_back(filter);
|
||||||
|
} else {
|
||||||
|
// Otherwise convert mime type to one or more extensions.
|
||||||
|
description = GetDescriptionFromMimeType(filter);
|
||||||
|
|
||||||
|
std::vector<CefString> ext;
|
||||||
|
CefGetExtensionsForMimeType(filter, ext);
|
||||||
|
for (size_t x = 0; x < ext.size(); ++x)
|
||||||
|
extensions.push_back("." + ext[x].ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extensions.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
GtkFileFilter* gtk_filter = gtk_file_filter_new();
|
||||||
|
|
||||||
|
std::string ext_str;
|
||||||
|
for (size_t x = 0; x < extensions.size(); ++x) {
|
||||||
|
const std::string& pattern = "*" + extensions[x];
|
||||||
|
if (x != 0)
|
||||||
|
ext_str += ";";
|
||||||
|
ext_str += pattern;
|
||||||
|
gtk_file_filter_add_pattern(gtk_filter, pattern.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description.empty())
|
||||||
|
description = ext_str;
|
||||||
|
else
|
||||||
|
description += " (" + ext_str + ")";
|
||||||
|
|
||||||
|
gtk_file_filter_set_name(gtk_filter, description.c_str());
|
||||||
|
gtk_file_chooser_add_filter(chooser, gtk_filter);
|
||||||
|
if (!has_filter)
|
||||||
|
has_filter = true;
|
||||||
|
|
||||||
|
filters->push_back(gtk_filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
|
||||||
|
ClientDialogHandlerGtk::ClientDialogHandlerGtk()
|
||||||
|
: gtk_parent_(NULL),
|
||||||
|
gtk_dialog_(NULL) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientDialogHandlerGtk::OnFileDialog(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
FileDialogMode mode,
|
||||||
|
const CefString& title,
|
||||||
|
const CefString& default_file_path,
|
||||||
|
const std::vector<CefString>& accept_filters,
|
||||||
|
int selected_accept_filter,
|
||||||
|
CefRefPtr<CefFileDialogCallback> callback) {
|
||||||
|
std::vector<CefString> files;
|
||||||
|
|
||||||
|
GtkFileChooserAction action;
|
||||||
|
const gchar* accept_button;
|
||||||
|
|
||||||
|
// Remove any modifier flags.
|
||||||
|
FileDialogMode mode_type =
|
||||||
|
static_cast<FileDialogMode>(mode & FILE_DIALOG_TYPE_MASK);
|
||||||
|
|
||||||
|
if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_MULTIPLE) {
|
||||||
|
action = GTK_FILE_CHOOSER_ACTION_OPEN;
|
||||||
|
accept_button = GTK_STOCK_OPEN;
|
||||||
|
} else if (mode_type == FILE_DIALOG_OPEN_FOLDER) {
|
||||||
|
action = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
|
||||||
|
accept_button = GTK_STOCK_OPEN;
|
||||||
|
} else if (mode_type == FILE_DIALOG_SAVE) {
|
||||||
|
action = GTK_FILE_CHOOSER_ACTION_SAVE;
|
||||||
|
accept_button = GTK_STOCK_SAVE;
|
||||||
|
} else {
|
||||||
|
NOTREACHED();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_OPEN_FOLDER:
|
||||||
|
title_str = "Open Folder";
|
||||||
|
break;
|
||||||
|
case FILE_DIALOG_SAVE:
|
||||||
|
title_str = "Save File";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK(gtk_parent_);
|
||||||
|
GtkWidget* window = gtk_widget_get_ancestor(
|
||||||
|
GTK_WIDGET(gtk_parent_), 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_type == FILE_DIALOG_OPEN_MULTIPLE)
|
||||||
|
gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||||
|
|
||||||
|
if (mode_type == FILE_DIALOG_SAVE) {
|
||||||
|
gtk_file_chooser_set_do_overwrite_confirmation(
|
||||||
|
GTK_FILE_CHOOSER(dialog),
|
||||||
|
!!(mode & FILE_DIALOG_OVERWRITEPROMPT_FLAG));
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog),
|
||||||
|
!(mode & FILE_DIALOG_HIDEREADONLY_FLAG));
|
||||||
|
|
||||||
|
if (!default_file_path.empty()) {
|
||||||
|
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
|
||||||
|
default_file_path.ToString().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<GtkFileFilter*> filters;
|
||||||
|
AddFilters(GTK_FILE_CHOOSER(dialog), accept_filters, true, &filters);
|
||||||
|
if (selected_accept_filter < static_cast<int>(filters.size())) {
|
||||||
|
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog),
|
||||||
|
filters[selected_accept_filter]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||||
|
if (mode_type == FILE_DIALOG_OPEN || mode_type == FILE_DIALOG_OPEN_FOLDER ||
|
||||||
|
mode_type == 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_type == 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int filter_index = selected_accept_filter;
|
||||||
|
if (success) {
|
||||||
|
GtkFileFilter* selected_filter =
|
||||||
|
gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(dialog));
|
||||||
|
if (selected_filter != NULL) {
|
||||||
|
for (size_t x = 0; x < filters.size(); ++x) {
|
||||||
|
if (filters[x] == selected_filter) {
|
||||||
|
filter_index = x;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_widget_destroy(dialog);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
callback->Continue(filter_index, files);
|
||||||
|
else
|
||||||
|
callback->Cancel();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientDialogHandlerGtk::OnJSDialog(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
const CefString& origin_url,
|
||||||
|
const CefString& accept_lang,
|
||||||
|
JSDialogType dialog_type,
|
||||||
|
const CefString& message_text,
|
||||||
|
const CefString& default_prompt_text,
|
||||||
|
CefRefPtr<CefJSDialogCallback> callback,
|
||||||
|
bool& suppress_message) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
GtkButtonsType buttons = GTK_BUTTONS_NONE;
|
||||||
|
GtkMessageType gtk_message_type = GTK_MESSAGE_OTHER;
|
||||||
|
std::string title;
|
||||||
|
|
||||||
|
switch (dialog_type) {
|
||||||
|
case JSDIALOGTYPE_ALERT:
|
||||||
|
buttons = GTK_BUTTONS_NONE;
|
||||||
|
gtk_message_type = GTK_MESSAGE_WARNING;
|
||||||
|
title = "JavaScript Alert";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSDIALOGTYPE_CONFIRM:
|
||||||
|
buttons = GTK_BUTTONS_CANCEL;
|
||||||
|
gtk_message_type = GTK_MESSAGE_QUESTION;
|
||||||
|
title = "JavaScript Confirm";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSDIALOGTYPE_PROMPT:
|
||||||
|
buttons = GTK_BUTTONS_CANCEL;
|
||||||
|
gtk_message_type = GTK_MESSAGE_QUESTION;
|
||||||
|
title = "JavaScript Prompt";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
js_dialog_callback_ = callback;
|
||||||
|
|
||||||
|
if (!origin_url.empty()) {
|
||||||
|
title += " - ";
|
||||||
|
title += origin_url.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK(gtk_parent_);
|
||||||
|
GtkWidget* window = gtk_widget_get_ancestor(
|
||||||
|
GTK_WIDGET(gtk_parent_), GTK_TYPE_WINDOW);
|
||||||
|
gtk_dialog_ = gtk_message_dialog_new(GTK_WINDOW(window),
|
||||||
|
GTK_DIALOG_MODAL,
|
||||||
|
gtk_message_type,
|
||||||
|
buttons,
|
||||||
|
"%s",
|
||||||
|
message_text.ToString().c_str());
|
||||||
|
g_signal_connect(gtk_dialog_,
|
||||||
|
"delete-event",
|
||||||
|
G_CALLBACK(gtk_widget_hide_on_delete),
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
gtk_window_set_title(GTK_WINDOW(gtk_dialog_), title.c_str());
|
||||||
|
|
||||||
|
GtkWidget* ok_button = gtk_dialog_add_button(GTK_DIALOG(gtk_dialog_),
|
||||||
|
GTK_STOCK_OK,
|
||||||
|
GTK_RESPONSE_OK);
|
||||||
|
|
||||||
|
if (dialog_type != JSDIALOGTYPE_PROMPT)
|
||||||
|
gtk_widget_grab_focus(ok_button);
|
||||||
|
|
||||||
|
if (dialog_type == JSDIALOGTYPE_PROMPT) {
|
||||||
|
GtkWidget* content_area =
|
||||||
|
gtk_dialog_get_content_area(GTK_DIALOG(gtk_dialog_));
|
||||||
|
GtkWidget* text_box = gtk_entry_new();
|
||||||
|
gtk_entry_set_text(GTK_ENTRY(text_box),
|
||||||
|
default_prompt_text.ToString().c_str());
|
||||||
|
gtk_box_pack_start(GTK_BOX(content_area), text_box, TRUE, TRUE, 0);
|
||||||
|
g_object_set_data(G_OBJECT(gtk_dialog_), kPromptTextId, text_box);
|
||||||
|
gtk_entry_set_activates_default(GTK_ENTRY(text_box), TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gtk_dialog_set_default_response(GTK_DIALOG(gtk_dialog_), GTK_RESPONSE_OK);
|
||||||
|
g_signal_connect(gtk_dialog_, "response", G_CALLBACK(OnDialogResponse), this);
|
||||||
|
gtk_widget_show_all(GTK_WIDGET(gtk_dialog_));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClientDialogHandlerGtk::OnBeforeUnloadDialog(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
const CefString& message_text,
|
||||||
|
bool is_reload,
|
||||||
|
CefRefPtr<CefJSDialogCallback> callback) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
const std::string& new_message_text =
|
||||||
|
message_text.ToString() + "\n\nIs it OK to leave/reload this page?";
|
||||||
|
bool suppress_message = false;
|
||||||
|
|
||||||
|
return OnJSDialog(browser, CefString(), CefString(), JSDIALOGTYPE_CONFIRM,
|
||||||
|
new_message_text, CefString(), callback, suppress_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClientDialogHandlerGtk::OnResetDialogState(CefRefPtr<CefBrowser> browser) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
if (!gtk_dialog_)
|
||||||
|
return;
|
||||||
|
gtk_widget_destroy(gtk_dialog_);
|
||||||
|
gtk_dialog_ = NULL;
|
||||||
|
js_dialog_callback_ = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void ClientDialogHandlerGtk::OnDialogResponse(GtkDialog* dialog,
|
||||||
|
gint response_id,
|
||||||
|
ClientDialogHandlerGtk* handler) {
|
||||||
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
|
||||||
|
DCHECK_EQ(dialog, GTK_DIALOG(handler->gtk_dialog_));
|
||||||
|
switch (response_id) {
|
||||||
|
case GTK_RESPONSE_OK:
|
||||||
|
handler->js_dialog_callback_->Continue(true, GetPromptText(dialog));
|
||||||
|
break;
|
||||||
|
case GTK_RESPONSE_CANCEL:
|
||||||
|
case GTK_RESPONSE_DELETE_EVENT:
|
||||||
|
handler->js_dialog_callback_->Continue(false, CefString());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
NOTREACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->OnResetDialogState(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
|
65
tests/cefclient/dialog_handler_gtk.h
Normal file
65
tests/cefclient/dialog_handler_gtk.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
|
||||||
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef CEF_TESTS_CEFCLIENT_DIALOG_HANDLER_GTK_H_
|
||||||
|
#define CEF_TESTS_CEFCLIENT_DIALOG_HANDLER_GTK_H_
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#include "include/cef_dialog_handler.h"
|
||||||
|
#include "include/cef_jsdialog_handler.h"
|
||||||
|
|
||||||
|
namespace client {
|
||||||
|
|
||||||
|
class ClientDialogHandlerGtk : public CefDialogHandler,
|
||||||
|
public CefJSDialogHandler {
|
||||||
|
public:
|
||||||
|
ClientDialogHandlerGtk();
|
||||||
|
|
||||||
|
// CefDialogHandler methods.
|
||||||
|
bool OnFileDialog(CefRefPtr<CefBrowser> browser,
|
||||||
|
FileDialogMode mode,
|
||||||
|
const CefString& title,
|
||||||
|
const CefString& default_file_path,
|
||||||
|
const std::vector<CefString>& accept_filters,
|
||||||
|
int selected_accept_filter,
|
||||||
|
CefRefPtr<CefFileDialogCallback> callback) OVERRIDE;
|
||||||
|
|
||||||
|
// CefJSDialogHandler methods.
|
||||||
|
bool OnJSDialog(CefRefPtr<CefBrowser> browser,
|
||||||
|
const CefString& origin_url,
|
||||||
|
const CefString& accept_lang,
|
||||||
|
JSDialogType dialog_type,
|
||||||
|
const CefString& message_text,
|
||||||
|
const CefString& default_prompt_text,
|
||||||
|
CefRefPtr<CefJSDialogCallback> callback,
|
||||||
|
bool& suppress_message) OVERRIDE;
|
||||||
|
bool OnBeforeUnloadDialog(
|
||||||
|
CefRefPtr<CefBrowser> browser,
|
||||||
|
const CefString& message_text,
|
||||||
|
bool is_reload,
|
||||||
|
CefRefPtr<CefJSDialogCallback> callback) OVERRIDE;
|
||||||
|
void OnResetDialogState(CefRefPtr<CefBrowser> browser) OVERRIDE;
|
||||||
|
|
||||||
|
void set_parent(GtkWidget* parent) {
|
||||||
|
gtk_parent_ = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void OnDialogResponse(GtkDialog *dialog,
|
||||||
|
gint response_id,
|
||||||
|
ClientDialogHandlerGtk* handler);
|
||||||
|
|
||||||
|
GtkWidget* gtk_parent_;
|
||||||
|
GtkWidget* gtk_dialog_;
|
||||||
|
CefRefPtr<CefJSDialogCallback> js_dialog_callback_;
|
||||||
|
|
||||||
|
IMPLEMENT_REFCOUNTING(ClientDialogHandlerGtk);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ClientDialogHandlerGtk);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace client
|
||||||
|
|
||||||
|
#endif // CEF_TESTS_CEFCLIENT_DIALOG_HANDLER_GTK_H_
|
@ -18,16 +18,16 @@ class ClientPrintHandlerGtk : public CefPrintHandler {
|
|||||||
public:
|
public:
|
||||||
ClientPrintHandlerGtk();
|
ClientPrintHandlerGtk();
|
||||||
|
|
||||||
// CefPrintHandler methods
|
// CefPrintHandler methods.
|
||||||
virtual void OnPrintSettings(CefRefPtr<CefPrintSettings> settings,
|
void OnPrintSettings(CefRefPtr<CefPrintSettings> settings,
|
||||||
bool get_defaults) OVERRIDE;
|
bool get_defaults) OVERRIDE;
|
||||||
virtual bool OnPrintDialog(
|
bool OnPrintDialog(
|
||||||
bool has_selection,
|
bool has_selection,
|
||||||
CefRefPtr<CefPrintDialogCallback> callback) OVERRIDE;
|
CefRefPtr<CefPrintDialogCallback> callback) OVERRIDE;
|
||||||
virtual bool OnPrintJob(const CefString& document_name,
|
bool OnPrintJob(const CefString& document_name,
|
||||||
const CefString& pdf_file_path,
|
const CefString& pdf_file_path,
|
||||||
CefRefPtr<CefPrintJobCallback> callback) OVERRIDE;
|
CefRefPtr<CefPrintJobCallback> callback) OVERRIDE;
|
||||||
virtual void OnPrintReset() OVERRIDE;
|
void OnPrintReset() OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void OnDialogResponse(GtkDialog *dialog,
|
void OnDialogResponse(GtkDialog *dialog,
|
||||||
@ -58,6 +58,7 @@ class ClientPrintHandlerGtk : public CefPrintHandler {
|
|||||||
CefRefPtr<CefPrintJobCallback> job_callback_;
|
CefRefPtr<CefPrintJobCallback> job_callback_;
|
||||||
|
|
||||||
IMPLEMENT_REFCOUNTING(ClientPrintHandlerGtk);
|
IMPLEMENT_REFCOUNTING(ClientPrintHandlerGtk);
|
||||||
|
DISALLOW_COPY_AND_ASSIGN(ClientPrintHandlerGtk);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
Loading…
x
Reference in New Issue
Block a user