1 // Copyright (c) 2012 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/tab_contents/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 "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"
23 using content::WebContents
;
25 ////////////////////////////////////////////////////////////////////////////////
26 // RenderViewContextMenuViews, public:
28 RenderViewContextMenuViews::RenderViewContextMenuViews(
29 WebContents
* web_contents
,
30 const content::ContextMenuParams
& params
)
31 : RenderViewContextMenu(web_contents
, params
),
32 bidi_submenu_model_(this) {
35 RenderViewContextMenuViews::~RenderViewContextMenuViews() {
40 RenderViewContextMenuViews
* RenderViewContextMenuViews::Create(
41 content::WebContents
* web_contents
,
42 const content::ContextMenuParams
& params
) {
43 return new RenderViewContextMenuViews(web_contents
, params
);
47 void 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
;
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
)
62 ////////////////////////////////////////////////////////////////////////////////
63 // RenderViewContextMenuViews, protected:
65 void RenderViewContextMenuViews::PlatformInit() {
66 menu_runner_
.reset(new views::MenuRunner(&menu_model_
));
69 void RenderViewContextMenuViews::PlatformCancel() {
70 DCHECK(menu_runner_
.get());
71 menu_runner_
->Cancel();
74 bool RenderViewContextMenuViews::GetAcceleratorForCommandId(
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.
80 case IDC_CONTENT_CONTEXT_UNDO
:
81 *accel
= ui::Accelerator(ui::VKEY_Z
, ui::EF_CONTROL_DOWN
);
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
);
90 case IDC_CONTENT_CONTEXT_CUT
:
91 *accel
= ui::Accelerator(ui::VKEY_X
, ui::EF_CONTROL_DOWN
);
94 case IDC_CONTENT_CONTEXT_COPY
:
95 *accel
= ui::Accelerator(ui::VKEY_C
, ui::EF_CONTROL_DOWN
);
98 case IDC_CONTENT_CONTEXT_PASTE
:
99 *accel
= ui::Accelerator(ui::VKEY_V
, ui::EF_CONTROL_DOWN
);
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
);
107 case IDC_CONTENT_CONTEXT_SELECTALL
:
108 *accel
= ui::Accelerator(ui::VKEY_A
, ui::EF_CONTROL_DOWN
);
116 void RenderViewContextMenuViews::ExecuteCommand(int command_id
,
118 switch (command_id
) {
119 case IDC_WRITING_DIRECTION_DEFAULT
:
120 // WebKit's current behavior is for this menu item to always be disabled.
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();
135 RenderViewContextMenu::ExecuteCommand(command_id
, event_flags
);
140 bool 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;
153 return RenderViewContextMenu::IsCommandIdChecked(command_id
);
157 bool RenderViewContextMenuViews::IsCommandIdEnabled(int command_id
) const {
158 switch (command_id
) {
159 case IDC_WRITING_DIRECTION_MENU
:
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
;
172 return RenderViewContextMenu::IsCommandIdEnabled(command_id
);
176 void 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
));
187 menu_model_
.AddSubMenu(
188 IDC_WRITING_DIRECTION_MENU
,
189 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU
),
190 &bidi_submenu_model_
);
193 void RenderViewContextMenuViews::UpdateMenuItem(int command_id
,
196 const base::string16
& title
) {
197 views::MenuItemView
* item
=
198 menu_runner_
->GetMenu()->GetMenuItemByID(command_id
);
202 item
->SetEnabled(enabled
);
203 item
->SetTitle(title
);
204 item
->SetVisible(!hidden
);
206 views::MenuItemView
* parent
= item
->GetParentMenuItem();
210 parent
->ChildrenChanged();