| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/cocoa/tab_contents/render_view_context_menu_mac.h" | 5 #include "chrome/browser/ui/cocoa/tab_contents/render_view_context_menu_mac.h" |
| 6 | 6 |
| 7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
| 8 #import "base/mac/scoped_sending_event.h" | 8 #import "base/mac/scoped_sending_event.h" |
| 9 #include "base/memory/scoped_nsobject.h" | 9 #include "base/memory/scoped_nsobject.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/sys_string_conversions.h" | 11 #include "base/sys_string_conversions.h" |
| 12 #include "chrome/app/chrome_command_ids.h" | 12 #include "chrome/app/chrome_command_ids.h" |
| 13 #import "chrome/browser/ui/cocoa/browser_window_controller.h" | 13 #import "chrome/browser/ui/cocoa/browser_window_controller.h" |
| 14 #import "chrome/browser/ui/cocoa/menu_controller.h" | 14 #import "chrome/browser/ui/cocoa/menu_controller.h" |
| 15 #include "content/public/browser/render_view_host.h" |
| 16 #include "content/public/browser/render_widget_host_view.h" |
| 15 #include "grit/generated_resources.h" | 17 #include "grit/generated_resources.h" |
| 16 #include "ui/base/l10n/l10n_util.h" | 18 #include "ui/base/l10n/l10n_util.h" |
| 17 | 19 |
| 18 using content::WebContents; | 20 using content::WebContents; |
| 19 | 21 |
| 20 // These are not documented, so use only after checking -respondsToSelector:. | |
| 21 @interface NSApplication (UndocumentedSpeechMethods) | |
| 22 - (void)speakString:(NSString*)string; | |
| 23 - (void)stopSpeaking:(id)sender; | |
| 24 - (BOOL)isSpeaking; | |
| 25 @end | |
| 26 | |
| 27 namespace { | 22 namespace { |
| 28 | 23 |
| 29 // Retrieves an NSMenuItem which has the specified command_id. This function | 24 // Retrieves an NSMenuItem which has the specified command_id. This function |
| 30 // traverses the given |model| in the depth-first order. When this function | 25 // traverses the given |model| in the depth-first order. When this function |
| 31 // finds an item whose command_id is the same as the given |command_id|, it | 26 // finds an item whose command_id is the same as the given |command_id|, it |
| 32 // returns the NSMenuItem associated with the item. This function emulates | 27 // returns the NSMenuItem associated with the item. This function emulates |
| 33 // views::MenuItemViews::GetMenuItemByID() for Mac. | 28 // views::MenuItemViews::GetMenuItemByID() for Mac. |
| 34 NSMenuItem* GetMenuItemByID(ui::MenuModel* model, | 29 NSMenuItem* GetMenuItemByID(ui::MenuModel* model, |
| 35 NSMenu* menu, | 30 NSMenu* menu, |
| 36 int command_id) { | 31 int command_id) { |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 case IDC_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY: | 143 case IDC_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY: |
| 149 // This is OK because the menu is not shown when it isn't | 144 // This is OK because the menu is not shown when it isn't |
| 150 // appropriate. | 145 // appropriate. |
| 151 return true; | 146 return true; |
| 152 | 147 |
| 153 case IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING: | 148 case IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING: |
| 154 // This is OK because the menu is not shown when it isn't | 149 // This is OK because the menu is not shown when it isn't |
| 155 // appropriate. | 150 // appropriate. |
| 156 return true; | 151 return true; |
| 157 | 152 |
| 158 case IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING: | 153 case IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING: { |
| 159 return [NSApp respondsToSelector:@selector(isSpeaking)] && | 154 content::RenderWidgetHostView* view = GetRenderViewHost()->GetView(); |
| 160 [NSApp isSpeaking]; | 155 return view && view->IsSpeaking(); |
| 156 } |
| 161 | 157 |
| 162 default: | 158 default: |
| 163 return RenderViewContextMenu::IsCommandIdEnabled(command_id); | 159 return RenderViewContextMenu::IsCommandIdEnabled(command_id); |
| 164 } | 160 } |
| 165 } | 161 } |
| 166 | 162 |
| 167 bool RenderViewContextMenuMac::GetAcceleratorForCommandId( | 163 bool RenderViewContextMenuMac::GetAcceleratorForCommandId( |
| 168 int command_id, | 164 int command_id, |
| 169 ui::Accelerator* accelerator) { | 165 ui::Accelerator* accelerator) { |
| 170 return false; | 166 return false; |
| 171 } | 167 } |
| 172 | 168 |
| 173 void RenderViewContextMenuMac::InitPlatformMenu() { | 169 void RenderViewContextMenuMac::InitPlatformMenu() { |
| 174 bool has_selection = !params_.selection_text.empty(); | 170 bool has_selection = !params_.selection_text.empty(); |
| 175 | 171 |
| 176 if (has_selection) { | 172 if (has_selection) { |
| 177 menu_model_.AddSeparator(); | 173 menu_model_.AddSeparator(); |
| 178 menu_model_.AddItemWithStringId( | 174 menu_model_.AddItemWithStringId( |
| 179 IDC_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY, | 175 IDC_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY, |
| 180 IDS_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY); | 176 IDS_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY); |
| 181 | 177 |
| 182 // Add speech items only if NSApp supports the private API we're using. | 178 content::RenderWidgetHostView* view = GetRenderViewHost()->GetView(); |
| 183 if ([NSApp respondsToSelector:@selector(speakString:)] && | 179 if (view && view->SupportsSpeech()) { |
| 184 [NSApp respondsToSelector:@selector(stopSpeaking:)]) { | |
| 185 speech_submenu_model_.AddItemWithStringId( | 180 speech_submenu_model_.AddItemWithStringId( |
| 186 IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING, | 181 IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING, |
| 187 IDS_CONTENT_CONTEXT_SPEECH_START_SPEAKING); | 182 IDS_SPEECH_START_SPEAKING_MAC); |
| 188 speech_submenu_model_.AddItemWithStringId( | 183 speech_submenu_model_.AddItemWithStringId( |
| 189 IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING, | 184 IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING, |
| 190 IDS_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING); | 185 IDS_SPEECH_STOP_SPEAKING_MAC); |
| 191 menu_model_.AddSubMenu( | 186 menu_model_.AddSubMenu( |
| 192 IDC_CONTENT_CONTEXT_SPEECH_MENU, | 187 IDC_CONTENT_CONTEXT_SPEECH_MENU, |
| 193 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPEECH_MENU), | 188 l10n_util::GetStringUTF16(IDS_SPEECH_MAC), |
| 194 &speech_submenu_model_); | 189 &speech_submenu_model_); |
| 195 } | 190 } |
| 196 } | 191 } |
| 197 } | 192 } |
| 198 | 193 |
| 199 void RenderViewContextMenuMac::LookUpInDictionary() { | 194 void RenderViewContextMenuMac::LookUpInDictionary() { |
| 200 // TODO(morrita): On Safari, A dictionary panel could be shown | 195 // TODO(morrita): On Safari, A dictionary panel could be shown |
| 201 // based on a preference setting of Dictionary.app. We currently | 196 // based on a preference setting of Dictionary.app. We currently |
| 202 // don't support it: http://crbug.com/17951 | 197 // don't support it: http://crbug.com/17951 |
| 203 NSString* text = base::SysUTF16ToNSString(params_.selection_text); | 198 NSString* text = base::SysUTF16ToNSString(params_.selection_text); |
| 204 NSPasteboard* pboard = [NSPasteboard pasteboardWithUniqueName]; | 199 NSPasteboard* pboard = [NSPasteboard pasteboardWithUniqueName]; |
| 205 // 10.5 and earlier require declareTypes before setData. | 200 // 10.5 and earlier require declareTypes before setData. |
| 206 // See the documentation on [NSPasteboard declareTypes]. | 201 // See the documentation on [NSPasteboard declareTypes]. |
| 207 NSArray* toDeclare = [NSArray arrayWithObject:NSStringPboardType]; | 202 NSArray* toDeclare = [NSArray arrayWithObject:NSStringPboardType]; |
| 208 [pboard declareTypes:toDeclare owner:nil]; | 203 [pboard declareTypes:toDeclare owner:nil]; |
| 209 BOOL ok = [pboard setString:text forType:NSStringPboardType]; | 204 BOOL ok = [pboard setString:text forType:NSStringPboardType]; |
| 210 if (ok) | 205 if (ok) |
| 211 NSPerformService(@"Look Up in Dictionary", pboard); | 206 NSPerformService(@"Look Up in Dictionary", pboard); |
| 212 } | 207 } |
| 213 | 208 |
| 214 void RenderViewContextMenuMac::StartSpeaking() { | 209 void RenderViewContextMenuMac::StartSpeaking() { |
| 215 NSString* text = base::SysUTF16ToNSString(params_.selection_text); | 210 content::RenderWidgetHostView* view = GetRenderViewHost()->GetView(); |
| 216 [NSApp speakString:text]; | 211 if (view) |
| 212 view->SpeakSelection(); |
| 217 } | 213 } |
| 218 | 214 |
| 219 void RenderViewContextMenuMac::StopSpeaking() { | 215 void RenderViewContextMenuMac::StopSpeaking() { |
| 220 [NSApp stopSpeaking:menu_controller_]; | 216 content::RenderWidgetHostView* view = GetRenderViewHost()->GetView(); |
| 217 if (view) |
| 218 view->StopSpeaking(); |
| 221 } | 219 } |
| 222 | 220 |
| 223 void RenderViewContextMenuMac::UpdateMenuItem(int command_id, | 221 void RenderViewContextMenuMac::UpdateMenuItem(int command_id, |
| 224 bool enabled, | 222 bool enabled, |
| 225 bool hidden, | 223 bool hidden, |
| 226 const string16& title) { | 224 const string16& title) { |
| 227 NSMenuItem* item = GetMenuItemByID(&menu_model_, [menu_controller_ menu], | 225 NSMenuItem* item = GetMenuItemByID(&menu_model_, [menu_controller_ menu], |
| 228 command_id); | 226 command_id); |
| 229 if (!item) | 227 if (!item) |
| 230 return; | 228 return; |
| 231 | 229 |
| 232 // Update the returned NSMenuItem directly so we can update it immediately. | 230 // Update the returned NSMenuItem directly so we can update it immediately. |
| 233 [item setEnabled:enabled]; | 231 [item setEnabled:enabled]; |
| 234 [item setTitle:SysUTF16ToNSString(title)]; | 232 [item setTitle:SysUTF16ToNSString(title)]; |
| 235 [item setHidden:hidden]; | 233 [item setHidden:hidden]; |
| 236 [[item menu] itemChanged:item]; | 234 [[item menu] itemChanged:item]; |
| 237 } | 235 } |
| OLD | NEW |