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.
5 #include "chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.h"
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 "grit/generated_resources.h"
14 #include "ui/base/accelerators/accelerator.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/events/keycodes/keyboard_codes.h"
17 #include "ui/gfx/point.h"
18 #include "ui/views/controls/menu/menu_item_view.h"
19 #include "ui/views/controls/menu/menu_runner.h"
21 using content::WebContents;
23 ////////////////////////////////////////////////////////////////////////////////
24 // RenderViewContextMenuViews, public:
26 RenderViewContextMenuViews::RenderViewContextMenuViews(
27 content::RenderFrameHost* render_frame_host,
28 const content::ContextMenuParams& params)
29 : RenderViewContextMenu(render_frame_host, params),
30 bidi_submenu_model_(this) {
33 RenderViewContextMenuViews::~RenderViewContextMenuViews() {
37 RenderViewContextMenuViews* RenderViewContextMenuViews::Create(
38 content::RenderFrameHost* render_frame_host,
39 const content::ContextMenuParams& params) {
40 return new RenderViewContextMenuViews(render_frame_host, params);
43 void RenderViewContextMenuViews::RunMenuAt(views::Widget* parent,
44 const gfx::Point& point,
45 ui::MenuSourceType type) {
46 views::MenuAnchorPosition anchor_position =
47 (type == ui::MENU_SOURCE_TOUCH || type == ui::MENU_SOURCE_TOUCH_EDIT_MENU)
48 ? views::MENU_ANCHOR_BOTTOMCENTER
49 : views::MENU_ANCHOR_TOPLEFT;
51 if (menu_runner_->RunMenuAt(parent, NULL, gfx::Rect(point, gfx::Size()),
52 anchor_position, type, views::MenuRunner::HAS_MNEMONICS |
53 views::MenuRunner::CONTEXT_MENU) ==
54 views::MenuRunner::MENU_DELETED)
58 ////////////////////////////////////////////////////////////////////////////////
59 // RenderViewContextMenuViews, protected:
61 void RenderViewContextMenuViews::PlatformInit() {
62 menu_runner_.reset(new views::MenuRunner(&menu_model_));
65 void RenderViewContextMenuViews::PlatformCancel() {
66 DCHECK(menu_runner_.get());
67 menu_runner_->Cancel();
70 bool RenderViewContextMenuViews::GetAcceleratorForCommandId(
72 ui::Accelerator* accel) {
73 // There are no formally defined accelerators we can query so we assume
74 // that Ctrl+C, Ctrl+V, Ctrl+X, Ctrl-A, etc do what they normally do.
76 case IDC_CONTENT_CONTEXT_UNDO:
77 *accel = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN);
80 case IDC_CONTENT_CONTEXT_REDO:
81 // TODO(jcampan): should it be Ctrl-Y?
82 *accel = ui::Accelerator(ui::VKEY_Z,
83 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
86 case IDC_CONTENT_CONTEXT_CUT:
87 *accel = ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN);
90 case IDC_CONTENT_CONTEXT_COPY:
91 *accel = ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN);
94 case IDC_CONTENT_CONTEXT_PASTE:
95 *accel = ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN);
98 case IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE:
99 *accel = ui::Accelerator(ui::VKEY_V,
100 ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
103 case IDC_CONTENT_CONTEXT_SELECTALL:
104 *accel = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN);
112 void RenderViewContextMenuViews::ExecuteCommand(int command_id,
114 switch (command_id) {
115 case IDC_WRITING_DIRECTION_DEFAULT:
116 // WebKit's current behavior is for this menu item to always be disabled.
120 case IDC_WRITING_DIRECTION_RTL:
121 case IDC_WRITING_DIRECTION_LTR: {
122 content::RenderViewHost* view_host = GetRenderViewHost();
123 view_host->UpdateTextDirection((command_id == IDC_WRITING_DIRECTION_RTL) ?
124 blink::WebTextDirectionRightToLeft :
125 blink::WebTextDirectionLeftToRight);
126 view_host->NotifyTextDirection();
131 RenderViewContextMenu::ExecuteCommand(command_id, event_flags);
136 bool RenderViewContextMenuViews::IsCommandIdChecked(int command_id) const {
137 switch (command_id) {
138 case IDC_WRITING_DIRECTION_DEFAULT:
139 return (params_.writing_direction_default &
140 blink::WebContextMenuData::CheckableMenuItemChecked) != 0;
141 case IDC_WRITING_DIRECTION_RTL:
142 return (params_.writing_direction_right_to_left &
143 blink::WebContextMenuData::CheckableMenuItemChecked) != 0;
144 case IDC_WRITING_DIRECTION_LTR:
145 return (params_.writing_direction_left_to_right &
146 blink::WebContextMenuData::CheckableMenuItemChecked) != 0;
149 return RenderViewContextMenu::IsCommandIdChecked(command_id);
153 bool RenderViewContextMenuViews::IsCommandIdEnabled(int command_id) const {
154 switch (command_id) {
155 case IDC_WRITING_DIRECTION_MENU:
157 case IDC_WRITING_DIRECTION_DEFAULT: // Provided to match OS defaults.
158 return params_.writing_direction_default &
159 blink::WebContextMenuData::CheckableMenuItemEnabled;
160 case IDC_WRITING_DIRECTION_RTL:
161 return params_.writing_direction_right_to_left &
162 blink::WebContextMenuData::CheckableMenuItemEnabled;
163 case IDC_WRITING_DIRECTION_LTR:
164 return params_.writing_direction_left_to_right &
165 blink::WebContextMenuData::CheckableMenuItemEnabled;
168 return RenderViewContextMenu::IsCommandIdEnabled(command_id);
172 void RenderViewContextMenuViews::AppendPlatformEditableItems() {
173 bidi_submenu_model_.AddCheckItem(
174 IDC_WRITING_DIRECTION_DEFAULT,
175 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT));
176 bidi_submenu_model_.AddCheckItem(
177 IDC_WRITING_DIRECTION_LTR,
178 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR));
179 bidi_submenu_model_.AddCheckItem(
180 IDC_WRITING_DIRECTION_RTL,
181 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL));
183 menu_model_.AddSubMenu(
184 IDC_WRITING_DIRECTION_MENU,
185 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU),
186 &bidi_submenu_model_);
189 void RenderViewContextMenuViews::UpdateMenuItem(int command_id,
192 const base::string16& title) {
193 views::MenuItemView* item =
194 menu_runner_->GetMenu()->GetMenuItemByID(command_id);
198 item->SetEnabled(enabled);
199 item->SetTitle(title);
200 item->SetVisible(!hidden);
202 views::MenuItemView* parent = item->GetParentMenuItem();
206 parent->ChildrenChanged();