Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / tab_contents / render_view_context_menu_views.cc
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.
4
5 #include "chrome/browser/ui/views/tab_contents/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
23 using content::WebContents;
24
25 ////////////////////////////////////////////////////////////////////////////////
26 // RenderViewContextMenuViews, public:
27
28 RenderViewContextMenuViews::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
35 RenderViewContextMenuViews::~RenderViewContextMenuViews() {
36 }
37
38 #if !defined(OS_WIN)
39 // static
40 RenderViewContextMenuViews* 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
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;
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
65 void RenderViewContextMenuViews::PlatformInit() {
66   menu_runner_.reset(new views::MenuRunner(&menu_model_));
67 }
68
69 void RenderViewContextMenuViews::PlatformCancel() {
70   DCHECK(menu_runner_.get());
71   menu_runner_->Cancel();
72 }
73
74 bool 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
116 void 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
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;
151
152     default:
153       return RenderViewContextMenu::IsCommandIdChecked(command_id);
154   }
155 }
156
157 bool 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
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));
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
193 void 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 }