[Mac]: Enable speech sub-menu under the edit menu and refactor speech implementation.

MainMenu.xib changes: Add submenu "Speech" with items "Start Speaking" and
"Stop Speaking" to the Edit menu (with localized ids for names).

This is a followup to http://crrev.com/126602, which implemented speech
support in the context menu. This changes also updates the context menu
implementation to go through the new one in the render view.

Also fixes some warnings found by 'gcl lint'.

BUG=31107, 46153
TEST=Select some text on a web page and go to Edit -> Speech -> Start Speaking. The
selected text should be spoken. While some text is being spoken, go to Edit -> Speech
-> Stop Speaking. The speech should stop. When no text is being spoken, Edit -> Speech
-> Stop Speaking should be disabled. Try the same steps as above but with selected
text in the omnibox. It should also work.

Review URL: https://chromiumcodereview.appspot.com/10820062

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150364 0039d316-1c4b-4281-b951-d872f2087c98
parent 3d9c8b00
...@@ -475,15 +475,6 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may ...@@ -475,15 +475,6 @@ Psst! Incognito mode <ph name="SHORTCUT_KEY">$1<ex>(Ctrl+Shift+N)</ex></ph> may
<message name="IDS_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY" desc="The name of the 'Look Up in Dictionary' item in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there."> <message name="IDS_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY" desc="The name of the 'Look Up in Dictionary' item in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
Look Up in Dictionary Look Up in Dictionary
</message> </message>
<message name="IDS_CONTENT_CONTEXT_SPEECH_MENU" desc="The name of the 'Speech' submenu in the content area context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
Speech
</message>
<message name="IDS_CONTENT_CONTEXT_SPEECH_START_SPEAKING" desc="The name of the 'Start Speaking' item from the 'Speech' submenu in the content area context menu. To translate, launch /Applications/Textedit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
Start Speaking
</message>
<message name="IDS_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING" desc="The name of the 'Stop Speaking' item from the 'Speech' submenu in the content area context menu. To translate, launch /Applications/Textedit.app in an appropriately localized version of OS X, right-click on the text entry area and use the translation from there.">
Stop Speaking
</message>
</if> </if>
<if expr="not pp_ifdef('use_titlecase')"> <if expr="not pp_ifdef('use_titlecase')">
<message name="IDS_CONTENT_CONTEXT_BACK" desc="The name of the Back command in the content area context menu"> <message name="IDS_CONTENT_CONTEXT_BACK" desc="The name of the Back command in the content area context menu">
...@@ -12875,6 +12866,16 @@ Some features may be unavailable. Please check that the profile exists and you ...@@ -12875,6 +12866,16 @@ Some features may be unavailable. Please check that the profile exists and you
<message name="IDS_EDIT_CHECK_GRAMMAR_MAC" desc="The Mac menu item for check grammar with spelling in the edit menu."> <message name="IDS_EDIT_CHECK_GRAMMAR_MAC" desc="The Mac menu item for check grammar with spelling in the edit menu.">
Check Grammar With Spelling Check Grammar With Spelling
</message> </message>
<!-- Edit::Speech submenu -->
<message name="IDS_SPEECH_MAC" desc="The Mac menu item for the 'Speech' submenu in the edit and context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, open the Edit menu and use the translation from there.">
Speech
</message>
<message name="IDS_SPEECH_START_SPEAKING_MAC" desc="The Mac menu item for the 'Start Speaking' item from the 'Speech' submenu in edit and context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, open the Edit menu and use the translation from there.">
Start Speaking
</message>
<message name="IDS_SPEECH_STOP_SPEAKING_MAC" desc="The Mac menu item for the 'Stop Speaking' item from the 'Speech' submenu in edit and context menu. To translate, launch /Applications/TextEdit.app in an appropriately localized version of OS X, open the Edit menu and use the translation from there.">
Stop Speaking
</message>
<!-- View menu --> <!-- View menu -->
<message name="IDS_BOOKMARK_BAR_ALWAYS_SHOW_MAC" desc="The Mac menu item for having bookmark bar always visible in the view menu."> <message name="IDS_BOOKMARK_BAR_ALWAYS_SHOW_MAC" desc="The Mac menu item for having bookmark bar always visible in the view menu.">
Always Show Bookmarks Bar Always Show Bookmarks Bar
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
</object> </object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<integer value="29"/>
</object> </object>
<object class="NSArray" key="IBDocument.PluginDependencies"> <object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
...@@ -636,6 +637,37 @@ ...@@ -636,6 +637,37 @@
</object> </object>
</object> </object>
</object> </object>
<object class="NSMenuItem" id="297966117">
<reference key="NSMenu" ref="789758025"/>
<string key="NSTitle">^IDS_SPEECH_MAC</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="353210768"/>
<reference key="NSMixedImage" ref="549394948"/>
<string key="NSAction">submenuAction:</string>
<object class="NSMenu" key="NSSubmenu" id="84147574">
<string key="NSTitle">^IDS_SPEECH_MAC</string>
<object class="NSMutableArray" key="NSMenuItems">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMenuItem" id="383191596">
<reference key="NSMenu" ref="84147574"/>
<string key="NSTitle">^IDS_SPEECH_START_SPEAKING_MAC</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="353210768"/>
<reference key="NSMixedImage" ref="549394948"/>
</object>
<object class="NSMenuItem" id="607634770">
<reference key="NSMenu" ref="84147574"/>
<string key="NSTitle">^IDS_SPEECH_STOP_SPEAKING_MAC</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="353210768"/>
<reference key="NSMixedImage" ref="549394948"/>
</object>
</object>
</object>
</object>
</object> </object>
</object> </object>
</object> </object>
...@@ -1825,6 +1857,22 @@ ...@@ -1825,6 +1857,22 @@
</object> </object>
<int key="connectionID">697</int> <int key="connectionID">697</int>
</object> </object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">startSpeaking:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="383191596"/>
</object>
<int key="connectionID">710</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">stopSpeaking:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="607634770"/>
</object>
<int key="connectionID">711</int>
</object>
</object> </object>
<object class="IBMutableOrderedSet" key="objectRecords"> <object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects"> <object class="NSArray" key="orderedObjects">
...@@ -1989,6 +2037,7 @@ ...@@ -1989,6 +2037,7 @@
<reference ref="972420730"/> <reference ref="972420730"/>
<reference ref="688066565"/> <reference ref="688066565"/>
<reference ref="499460629"/> <reference ref="499460629"/>
<reference ref="297966117"/>
</object> </object>
<reference key="parent" ref="952259628"/> <reference key="parent" ref="952259628"/>
</object> </object>
...@@ -2698,6 +2747,35 @@ ...@@ -2698,6 +2747,35 @@
<reference key="object" ref="311743933"/> <reference key="object" ref="311743933"/>
<reference key="parent" ref="720053764"/> <reference key="parent" ref="720053764"/>
</object> </object>
<object class="IBObjectRecord">
<int key="objectID">700</int>
<reference key="object" ref="297966117"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="84147574"/>
</object>
<reference key="parent" ref="789758025"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">701</int>
<reference key="object" ref="84147574"/>
<object class="NSMutableArray" key="children">
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="607634770"/>
<reference ref="383191596"/>
</object>
<reference key="parent" ref="297966117"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">702</int>
<reference key="object" ref="607634770"/>
<reference key="parent" ref="84147574"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">705</int>
<reference key="object" ref="383191596"/>
<reference key="parent" ref="84147574"/>
</object>
</object> </object>
</object> </object>
<object class="NSMutableDictionary" key="flattenedProperties"> <object class="NSMutableDictionary" key="flattenedProperties">
...@@ -2724,11 +2802,13 @@ ...@@ -2724,11 +2802,13 @@
<string>197.IBPluginDependency</string> <string>197.IBPluginDependency</string>
<string>198.IBPluginDependency</string> <string>198.IBPluginDependency</string>
<string>199.IBPluginDependency</string> <string>199.IBPluginDependency</string>
<string>200.IBEditorWindowLastContentRect</string>
<string>200.IBPluginDependency</string> <string>200.IBPluginDependency</string>
<string>201.IBPluginDependency</string> <string>201.IBPluginDependency</string>
<string>202.IBPluginDependency</string> <string>202.IBPluginDependency</string>
<string>203.IBPluginDependency</string> <string>203.IBPluginDependency</string>
<string>204.IBPluginDependency</string> <string>204.IBPluginDependency</string>
<string>205.IBEditorWindowLastContentRect</string>
<string>205.IBPluginDependency</string> <string>205.IBPluginDependency</string>
<string>206.IBPluginDependency</string> <string>206.IBPluginDependency</string>
<string>207.IBPluginDependency</string> <string>207.IBPluginDependency</string>
...@@ -2748,6 +2828,7 @@ ...@@ -2748,6 +2828,7 @@
<string>236.IBPluginDependency</string> <string>236.IBPluginDependency</string>
<string>239.IBPluginDependency</string> <string>239.IBPluginDependency</string>
<string>24.IBPluginDependency</string> <string>24.IBPluginDependency</string>
<string>29.IBEditorWindowLastContentRect</string>
<string>29.IBPluginDependency</string> <string>29.IBPluginDependency</string>
<string>295.IBPluginDependency</string> <string>295.IBPluginDependency</string>
<string>296.IBPluginDependency</string> <string>296.IBPluginDependency</string>
...@@ -2827,6 +2908,11 @@ ...@@ -2827,6 +2908,11 @@
<string>691.IBPluginDependency</string> <string>691.IBPluginDependency</string>
<string>692.IBPluginDependency</string> <string>692.IBPluginDependency</string>
<string>694.IBPluginDependency</string> <string>694.IBPluginDependency</string>
<string>700.IBPluginDependency</string>
<string>701.IBEditorWindowLastContentRect</string>
<string>701.IBPluginDependency</string>
<string>702.IBPluginDependency</string>
<string>705.IBPluginDependency</string>
<string>72.IBPluginDependency</string> <string>72.IBPluginDependency</string>
<string>73.IBPluginDependency</string> <string>73.IBPluginDependency</string>
<string>74.IBPluginDependency</string> <string>74.IBPluginDependency</string>
...@@ -2859,11 +2945,13 @@ ...@@ -2859,11 +2945,13 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{877, 345}, {373, 83}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{519, 385}, {358, 263}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
...@@ -2883,6 +2971,7 @@ ...@@ -2883,6 +2971,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{77, 648}, {1852, 20}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
...@@ -2963,6 +3052,11 @@ ...@@ -2963,6 +3052,11 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{877, 365}, {341, 43}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
...@@ -2989,7 +3083,7 @@ ...@@ -2989,7 +3083,7 @@
</object> </object>
</object> </object>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">697</int> <int key="maxID">711</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">
......
...@@ -12,18 +12,13 @@ ...@@ -12,18 +12,13 @@
#include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_command_ids.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/menu_controller.h" #import "chrome/browser/ui/cocoa/menu_controller.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
using content::WebContents; using content::WebContents;
// These are not documented, so use only after checking -respondsToSelector:.
@interface NSApplication (UndocumentedSpeechMethods)
- (void)speakString:(NSString*)string;
- (void)stopSpeaking:(id)sender;
- (BOOL)isSpeaking;
@end
namespace { namespace {
// Retrieves an NSMenuItem which has the specified command_id. This function // Retrieves an NSMenuItem which has the specified command_id. This function
...@@ -155,9 +150,10 @@ bool RenderViewContextMenuMac::IsCommandIdEnabled(int command_id) const { ...@@ -155,9 +150,10 @@ bool RenderViewContextMenuMac::IsCommandIdEnabled(int command_id) const {
// appropriate. // appropriate.
return true; return true;
case IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING: case IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING: {
return [NSApp respondsToSelector:@selector(isSpeaking)] && content::RenderWidgetHostView* view = GetRenderViewHost()->GetView();
[NSApp isSpeaking]; return view && view->IsSpeaking();
}
default: default:
return RenderViewContextMenu::IsCommandIdEnabled(command_id); return RenderViewContextMenu::IsCommandIdEnabled(command_id);
...@@ -179,18 +175,17 @@ void RenderViewContextMenuMac::InitPlatformMenu() { ...@@ -179,18 +175,17 @@ void RenderViewContextMenuMac::InitPlatformMenu() {
IDC_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY, IDC_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY,
IDS_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY); IDS_CONTENT_CONTEXT_LOOK_UP_IN_DICTIONARY);
// Add speech items only if NSApp supports the private API we're using. content::RenderWidgetHostView* view = GetRenderViewHost()->GetView();
if ([NSApp respondsToSelector:@selector(speakString:)] && if (view && view->SupportsSpeech()) {
[NSApp respondsToSelector:@selector(stopSpeaking:)]) {
speech_submenu_model_.AddItemWithStringId( speech_submenu_model_.AddItemWithStringId(
IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING, IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING,
IDS_CONTENT_CONTEXT_SPEECH_START_SPEAKING); IDS_SPEECH_START_SPEAKING_MAC);
speech_submenu_model_.AddItemWithStringId( speech_submenu_model_.AddItemWithStringId(
IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING, IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING,
IDS_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING); IDS_SPEECH_STOP_SPEAKING_MAC);
menu_model_.AddSubMenu( menu_model_.AddSubMenu(
IDC_CONTENT_CONTEXT_SPEECH_MENU, IDC_CONTENT_CONTEXT_SPEECH_MENU,
l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_SPEECH_MENU), l10n_util::GetStringUTF16(IDS_SPEECH_MAC),
&speech_submenu_model_); &speech_submenu_model_);
} }
} }
...@@ -212,12 +207,15 @@ void RenderViewContextMenuMac::LookUpInDictionary() { ...@@ -212,12 +207,15 @@ void RenderViewContextMenuMac::LookUpInDictionary() {
} }
void RenderViewContextMenuMac::StartSpeaking() { void RenderViewContextMenuMac::StartSpeaking() {
NSString* text = base::SysUTF16ToNSString(params_.selection_text); content::RenderWidgetHostView* view = GetRenderViewHost()->GetView();
[NSApp speakString:text]; if (view)
view->SpeakSelection();
} }
void RenderViewContextMenuMac::StopSpeaking() { void RenderViewContextMenuMac::StopSpeaking() {
[NSApp stopSpeaking:menu_controller_]; content::RenderWidgetHostView* view = GetRenderViewHost()->GetView();
if (view)
view->StopSpeaking();
} }
void RenderViewContextMenuMac::UpdateMenuItem(int command_id, void RenderViewContextMenuMac::UpdateMenuItem(int command_id,
......
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#include <list> #include <list>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/memory/scoped_nsobject.h" #include "base/memory/scoped_nsobject.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
...@@ -56,7 +60,7 @@ class RenderWidgetHostViewMacEditCommandHelper; ...@@ -56,7 +60,7 @@ class RenderWidgetHostViewMacEditCommandHelper;
// These are part of the magic tooltip code from WebKit's WebHTMLView: // These are part of the magic tooltip code from WebKit's WebHTMLView:
id trackingRectOwner_; // (not retained) id trackingRectOwner_; // (not retained)
void *trackingRectUserData_; void* trackingRectUserData_;
NSTrackingRectTag lastToolTipTag_; NSTrackingRectTag lastToolTipTag_;
scoped_nsobject<NSString> toolTip_; scoped_nsobject<NSString> toolTip_;
...@@ -205,6 +209,10 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase { ...@@ -205,6 +209,10 @@ class RenderWidgetHostViewMac : public RenderWidgetHostViewBase {
virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE; virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE;
virtual void SetWindowVisibility(bool visible) OVERRIDE; virtual void SetWindowVisibility(bool visible) OVERRIDE;
virtual void WindowFrameChanged() OVERRIDE; virtual void WindowFrameChanged() OVERRIDE;
virtual bool SupportsSpeech() const OVERRIDE;
virtual void SpeakSelection() OVERRIDE;
virtual bool IsSpeaking() const OVERRIDE;
virtual void StopSpeaking() OVERRIDE;
virtual void SetBackground(const SkBitmap& background) OVERRIDE; virtual void SetBackground(const SkBitmap& background) OVERRIDE;
// Implementation of RenderWidgetHostViewPort. // Implementation of RenderWidgetHostViewPort.
......
...@@ -66,6 +66,13 @@ using WebKit::WebMouseEvent; ...@@ -66,6 +66,13 @@ using WebKit::WebMouseEvent;
using WebKit::WebMouseWheelEvent; using WebKit::WebMouseWheelEvent;
using WebKit::WebGestureEvent; using WebKit::WebGestureEvent;
// These are not documented, so use only after checking -respondsToSelector:.
@interface NSApplication (UndocumentedSpeechMethods)
- (void)speakString:(NSString*)string;
- (void)stopSpeaking:(id)sender;
- (BOOL)isSpeaking;
@end
// Declare things that are part of the 10.7 SDK. // Declare things that are part of the 10.7 SDK.
#if !defined(MAC_OS_X_VERSION_10_7) || \ #if !defined(MAC_OS_X_VERSION_10_7) || \
MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
...@@ -730,6 +737,26 @@ void RenderWidgetHostViewMac::SetTooltipText(const string16& tooltip_text) { ...@@ -730,6 +737,26 @@ void RenderWidgetHostViewMac::SetTooltipText(const string16& tooltip_text) {
} }
} }
bool RenderWidgetHostViewMac::SupportsSpeech() const {
return [NSApp respondsToSelector:@selector(speakString:)] &&
[NSApp respondsToSelector:@selector(stopSpeaking:)];
}
void RenderWidgetHostViewMac::SpeakSelection() {
if ([NSApp respondsToSelector:@selector(speakString:)])
[NSApp speakString:base::SysUTF8ToNSString(selected_text_)];
}
bool RenderWidgetHostViewMac::IsSpeaking() const {
return [NSApp respondsToSelector:@selector(isSpeaking)] &&
[NSApp isSpeaking];
}
void RenderWidgetHostViewMac::StopSpeaking() {
if ([NSApp respondsToSelector:@selector(stopSpeaking:)])
[NSApp stopSpeaking:cocoa_view_];
}
// //
// RenderWidgetHostViewCocoa uses the stored selection text, // RenderWidgetHostViewCocoa uses the stored selection text,
// which implements NSServicesRequests protocol. // which implements NSServicesRequests protocol.
...@@ -2304,6 +2331,15 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) { ...@@ -2304,6 +2331,15 @@ void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
SEL action = [item action]; SEL action = [item action];
if (action == @selector(stopSpeaking:)) {
return renderWidgetHostView_->render_widget_host_->IsRenderView() &&
renderWidgetHostView_->IsSpeaking();
}
if (action == @selector(startSpeaking:)) {
return renderWidgetHostView_->render_widget_host_->IsRenderView() &&
renderWidgetHostView_->SupportsSpeech();
}
// For now, these actions are always enabled for render view, // For now, these actions are always enabled for render view,
// this is sub-optimal. // this is sub-optimal.
// TODO(suzhe): Plumb the "can*" methods up from WebCore. // TODO(suzhe): Plumb the "can*" methods up from WebCore.
...@@ -3033,6 +3069,14 @@ extern NSString *NSTextInputReplacementRangeAttributeName; ...@@ -3033,6 +3069,14 @@ extern NSString *NSTextInputReplacementRangeAttributeName;
} }
} }
- (void)startSpeaking:(id)sender {
renderWidgetHostView_->SpeakSelection();
}
- (void)stopSpeaking:(id)sender {
renderWidgetHostView_->StopSpeaking();
}
- (void)cancelComposition { - (void)cancelComposition {
if (!hasMarkedText_) if (!hasMarkedText_)
return; return;
......
...@@ -137,6 +137,20 @@ void TestRenderWidgetHostView::SetActive(bool active) { ...@@ -137,6 +137,20 @@ void TestRenderWidgetHostView::SetActive(bool active) {
// <viettrungluu@gmail.com>: Do I need to do anything here? // <viettrungluu@gmail.com>: Do I need to do anything here?
} }
bool TestRenderWidgetHostView::SupportsSpeech() const {
return false;
}
void TestRenderWidgetHostView::SpeakSelection() {
}
bool TestRenderWidgetHostView::IsSpeaking() const {
return false;
}
void TestRenderWidgetHostView::StopSpeaking() {
}
void TestRenderWidgetHostView::PluginFocusChanged(bool focused, void TestRenderWidgetHostView::PluginFocusChanged(bool focused,
int plugin_id) { int plugin_id) {
} }
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#ifndef CONTENT_BROWSER_RENDERER_HOST_TEST_RENDER_VIEW_HOST_H_ #ifndef CONTENT_BROWSER_RENDERER_HOST_TEST_RENDER_VIEW_HOST_H_
#define CONTENT_BROWSER_RENDERER_HOST_TEST_RENDER_VIEW_HOST_H_ #define CONTENT_BROWSER_RENDERER_HOST_TEST_RENDER_VIEW_HOST_H_
#include <string>
#include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/gtest_prod_util.h" #include "base/gtest_prod_util.h"
#include "build/build_config.h" #include "build/build_config.h"
...@@ -66,6 +69,10 @@ class TestRenderWidgetHostView : public RenderWidgetHostViewBase { ...@@ -66,6 +69,10 @@ class TestRenderWidgetHostView : public RenderWidgetHostViewBase {
virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE {} virtual void SetTakesFocusOnlyOnMouseDown(bool flag) OVERRIDE {}
virtual void SetWindowVisibility(bool visible) OVERRIDE {} virtual void SetWindowVisibility(bool visible) OVERRIDE {}
virtual void WindowFrameChanged() OVERRIDE {} virtual void WindowFrameChanged() OVERRIDE {}
virtual bool SupportsSpeech() const OVERRIDE;
virtual void SpeakSelection() OVERRIDE;
virtual bool IsSpeaking() const OVERRIDE;
virtual void StopSpeaking() OVERRIDE;
#endif // defined(OS_MACOSX) #endif // defined(OS_MACOSX)
#if defined(TOOLKIT_GTK) #if defined(TOOLKIT_GTK)
virtual GdkEventButton* GetLastMouseDown() OVERRIDE; virtual GdkEventButton* GetLastMouseDown() OVERRIDE;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_VIEW_H_ #define CONTENT_PUBLIC_BROWSER_RENDER_WIDGET_HOST_VIEW_H_
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/string16.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRegion.h" #include "third_party/skia/include/core/SkRegion.h"
...@@ -123,6 +124,15 @@ class CONTENT_EXPORT RenderWidgetHostView { ...@@ -123,6 +124,15 @@ class CONTENT_EXPORT RenderWidgetHostView {
// Informs the view that its containing window's frame changed. // Informs the view that its containing window's frame changed.
virtual void WindowFrameChanged() = 0; virtual void WindowFrameChanged() = 0;
// Returns |true| if Mac OS X text to speech is supported.
virtual bool SupportsSpeech() const = 0;
// Tells the view to speak the currently selected text.
virtual void SpeakSelection() = 0;
// Returns |true| if text is currently being spoken by Mac OS X.
virtual bool IsSpeaking() const = 0;
// Stops speaking, if it is currently in progress.
virtual void StopSpeaking() = 0;
#endif // defined(OS_MACOSX) #endif // defined(OS_MACOSX)
#if defined(TOOLKIT_GTK) #if defined(TOOLKIT_GTK)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment