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