render_view_context_menu_mac.mm revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 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/tab_contents/render_view_context_menu_mac.h"
6
7#include "base/compiler_specific.h"
8#include "base/message_loop.h"
9#include "base/scoped_nsobject.h"
10#include "base/sys_string_conversions.h"
11#include "chrome/app/chrome_dll_resource.h"
12#import "chrome/browser/cocoa/menu_controller.h"
13#include "grit/generated_resources.h"
14
15// Obj-C bridge class that is the target of all items in the context menu.
16// Relies on the tag being set to the command id.
17
18RenderViewContextMenuMac::RenderViewContextMenuMac(
19    TabContents* web_contents,
20    const ContextMenuParams& params,
21    NSView* parent_view)
22    : RenderViewContextMenu(web_contents, params),
23      parent_view_(parent_view) {
24}
25
26RenderViewContextMenuMac::~RenderViewContextMenuMac() {
27}
28
29void RenderViewContextMenuMac::PlatformInit() {
30  InitPlatformMenu();
31  menuController_.reset(
32      [[MenuController alloc] initWithModel:&menu_model_
33                     useWithPopUpButtonCell:NO]);
34
35  // Synthesize an event for the click, as there is no certainty that
36  // [NSApp currentEvent] will return a valid event.
37  NSEvent* currentEvent = [NSApp currentEvent];
38  NSWindow* window = [parent_view_ window];
39  NSPoint position = [window mouseLocationOutsideOfEventStream];
40  NSTimeInterval eventTime = [currentEvent timestamp];
41  NSEvent* clickEvent = [NSEvent mouseEventWithType:NSRightMouseDown
42                                           location:position
43                                      modifierFlags:NSRightMouseDownMask
44                                          timestamp:eventTime
45                                       windowNumber:[window windowNumber]
46                                            context:nil
47                                        eventNumber:0
48                                         clickCount:1
49                                           pressure:1.0];
50
51  {
52    // Make sure events can be pumped while the menu is up.
53    MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
54
55    // Show the menu.
56    [NSMenu popUpContextMenu:[menuController_ menu]
57                   withEvent:clickEvent
58                     forView:parent_view_];
59  }
60}
61
62void RenderViewContextMenuMac::InitPlatformMenu() {
63  bool has_selection = !params_.selection_text.empty();
64
65  if (has_selection) {
66      menu_model_.AddSeparator();
67      menu_model_.AddItemWithStringId(
68          IDC_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY,
69          IDS_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY);
70  }
71
72}
73
74void RenderViewContextMenuMac::LookUpInDictionary() {
75  // TODO(morrita): On Safari, A dictionary panel could be shown
76  // based on a preference setting of Dictionary.app.  We currently
77  // don't support it: http://crbug.com/17951
78  NSString* text = base::SysWideToNSString(params_.selection_text);
79  NSPasteboard* pboard = [NSPasteboard pasteboardWithUniqueName];
80  // 10.5 and earlier require declareTypes before setData.
81  // See the documentation on [NSPasteboard declareTypes].
82  NSArray* toDeclare = [NSArray arrayWithObject:NSStringPboardType];
83  [pboard declareTypes:toDeclare owner:nil];
84  BOOL ok = [pboard setString:text forType:NSStringPboardType];
85  if (ok)
86    NSPerformService(@"Look Up in Dictionary", pboard);
87}
88