Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / renderer_context_menu / render_view_context_menu_views.cc
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 "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"
20
21 using content::WebContents;
22
23 ////////////////////////////////////////////////////////////////////////////////
24 // RenderViewContextMenuViews, public:
25
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) {
31 }
32
33 RenderViewContextMenuViews::~RenderViewContextMenuViews() {
34 }
35
36 // static
37 RenderViewContextMenuViews* RenderViewContextMenuViews::Create(
38     content::RenderFrameHost* render_frame_host,
39     const content::ContextMenuParams& params) {
40   return new RenderViewContextMenuViews(render_frame_host, params);
41 }
42
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;
50
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)
55     return;
56 }
57
58 ////////////////////////////////////////////////////////////////////////////////
59 // RenderViewContextMenuViews, protected:
60
61 void RenderViewContextMenuViews::PlatformInit() {
62   menu_runner_.reset(new views::MenuRunner(&menu_model_));
63 }
64
65 void RenderViewContextMenuViews::PlatformCancel() {
66   DCHECK(menu_runner_.get());
67   menu_runner_->Cancel();
68 }
69
70 bool RenderViewContextMenuViews::GetAcceleratorForCommandId(
71     int command_id,
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.
75   switch (command_id) {
76     case IDC_CONTENT_CONTEXT_UNDO:
77       *accel = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN);
78       return true;
79
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);
84       return true;
85
86     case IDC_CONTENT_CONTEXT_CUT:
87       *accel = ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN);
88       return true;
89
90     case IDC_CONTENT_CONTEXT_COPY:
91       *accel = ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN);
92       return true;
93
94     case IDC_CONTENT_CONTEXT_PASTE:
95       *accel = ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN);
96       return true;
97
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);
101       return true;
102
103     case IDC_CONTENT_CONTEXT_SELECTALL:
104       *accel = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN);
105       return true;
106
107     default:
108       return false;
109   }
110 }
111
112 void RenderViewContextMenuViews::ExecuteCommand(int command_id,
113                                                 int event_flags) {
114   switch (command_id) {
115     case IDC_WRITING_DIRECTION_DEFAULT:
116       // WebKit's current behavior is for this menu item to always be disabled.
117       NOTREACHED();
118       break;
119
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();
127       break;
128     }
129
130     default:
131       RenderViewContextMenu::ExecuteCommand(command_id, event_flags);
132       break;
133   }
134 }
135
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;
147
148     default:
149       return RenderViewContextMenu::IsCommandIdChecked(command_id);
150   }
151 }
152
153 bool RenderViewContextMenuViews::IsCommandIdEnabled(int command_id) const {
154   switch (command_id) {
155     case IDC_WRITING_DIRECTION_MENU:
156       return true;
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;
166
167     default:
168       return RenderViewContextMenu::IsCommandIdEnabled(command_id);
169   }
170 }
171
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));
182
183   menu_model_.AddSubMenu(
184       IDC_WRITING_DIRECTION_MENU,
185       l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU),
186       &bidi_submenu_model_);
187 }
188
189 void RenderViewContextMenuViews::UpdateMenuItem(int command_id,
190                                                 bool enabled,
191                                                 bool hidden,
192                                                 const base::string16& title) {
193   views::MenuItemView* item =
194       menu_runner_->GetMenu()->GetMenuItemByID(command_id);
195   if (!item)
196     return;
197
198   item->SetEnabled(enabled);
199   item->SetTitle(title);
200   item->SetVisible(!hidden);
201
202   views::MenuItemView* parent = item->GetParentMenuItem();
203   if (!parent)
204     return;
205
206   parent->ChildrenChanged();
207 }