// Copyright 2013 The Chromium 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 "content/shell/browser/shell_web_contents_view_delegate.h" #include "base/command_line.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" #include "content/public/common/context_menu_params.h" #include "content/shell/browser/shell.h" #include "content/shell/browser/shell_browser_context.h" #include "content/shell/browser/shell_browser_main_parts.h" #include "content/shell/browser/shell_content_browser_client.h" #include "content/shell/browser/shell_devtools_frontend.h" #include "content/shell/browser/shell_web_contents_view_delegate_creator.h" #include "content/shell/common/shell_switches.h" #include "third_party/WebKit/public/web/WebContextMenuData.h" #include "ui/base/gtk/focus_store_gtk.h" #include "ui/base/gtk/gtk_floating_container.h" using blink::WebContextMenuData; namespace content { WebContentsViewDelegate* CreateShellWebContentsViewDelegate( WebContents* web_contents) { return new ShellWebContentsViewDelegate(web_contents); } ShellWebContentsViewDelegate::ShellWebContentsViewDelegate( WebContents* web_contents) : web_contents_(web_contents), floating_(gtk_floating_container_new()) { } ShellWebContentsViewDelegate::~ShellWebContentsViewDelegate() { floating_.Destroy(); } void ShellWebContentsViewDelegate::ShowContextMenu( RenderFrameHost* render_frame_host, const ContextMenuParams& params) { if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) return; GtkWidget* menu = gtk_menu_new(); params_ = params; bool has_link = !params_.unfiltered_link_url.is_empty(); bool has_selection = !params_.selection_text.empty(); if (params_.media_type == WebContextMenuData::MediaTypeNone && !has_link && !has_selection && !params_.is_editable) { GtkWidget* back_menu = gtk_menu_item_new_with_label("Back"); gtk_menu_append(GTK_MENU(menu), back_menu); g_signal_connect(back_menu, "activate", G_CALLBACK(OnBackMenuActivatedThunk), this); gtk_widget_set_sensitive(back_menu, web_contents_->GetController().CanGoBack()); GtkWidget* forward_menu = gtk_menu_item_new_with_label("Forward"); gtk_menu_append(GTK_MENU(menu), forward_menu); g_signal_connect(forward_menu, "activate", G_CALLBACK(OnForwardMenuActivatedThunk), this); gtk_widget_set_sensitive(forward_menu, web_contents_->GetController().CanGoForward()); GtkWidget* reload_menu = gtk_menu_item_new_with_label("Reload"); gtk_menu_append(GTK_MENU(menu), reload_menu); g_signal_connect(reload_menu, "activate", G_CALLBACK(OnReloadMenuActivatedThunk), this); GtkWidget* navigate_separator = gtk_separator_menu_item_new(); gtk_menu_append(GTK_MENU(menu), navigate_separator); } if (has_link) { GtkWidget* open_menu = gtk_menu_item_new_with_label("Open in New Window"); gtk_menu_append(GTK_MENU(menu), open_menu); g_signal_connect(open_menu, "activate", G_CALLBACK(OnOpenURLMenuActivatedThunk), this); GtkWidget* link_separator = gtk_separator_menu_item_new(); gtk_menu_append(GTK_MENU(menu), link_separator); } if (params_.is_editable) { GtkWidget* cut_menu = gtk_menu_item_new_with_label("Cut"); gtk_menu_append(GTK_MENU(menu), cut_menu); g_signal_connect(cut_menu, "activate", G_CALLBACK(OnCutMenuActivatedThunk), this); gtk_widget_set_sensitive( cut_menu, params_.edit_flags & WebContextMenuData::CanCut); GtkWidget* copy_menu = gtk_menu_item_new_with_label("Copy"); gtk_menu_append(GTK_MENU(menu), copy_menu); g_signal_connect(copy_menu, "activate", G_CALLBACK(OnCopyMenuActivatedThunk), this); gtk_widget_set_sensitive( copy_menu, params_.edit_flags & WebContextMenuData::CanCopy); GtkWidget* paste_menu = gtk_menu_item_new_with_label("Paste"); gtk_menu_append(GTK_MENU(menu), paste_menu); g_signal_connect(paste_menu, "activate", G_CALLBACK(OnPasteMenuActivatedThunk), this); gtk_widget_set_sensitive( paste_menu, params_.edit_flags & WebContextMenuData::CanPaste); GtkWidget* delete_menu = gtk_menu_item_new_with_label("Delete"); gtk_menu_append(GTK_MENU(menu), delete_menu); g_signal_connect(delete_menu, "activate", G_CALLBACK(OnDeleteMenuActivatedThunk), this); gtk_widget_set_sensitive( delete_menu, params_.edit_flags & WebContextMenuData::CanDelete); GtkWidget* edit_separator = gtk_separator_menu_item_new(); gtk_menu_append(GTK_MENU(menu), edit_separator); } else if (has_selection) { GtkWidget* copy_menu = gtk_menu_item_new_with_label("Copy"); gtk_menu_append(GTK_MENU(menu), copy_menu); g_signal_connect(copy_menu, "activate", G_CALLBACK(OnCopyMenuActivatedThunk), this); GtkWidget* copy_separator = gtk_separator_menu_item_new(); gtk_menu_append(GTK_MENU(menu), copy_separator); } GtkWidget* inspect_menu = gtk_menu_item_new_with_label("Inspect..."); gtk_menu_append(GTK_MENU(menu), inspect_menu); g_signal_connect(inspect_menu, "activate", G_CALLBACK(OnInspectMenuActivatedThunk), this); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, GDK_CURRENT_TIME); } WebDragDestDelegate* ShellWebContentsViewDelegate::GetDragDestDelegate() { return NULL; } void ShellWebContentsViewDelegate::Initialize(GtkWidget* expanded_container, ui::FocusStoreGtk* focus_store) { expanded_container_ = expanded_container; gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_container_); gtk_widget_show(floating_.get()); } gfx::NativeView ShellWebContentsViewDelegate::GetNativeView() const { return floating_.get(); } void ShellWebContentsViewDelegate::Focus() { GtkWidget* widget = web_contents_->GetView()->GetContentNativeView(); if (widget) gtk_widget_grab_focus(widget); } gboolean ShellWebContentsViewDelegate::OnNativeViewFocusEvent( GtkWidget* widget, GtkDirectionType type, gboolean* return_value) { return false; } void ShellWebContentsViewDelegate::OnBackMenuActivated(GtkWidget* widget) { web_contents_->GetController().GoToOffset(-1); web_contents_->GetView()->Focus(); } void ShellWebContentsViewDelegate::OnForwardMenuActivated(GtkWidget* widget) { web_contents_->GetController().GoToOffset(1); web_contents_->GetView()->Focus(); } void ShellWebContentsViewDelegate::OnReloadMenuActivated(GtkWidget* widget) { web_contents_->GetController().Reload(false); web_contents_->GetView()->Focus(); } void ShellWebContentsViewDelegate::OnOpenURLMenuActivated(GtkWidget* widget) { ShellBrowserContext* browser_context = ShellContentBrowserClient::Get()->browser_context(); Shell::CreateNewWindow(browser_context, params_.link_url, NULL, MSG_ROUTING_NONE, gfx::Size()); } void ShellWebContentsViewDelegate::OnCutMenuActivated(GtkWidget* widget) { RenderFrameHost* frame = web_contents_->GetFocusedFrame(); if (frame) frame->Cut(); } void ShellWebContentsViewDelegate::OnCopyMenuActivated(GtkWidget* widget) { RenderFrameHost* frame = web_contents_->GetFocusedFrame(); if (frame) frame->Copy(); } void ShellWebContentsViewDelegate::OnPasteMenuActivated(GtkWidget* widget) { RenderFrameHost* frame = web_contents_->GetFocusedFrame(); if (frame) frame->Paste(); } void ShellWebContentsViewDelegate::OnDeleteMenuActivated(GtkWidget* widget) { web_contents_->GetRenderViewHost()->Delete(); } void ShellWebContentsViewDelegate::OnInspectMenuActivated(GtkWidget* widget) { ShellDevToolsFrontend::Show(web_contents_); } } // namespace content