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 "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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |