1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/ui/views/renderer_context_menu/render_view_context_menu_views.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/strings/string16.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/renderer_context_menu/views/toolkit_delegate_views.h"
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/accelerators/accelerator.h"
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/events/keycodes/keyboard_codes.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderViewContextMenuViews, public:
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewContextMenuViews::RenderViewContextMenuViews(
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::RenderFrameHost* render_frame_host,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::ContextMenuParams& params)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : RenderViewContextMenu(render_frame_host, params),
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      bidi_submenu_model_(this) {
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ToolkitDelegate> delegate(new ToolkitDelegateViews);
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  set_toolkit_delegate(delegate.Pass());
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewContextMenuViews::~RenderViewContextMenuViews() {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderViewContextMenuViews* RenderViewContextMenuViews::Create(
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::RenderFrameHost* render_frame_host,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::ContextMenuParams& params) {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return new RenderViewContextMenuViews(render_frame_host, params);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid RenderViewContextMenuViews::RunMenuAt(views::Widget* parent,
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                           const gfx::Point& point,
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                           ui::MenuSourceType type) {
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static_cast<ToolkitDelegateViews*>(toolkit_delegate())->
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      RunMenuAt(parent, point, type);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderViewContextMenuViews, protected:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderViewContextMenuViews::GetAcceleratorForCommandId(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int command_id,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::Accelerator* accel) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are no formally defined accelerators we can query so we assume
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that Ctrl+C, Ctrl+V, Ctrl+X, Ctrl-A, etc do what they normally do.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (command_id) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDC_CONTENT_CONTEXT_UNDO:
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *accel = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDC_CONTENT_CONTEXT_REDO:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(jcampan): should it be Ctrl-Y?
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *accel = ui::Accelerator(ui::VKEY_Z,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDC_CONTENT_CONTEXT_CUT:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *accel = ui::Accelerator(ui::VKEY_X, ui::EF_CONTROL_DOWN);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDC_CONTENT_CONTEXT_COPY:
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *accel = ui::Accelerator(ui::VKEY_C, ui::EF_CONTROL_DOWN);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDC_CONTENT_CONTEXT_PASTE:
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *accel = ui::Accelerator(ui::VKEY_V, ui::EF_CONTROL_DOWN);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE:
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *accel = ui::Accelerator(ui::VKEY_V,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case IDC_CONTENT_CONTEXT_SELECTALL:
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *accel = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void RenderViewContextMenuViews::ExecuteCommand(int command_id,
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                                int event_flags) {
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  switch (command_id) {
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_DEFAULT:
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // WebKit's current behavior is for this menu item to always be disabled.
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NOTREACHED();
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      break;
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_RTL:
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_LTR: {
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      content::RenderViewHost* view_host = GetRenderViewHost();
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      view_host->UpdateTextDirection((command_id == IDC_WRITING_DIRECTION_RTL) ?
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebTextDirectionRightToLeft :
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebTextDirectionLeftToRight);
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      view_host->NotifyTextDirection();
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      break;
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    default:
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      RenderViewContextMenu::ExecuteCommand(command_id, event_flags);
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      break;
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool RenderViewContextMenuViews::IsCommandIdChecked(int command_id) const {
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  switch (command_id) {
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_DEFAULT:
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return (params_.writing_direction_default &
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebContextMenuData::CheckableMenuItemChecked) != 0;
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_RTL:
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return (params_.writing_direction_right_to_left &
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebContextMenuData::CheckableMenuItemChecked) != 0;
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_LTR:
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return (params_.writing_direction_left_to_right &
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebContextMenuData::CheckableMenuItemChecked) != 0;
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    default:
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return RenderViewContextMenu::IsCommandIdChecked(command_id);
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool RenderViewContextMenuViews::IsCommandIdEnabled(int command_id) const {
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  switch (command_id) {
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_MENU:
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return true;
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_DEFAULT:  // Provided to match OS defaults.
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return params_.writing_direction_default &
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebContextMenuData::CheckableMenuItemEnabled;
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_RTL:
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return params_.writing_direction_right_to_left &
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebContextMenuData::CheckableMenuItemEnabled;
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case IDC_WRITING_DIRECTION_LTR:
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return params_.writing_direction_left_to_right &
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          blink::WebContextMenuData::CheckableMenuItemEnabled;
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    default:
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return RenderViewContextMenu::IsCommandIdEnabled(command_id);
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void RenderViewContextMenuViews::AppendPlatformEditableItems() {
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bidi_submenu_model_.AddCheckItem(
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      IDC_WRITING_DIRECTION_DEFAULT,
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT));
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bidi_submenu_model_.AddCheckItem(
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      IDC_WRITING_DIRECTION_LTR,
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR));
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  bidi_submenu_model_.AddCheckItem(
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      IDC_WRITING_DIRECTION_RTL,
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL));
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  menu_model_.AddSubMenu(
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      IDC_WRITING_DIRECTION_MENU,
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU),
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      &bidi_submenu_model_);
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
170