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 "athena/content/render_view_context_menu_impl.h"
6
7#include "athena/strings/grit/athena_strings.h"
8#include "components/renderer_context_menu/context_menu_content_type.h"
9#include "components/renderer_context_menu/views/toolkit_delegate_views.h"
10#include "content/public/browser/browser_context.h"
11#include "content/public/browser/web_contents.h"
12#include "third_party/WebKit/public/web/WebContextMenuData.h"
13#include "ui/base/l10n/l10n_util.h"
14
15namespace athena {
16using blink::WebContextMenuData;
17
18namespace {
19
20enum {
21  // Nativation
22  CMD_BACK = 0,
23  CMD_FORWARD,
24  CMD_RELOAD,
25  CMD_VIEW_SOURCE,
26
27  // Link
28  CMD_OPEN_LINK_NEW_ACTIVITY,
29
30  // Edit
31  CMD_UNDO,
32  CMD_REDO,
33  CMD_CUT,
34  CMD_COPY,
35  CMD_PASTE,
36  CMD_PASTE_AND_MATCH_STYLE,
37  CMD_DELETE,
38  CMD_SELECT_ALL,
39  CMD_LAST,
40};
41
42// Max number of custom command ids allowd.
43const int kNumCustomCommandIds = 1000;
44
45// TODO(oshima): Move IDS for context menus to components/renderer_context_menu
46// and replace hardcoded strings below.
47void AppendPageItems(ui::SimpleMenuModel* menu_model) {
48  menu_model->AddItem(CMD_BACK,
49                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_BACK));
50  menu_model->AddItem(CMD_FORWARD,
51                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_FORWARD));
52  menu_model->AddItem(CMD_RELOAD,
53                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_RELOAD));
54  menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
55  menu_model->AddItem(
56      CMD_VIEW_SOURCE,
57      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_VIEWPAGESOURCE));
58}
59
60void AppendLinkItems(const content::ContextMenuParams& params,
61                     ui::SimpleMenuModel* menu_model) {
62  if (!params.link_url.is_empty())
63    menu_model->AddItem(
64        CMD_OPEN_LINK_NEW_ACTIVITY,
65        l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_OPENLINKNEWACTIVITY));
66}
67
68void AppendEditableItems(ui::SimpleMenuModel* menu_model) {
69  menu_model->AddItem(CMD_UNDO,
70                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_UNDO));
71  menu_model->AddItem(CMD_REDO,
72                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_REDO));
73  menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
74  menu_model->AddItem(CMD_CUT,
75                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_CUT));
76  menu_model->AddItem(CMD_COPY,
77                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_COPY));
78  menu_model->AddItem(CMD_PASTE,
79                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_PASTE));
80  menu_model->AddItem(
81      CMD_PASTE_AND_MATCH_STYLE,
82      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_PASTE_AND_MATCH_STYLE));
83  menu_model->AddItem(CMD_DELETE,
84                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_DELETE));
85  menu_model->AddSeparator(ui::NORMAL_SEPARATOR);
86  menu_model->AddItem(CMD_SELECT_ALL,
87                      l10n_util::GetStringUTF16(IDS_ATHENA_CONTEXT_SELECTALL));
88}
89
90}  // namespace
91
92RenderViewContextMenuImpl::RenderViewContextMenuImpl(
93    content::RenderFrameHost* render_frame_host,
94    const content::ContextMenuParams& params)
95    : RenderViewContextMenuBase(render_frame_host, params) {
96  SetContentCustomCommandIdRange(CMD_LAST, CMD_LAST + kNumCustomCommandIds);
97  // TODO(oshima): Support other types
98  set_content_type(
99      new ContextMenuContentType(source_web_contents_, params, true));
100  set_toolkit_delegate(scoped_ptr<ToolkitDelegate>(new ToolkitDelegateViews));
101}
102
103RenderViewContextMenuImpl::~RenderViewContextMenuImpl() {
104}
105
106void RenderViewContextMenuImpl::RunMenuAt(views::Widget* parent,
107                                          const gfx::Point& point,
108                                          ui::MenuSourceType type) {
109  static_cast<ToolkitDelegateViews*>(toolkit_delegate())
110      ->RunMenuAt(parent, point, type);
111}
112
113void RenderViewContextMenuImpl::InitMenu() {
114  RenderViewContextMenuBase::InitMenu();
115  bool needs_separator = false;
116  if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_PAGE)) {
117    AppendPageItems(&menu_model_);
118    needs_separator = true;
119  }
120
121  if (content_type_->SupportsGroup(ContextMenuContentType::ITEM_GROUP_LINK)) {
122    if (needs_separator)
123      AddSeparator();
124    AppendLinkItems(params_, &menu_model_);
125    needs_separator = true;
126  }
127
128  if (content_type_->SupportsGroup(
129          ContextMenuContentType::ITEM_GROUP_EDITABLE)) {
130    if (needs_separator)
131      AddSeparator();
132    AppendEditableItems(&menu_model_);
133  }
134}
135
136void RenderViewContextMenuImpl::RecordShownItem(int id) {
137  // TODO(oshima): Imelement UMA stats. crbug.com/401673
138  NOTIMPLEMENTED();
139}
140
141void RenderViewContextMenuImpl::RecordUsedItem(int id) {
142  // TODO(oshima): Imelement UMA stats. crbug.com/401673
143  NOTIMPLEMENTED();
144}
145
146#if defined(ENABLE_PLUGINS)
147void RenderViewContextMenuImpl::HandleAuthorizeAllPlugins() {
148}
149#endif
150
151void RenderViewContextMenuImpl::NotifyMenuShown() {
152}
153
154void RenderViewContextMenuImpl::NotifyURLOpened(
155    const GURL& url,
156    content::WebContents* new_contents) {
157}
158
159bool RenderViewContextMenuImpl::GetAcceleratorForCommandId(
160    int command_id,
161    ui::Accelerator* accelerator) {
162  NOTIMPLEMENTED();
163  return false;
164}
165
166bool RenderViewContextMenuImpl::IsCommandIdChecked(int command_id) const {
167  return false;
168}
169
170bool RenderViewContextMenuImpl::IsCommandIdEnabled(int command_id) const {
171  {
172    bool enabled = false;
173    if (RenderViewContextMenuBase::IsCommandIdKnown(command_id, &enabled))
174      return enabled;
175  }
176  switch (command_id) {
177    // Navigation
178    case CMD_BACK:
179      return source_web_contents_->GetController().CanGoBack();
180    case CMD_FORWARD:
181      return source_web_contents_->GetController().CanGoForward();
182    case CMD_RELOAD:
183      return true;
184    case CMD_VIEW_SOURCE:
185      return source_web_contents_->GetController().CanViewSource();
186
187    // Link
188    case CMD_OPEN_LINK_NEW_ACTIVITY:
189      return params_.link_url.is_valid();
190
191    // Editable
192    case CMD_UNDO:
193      return !!(params_.edit_flags & WebContextMenuData::CanUndo);
194
195    case CMD_REDO:
196      return !!(params_.edit_flags & WebContextMenuData::CanRedo);
197
198    case CMD_CUT:
199      return !!(params_.edit_flags & WebContextMenuData::CanCut);
200
201    case CMD_COPY:
202      return !!(params_.edit_flags & WebContextMenuData::CanCopy);
203
204    case CMD_PASTE:
205    case CMD_PASTE_AND_MATCH_STYLE:
206      return !!(params_.edit_flags & WebContextMenuData::CanPaste);
207
208    case CMD_DELETE:
209      return !!(params_.edit_flags & WebContextMenuData::CanDelete);
210
211    case CMD_SELECT_ALL:
212      return !!(params_.edit_flags & WebContextMenuData::CanSelectAll);
213  }
214  return false;
215}
216
217void RenderViewContextMenuImpl::ExecuteCommand(int command_id,
218                                               int event_flags) {
219  RenderViewContextMenuBase::ExecuteCommand(command_id, event_flags);
220  if (command_executed_)
221    return;
222  command_executed_ = true;
223  switch (command_id) {
224    // Navigation
225    case CMD_BACK:
226      source_web_contents_->GetController().GoBack();
227      break;
228    case CMD_FORWARD:
229      source_web_contents_->GetController().GoForward();
230      break;
231    case CMD_RELOAD:
232      source_web_contents_->GetController().Reload(true);
233      break;
234    case CMD_VIEW_SOURCE:
235      source_web_contents_->ViewSource();
236      break;
237
238    // Link
239    case CMD_OPEN_LINK_NEW_ACTIVITY:
240      OpenURL(
241          params_.link_url,
242          params_.frame_url.is_empty() ? params_.page_url : params_.frame_url,
243          NEW_FOREGROUND_TAB,
244          ui::PAGE_TRANSITION_LINK);
245      break;
246
247    // Editable
248    case CMD_UNDO:
249      source_web_contents_->Undo();
250      break;
251
252    case CMD_REDO:
253      source_web_contents_->Redo();
254      break;
255
256    case CMD_CUT:
257      source_web_contents_->Cut();
258      break;
259
260    case CMD_COPY:
261      source_web_contents_->Copy();
262      break;
263
264    case CMD_PASTE:
265      source_web_contents_->Paste();
266      break;
267
268    case CMD_PASTE_AND_MATCH_STYLE:
269      source_web_contents_->PasteAndMatchStyle();
270      break;
271
272    case CMD_DELETE:
273      source_web_contents_->Delete();
274      break;
275
276    case CMD_SELECT_ALL:
277      source_web_contents_->SelectAll();
278      break;
279  }
280}
281
282}  // namespace athena
283