render_view_context_menu_views.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.h" 6 7#include "base/logging.h" 8#include "base/strings/utf_string_conversions.h" 9#include "chrome/app/chrome_command_ids.h" 10#include "content/public/browser/render_view_host.h" 11#include "content/public/browser/render_widget_host_view.h" 12#include "content/public/browser/web_contents.h" 13#include "content/public/browser/web_contents_view.h" 14#include "grit/generated_resources.h" 15#include "ui/base/accelerators/accelerator.h" 16#include "ui/base/l10n/l10n_util.h" 17#include "ui/events/keycodes/keyboard_codes.h" 18#include "ui/gfx/point.h" 19#include "ui/views/controls/menu/menu_item_view.h" 20#include "ui/views/controls/menu/menu_runner.h" 21 22 23using content::WebContents; 24 25//////////////////////////////////////////////////////////////////////////////// 26// RenderViewContextMenuViews, public: 27 28RenderViewContextMenuViews::RenderViewContextMenuViews( 29 content::RenderFrameHost* render_frame_host, 30 const content::ContextMenuParams& params) 31 : RenderViewContextMenu(render_frame_host, params), 32 bidi_submenu_model_(this) { 33} 34 35RenderViewContextMenuViews::~RenderViewContextMenuViews() { 36} 37 38#if !defined(OS_WIN) 39// static 40RenderViewContextMenuViews* RenderViewContextMenuViews::Create( 41 content::RenderFrameHost* render_frame_host, 42 const content::ContextMenuParams& params) { 43 return new RenderViewContextMenuViews(render_frame_host, params); 44} 45#endif // OS_WIN 46 47void RenderViewContextMenuViews::RunMenuAt(views::Widget* parent, 48 const gfx::Point& point, 49 ui::MenuSourceType type) { 50 views::MenuItemView::AnchorPosition anchor_position = 51 (type == ui::MENU_SOURCE_TOUCH || 52 type == ui::MENU_SOURCE_TOUCH_EDIT_MENU) ? 53 views::MenuItemView::BOTTOMCENTER : views::MenuItemView::TOPLEFT; 54 55 if (menu_runner_->RunMenuAt(parent, NULL, gfx::Rect(point, gfx::Size()), 56 anchor_position, type, views::MenuRunner::HAS_MNEMONICS | 57 views::MenuRunner::CONTEXT_MENU) == 58 views::MenuRunner::MENU_DELETED) 59 return; 60} 61 62//////////////////////////////////////////////////////////////////////////////// 63// RenderViewContextMenuViews, protected: 64 65void RenderViewContextMenuViews::PlatformInit() { 66 menu_runner_.reset(new views::MenuRunner(&menu_model_)); 67} 68 69void RenderViewContextMenuViews::PlatformCancel() { 70 DCHECK(menu_runner_.get()); 71 menu_runner_->Cancel(); 72} 73 74bool RenderViewContextMenuViews::GetAcceleratorForCommandId( 75 int command_id, 76 ui::Accelerator* accel) { 77 // There are no formally defined accelerators we can query so we assume 78 // that Ctrl+C, Ctrl+V, Ctrl+X, Ctrl-A, etc do what they normally do. 79 switch (command_id) { 80 case IDC_CONTENT_CONTEXT_UNDO: 81 *accel = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN); 82 return true; 83 84 case IDC_CONTENT_CONTEXT_REDO: 85 // TODO(jcampan): should it be Ctrl-Y? 86 *accel = ui::Accelerator(ui::VKEY_Z, 87 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); 88 return true; 89 90 case IDC_CONTENT_CONTEXT_CUT: 91 *accel = ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN); 92 return true; 93 94 case IDC_CONTENT_CONTEXT_COPY: 95 *accel = ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN); 96 return true; 97 98 case IDC_CONTENT_CONTEXT_PASTE: 99 *accel = ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN); 100 return true; 101 102 case IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE: 103 *accel = ui::Accelerator(ui::VKEY_V, 104 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN); 105 return true; 106 107 case IDC_CONTENT_CONTEXT_SELECTALL: 108 *accel = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN); 109 return true; 110 111 default: 112 return false; 113 } 114} 115 116void RenderViewContextMenuViews::ExecuteCommand(int command_id, 117 int event_flags) { 118 switch (command_id) { 119 case IDC_WRITING_DIRECTION_DEFAULT: 120 // WebKit's current behavior is for this menu item to always be disabled. 121 NOTREACHED(); 122 break; 123 124 case IDC_WRITING_DIRECTION_RTL: 125 case IDC_WRITING_DIRECTION_LTR: { 126 content::RenderViewHost* view_host = GetRenderViewHost(); 127 view_host->UpdateTextDirection((command_id == IDC_WRITING_DIRECTION_RTL) ? 128 blink::WebTextDirectionRightToLeft : 129 blink::WebTextDirectionLeftToRight); 130 view_host->NotifyTextDirection(); 131 break; 132 } 133 134 default: 135 RenderViewContextMenu::ExecuteCommand(command_id, event_flags); 136 break; 137 } 138} 139 140bool RenderViewContextMenuViews::IsCommandIdChecked(int command_id) const { 141 switch (command_id) { 142 case IDC_WRITING_DIRECTION_DEFAULT: 143 return (params_.writing_direction_default & 144 blink::WebContextMenuData::CheckableMenuItemChecked) != 0; 145 case IDC_WRITING_DIRECTION_RTL: 146 return (params_.writing_direction_right_to_left & 147 blink::WebContextMenuData::CheckableMenuItemChecked) != 0; 148 case IDC_WRITING_DIRECTION_LTR: 149 return (params_.writing_direction_left_to_right & 150 blink::WebContextMenuData::CheckableMenuItemChecked) != 0; 151 152 default: 153 return RenderViewContextMenu::IsCommandIdChecked(command_id); 154 } 155} 156 157bool RenderViewContextMenuViews::IsCommandIdEnabled(int command_id) const { 158 switch (command_id) { 159 case IDC_WRITING_DIRECTION_MENU: 160 return true; 161 case IDC_WRITING_DIRECTION_DEFAULT: // Provided to match OS defaults. 162 return params_.writing_direction_default & 163 blink::WebContextMenuData::CheckableMenuItemEnabled; 164 case IDC_WRITING_DIRECTION_RTL: 165 return params_.writing_direction_right_to_left & 166 blink::WebContextMenuData::CheckableMenuItemEnabled; 167 case IDC_WRITING_DIRECTION_LTR: 168 return params_.writing_direction_left_to_right & 169 blink::WebContextMenuData::CheckableMenuItemEnabled; 170 171 default: 172 return RenderViewContextMenu::IsCommandIdEnabled(command_id); 173 } 174} 175 176void RenderViewContextMenuViews::AppendPlatformEditableItems() { 177 bidi_submenu_model_.AddCheckItem( 178 IDC_WRITING_DIRECTION_DEFAULT, 179 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT)); 180 bidi_submenu_model_.AddCheckItem( 181 IDC_WRITING_DIRECTION_LTR, 182 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR)); 183 bidi_submenu_model_.AddCheckItem( 184 IDC_WRITING_DIRECTION_RTL, 185 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL)); 186 187 menu_model_.AddSubMenu( 188 IDC_WRITING_DIRECTION_MENU, 189 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU), 190 &bidi_submenu_model_); 191} 192 193void RenderViewContextMenuViews::UpdateMenuItem(int command_id, 194 bool enabled, 195 bool hidden, 196 const base::string16& title) { 197 views::MenuItemView* item = 198 menu_runner_->GetMenu()->GetMenuItemByID(command_id); 199 if (!item) 200 return; 201 202 item->SetEnabled(enabled); 203 item->SetTitle(title); 204 item->SetVisible(!hidden); 205 206 views::MenuItemView* parent = item->GetParentMenuItem(); 207 if (!parent) 208 return; 209 210 parent->ChildrenChanged(); 211} 212