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 |