Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 10820062: [Mac]: Enable speech sub-menu under the edit menu and pipe it through to the renderer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: sp Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "content/browser/renderer_host/render_widget_host_view_mac.h" 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
6 6
7 #include <QuartzCore/QuartzCore.h> 7 #include <QuartzCore/QuartzCore.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 using content::RenderViewHostImpl; 58 using content::RenderViewHostImpl;
59 using content::RenderWidgetHostImpl; 59 using content::RenderWidgetHostImpl;
60 using content::RenderWidgetHostViewMac; 60 using content::RenderWidgetHostViewMac;
61 using content::RenderWidgetHostViewMacEditCommandHelper; 61 using content::RenderWidgetHostViewMacEditCommandHelper;
62 using WebKit::WebInputEvent; 62 using WebKit::WebInputEvent;
63 using WebKit::WebInputEventFactory; 63 using WebKit::WebInputEventFactory;
64 using WebKit::WebMouseEvent; 64 using WebKit::WebMouseEvent;
65 using WebKit::WebMouseWheelEvent; 65 using WebKit::WebMouseWheelEvent;
66 using WebKit::WebGestureEvent; 66 using WebKit::WebGestureEvent;
67 67
68 // These are not documented, so use only after checking -respondsToSelector:.
69 @interface NSApplication (UndocumentedSpeechMethods)
70 - (void)speakString:(NSString*)string;
71 - (void)stopSpeaking:(id)sender;
72 - (BOOL)isSpeaking;
73 @end
74
68 // Declare things that are part of the 10.7 SDK. 75 // Declare things that are part of the 10.7 SDK.
69 #if !defined(MAC_OS_X_VERSION_10_7) || \ 76 #if !defined(MAC_OS_X_VERSION_10_7) || \
70 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 77 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7
71 @interface NSEvent (LionAPI) 78 @interface NSEvent (LionAPI)
72 + (id)addLocalMonitorForEventsMatchingMask:(NSEventMask)mask 79 + (id)addLocalMonitorForEventsMatchingMask:(NSEventMask)mask
73 handler:(NSEvent* (^)(NSEvent*))block; 80 handler:(NSEvent* (^)(NSEvent*))block;
74 + (void)removeMonitor:(id)eventMonitor; 81 + (void)removeMonitor:(id)eventMonitor;
75 @end 82 @end
76 83
77 @interface NSScreen (LionAPI) 84 @interface NSScreen (LionAPI)
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 // set it again every single time the mouse moves. 746 // set it again every single time the mouse moves.
740 string16 display_text = tooltip_text_; 747 string16 display_text = tooltip_text_;
741 if (tooltip_text_.length() > kMaxTooltipLength) 748 if (tooltip_text_.length() > kMaxTooltipLength)
742 display_text = tooltip_text_.substr(0, kMaxTooltipLength); 749 display_text = tooltip_text_.substr(0, kMaxTooltipLength);
743 750
744 NSString* tooltip_nsstring = base::SysUTF16ToNSString(display_text); 751 NSString* tooltip_nsstring = base::SysUTF16ToNSString(display_text);
745 [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring]; 752 [cocoa_view_ setToolTipAtMousePoint:tooltip_nsstring];
746 } 753 }
747 } 754 }
748 755
756 bool RenderWidgetHostViewMac::SupportsSpeech() const {
757 return [NSApp respondsToSelector:@selector(speakString:)] &&
758 [NSApp respondsToSelector:@selector(stopSpeaking:)];
759 }
760
761 void RenderWidgetHostViewMac::SpeakSelection() {
762 // No need to check -respondsToSelect: because -validateUserInterfaceItem:
763 // validates this before enabling the item.
764 [NSApp speakString:base::SysUTF8ToNSString(selected_text_)];
765 }
766
767 bool RenderWidgetHostViewMac::IsSpeaking() const {
768 return [NSApp respondsToSelector:@selector(isSpeaking)] &&
769 [NSApp isSpeaking];
770 }
771
772 void RenderWidgetHostViewMac::StopSpeaking() {
773 // No need to check -respondsToSelect: because -validateUserInterfaceItem:
774 // validates this before enabling the item.
Nico 2012/08/06 15:47:31 With this now being a public method, you probably
Alexei Svitkine (slow) 2012/08/06 16:30:42 Done.
775 [NSApp stopSpeaking:cocoa_view_];
776 }
777
749 // 778 //
750 // RenderWidgetHostViewCocoa uses the stored selection text, 779 // RenderWidgetHostViewCocoa uses the stored selection text,
751 // which implements NSServicesRequests protocol. 780 // which implements NSServicesRequests protocol.
752 // 781 //
753 void RenderWidgetHostViewMac::SelectionChanged(const string16& text, 782 void RenderWidgetHostViewMac::SelectionChanged(const string16& text,
754 size_t offset, 783 size_t offset,
755 const ui::Range& range) { 784 const ui::Range& range) {
756 if (range.is_empty() || text.empty()) { 785 if (range.is_empty() || text.empty()) {
757 selected_text_.clear(); 786 selected_text_.clear();
758 } else { 787 } else {
(...skipping 1574 matching lines...) Expand 10 before | Expand all | Expand 10 after
2333 @selector(validateUserInterfaceItem:isValidItem:)]) { 2362 @selector(validateUserInterfaceItem:isValidItem:)]) {
2334 BOOL valid; 2363 BOOL valid;
2335 BOOL known = [delegate_ validateUserInterfaceItem:item 2364 BOOL known = [delegate_ validateUserInterfaceItem:item
2336 isValidItem:&valid]; 2365 isValidItem:&valid];
2337 if (known) 2366 if (known)
2338 return valid; 2367 return valid;
2339 } 2368 }
2340 2369
2341 SEL action = [item action]; 2370 SEL action = [item action];
2342 2371
2372 if (action == @selector(stopSpeaking:)) {
2373 return renderWidgetHostView_->render_widget_host_->IsRenderView() &&
2374 renderWidgetHostView_->IsSpeaking();
2375 }
2376 if (action == @selector(startSpeaking:)) {
2377 return renderWidgetHostView_->render_widget_host_->IsRenderView() &&
2378 renderWidgetHostView_->SupportsSpeech();
2379 }
2380
2343 // For now, these actions are always enabled for render view, 2381 // For now, these actions are always enabled for render view,
2344 // this is sub-optimal. 2382 // this is sub-optimal.
2345 // TODO(suzhe): Plumb the "can*" methods up from WebCore. 2383 // TODO(suzhe): Plumb the "can*" methods up from WebCore.
2346 if (action == @selector(undo:) || 2384 if (action == @selector(undo:) ||
2347 action == @selector(redo:) || 2385 action == @selector(redo:) ||
2348 action == @selector(cut:) || 2386 action == @selector(cut:) ||
2349 action == @selector(copy:) || 2387 action == @selector(copy:) ||
2350 action == @selector(copyToFindPboard:) || 2388 action == @selector(copyToFindPboard:) ||
2351 action == @selector(paste:) || 2389 action == @selector(paste:) ||
2352 action == @selector(pasteAndMatchStyle:)) { 2390 action == @selector(pasteAndMatchStyle:)) {
(...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after
3064 } 3102 }
3065 } 3103 }
3066 3104
3067 - (void)pasteAndMatchStyle:(id)sender { 3105 - (void)pasteAndMatchStyle:(id)sender {
3068 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) { 3106 if (renderWidgetHostView_->render_widget_host_->IsRenderView()) {
3069 static_cast<RenderViewHostImpl*>( 3107 static_cast<RenderViewHostImpl*>(
3070 renderWidgetHostView_->render_widget_host_)->PasteAndMatchStyle(); 3108 renderWidgetHostView_->render_widget_host_)->PasteAndMatchStyle();
3071 } 3109 }
3072 } 3110 }
3073 3111
3112 - (void)startSpeaking:(id)sender {
3113 renderWidgetHostView_->SpeakSelection();
3114 }
3115
3116 - (void)stopSpeaking:(id)sender {
3117 renderWidgetHostView_->StopSpeaking();
3118 }
3119
3074 - (void)cancelComposition { 3120 - (void)cancelComposition {
3075 if (!hasMarkedText_) 3121 if (!hasMarkedText_)
3076 return; 3122 return;
3077 3123
3078 // Cancel the ongoing composition. [NSInputManager markedTextAbandoned:] 3124 // Cancel the ongoing composition. [NSInputManager markedTextAbandoned:]
3079 // doesn't call any NSTextInput functions, such as setMarkedText or 3125 // doesn't call any NSTextInput functions, such as setMarkedText or
3080 // insertText. So, we need to send an IPC message to a renderer so it can 3126 // insertText. So, we need to send an IPC message to a renderer so it can
3081 // delete the composition node. 3127 // delete the composition node.
3082 NSInputManager *currentInputManager = [NSInputManager currentInputManager]; 3128 NSInputManager *currentInputManager = [NSInputManager currentInputManager];
3083 [currentInputManager markedTextAbandoned:self]; 3129 [currentInputManager markedTextAbandoned:self];
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
3215 if (!string) return NO; 3261 if (!string) return NO;
3216 3262
3217 // If the user is currently using an IME, confirm the IME input, 3263 // If the user is currently using an IME, confirm the IME input,
3218 // and then insert the text from the service, the same as TextEdit and Safari. 3264 // and then insert the text from the service, the same as TextEdit and Safari.
3219 [self confirmComposition]; 3265 [self confirmComposition];
3220 [self insertText:string]; 3266 [self insertText:string];
3221 return YES; 3267 return YES;
3222 } 3268 }
3223 3269
3224 @end 3270 @end
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_mac.h ('k') | content/browser/renderer_host/test_render_view_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698