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

Side by Side Diff: ui/base/cocoa/text_services_context_menu.cc

Issue 2164483006: [MacViews] Implemented text context menu (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix for tapted 2 Created 4 years 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/cocoa/text_services_context_menu.h"
6
7 #include <utility>
8
9 #include <ApplicationServices/ApplicationServices.h>
10 #include <CoreAudio/CoreAudio.h>
11
12 #include "base/strings/sys_string_conversions.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/app/chrome_command_ids.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/strings/grit/ui_strings.h"
17
18 namespace {
19
20 // The speech channel used for speaking.
21 SpeechChannel speechChannel;
22
23 // Returns the TextDirection associated associated with the given
24 // BiDi |command_id|.
25 base::i18n::TextDirection GetTextDirectionFromCommandId(int command_id) {
26 switch (command_id) {
27 case IDC_WRITING_DIRECTION_DEFAULT:
28 return base::i18n::TextDirection::UNKNOWN_DIRECTION;
29 case IDC_WRITING_DIRECTION_LTR:
30 return base::i18n::TextDirection::LEFT_TO_RIGHT;
31 case IDC_WRITING_DIRECTION_RTL:
32 return base::i18n::TextDirection::RIGHT_TO_LEFT;
33 default:
34 NOTREACHED();
35 return base::i18n::TextDirection::UNKNOWN_DIRECTION;
36 }
37 }
38
39 } // namespace
40
41 namespace ui {
42
43 //////////////////////////////////////////////////////////////////
44 // TextServicesContextMenu, public:
45
46 TextServicesContextMenu::TextServicesContextMenu(Delegate* delegate)
47 : speech_submenu_model_(this),
48 bidi_submenu_model_(this),
49 delegate_(delegate) {
50 DCHECK(delegate);
51
52 // Add items to the speech submenu.
53 speech_submenu_model_.AddItemWithStringId(
54 IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING, IDS_SPEECH_START_SPEAKING_MAC);
55 speech_submenu_model_.AddItemWithStringId(
56 IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING, IDS_SPEECH_STOP_SPEAKING_MAC);
57
58 // Add items to the BiDi submenu.
59 bidi_submenu_model_.AddCheckItem(
60 IDC_WRITING_DIRECTION_DEFAULT,
61 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_DEFAULT));
62 bidi_submenu_model_.AddCheckItem(
63 IDC_WRITING_DIRECTION_LTR,
64 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_LTR));
65 bidi_submenu_model_.AddCheckItem(
66 IDC_WRITING_DIRECTION_RTL,
67 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_RTL));
68 }
69
70 void TextServicesContextMenu::SpeakText(const base::string16& text) {
71 if (IsSpeaking())
72 StopSpeaking();
73
74 NewSpeechChannel(nullptr, &speechChannel);
75 SpeakCFString(speechChannel, SysUTF16ToCFStringRef(text), nullptr);
76 }
77
78 void TextServicesContextMenu::StopSpeaking() {
79 StopSpeechAt(speechChannel, kImmediate);
80 DisposeSpeechChannel(speechChannel);
81 }
82
83 bool TextServicesContextMenu::IsSpeaking() {
84 return SpeechBusy();
85 }
86
87 void TextServicesContextMenu::AppendToContextMenu(SimpleMenuModel* model) {
tapted 2016/12/19 07:41:21 we can perhaps just pass in |index|? (see below)
spqchan 2016/12/21 01:03:02 I think it's better to just get rid of look up fro
88 base::string16 printable_selection_text = delegate_->GetSelectedText();
89 if (printable_selection_text.empty())
90 return;
91
92 if (delegate_->IsLookUpAvailable()) {
93 // In case the user has selected a word that triggers spelling suggestions,
94 // show the dictionary lookup under the group that contains the command to
95 // “Add to Dictionary.”
96 int index = model->GetIndexOfCommandId(IDC_SPELLCHECK_ADD_TO_DICTIONARY);
tapted 2016/12/19 07:41:21 which means this is hard to fix (i.e. if we can't
spqchan 2016/12/21 01:03:02 Sounds good, let's just make it add only submenus
97 if (index < 0) {
98 index = 0;
99 } else {
100 while (model->GetTypeAt(index) != MenuModel::TYPE_SEPARATOR)
101 index++;
102 index += 1; // Place it below the separator.
103 }
104
105 model->InsertItemAt(index++, IDC_CONTENT_CONTEXT_LOOK_UP,
106 l10n_util::GetStringFUTF16(IDS_CONTENT_CONTEXT_LOOK_UP,
107 printable_selection_text));
108 model->InsertSeparatorAt(index++, NORMAL_SEPARATOR);
109 }
110
111 model->AddSeparator(NORMAL_SEPARATOR);
112
113 model->AddSubMenu(IDC_CONTENT_CONTEXT_SPEECH_MENU,
114 l10n_util::GetStringUTF16(IDS_SPEECH_MAC),
115 &speech_submenu_model_);
116 }
117
118 void TextServicesContextMenu::AppendEditableItems(SimpleMenuModel* model) {
119 model->AddSubMenu(
120 IDC_WRITING_DIRECTION_MENU,
121 l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_WRITING_DIRECTION_MENU),
122 &bidi_submenu_model_);
123 }
124
125 bool TextServicesContextMenu::IsTextServicesCommandId(int command_id) const {
126 switch (command_id) {
127 case IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING:
128 case IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING:
129 case IDC_CONTENT_CONTEXT_LOOK_UP:
130 case IDC_WRITING_DIRECTION_DEFAULT:
131 case IDC_WRITING_DIRECTION_LTR:
132 case IDC_WRITING_DIRECTION_RTL:
133 return true;
134 }
135
136 return false;
137 }
138
139 //////////////////////////////////////////////////////////////////
140 // TextServicesContextMenu::SimpleMenuModel::Delegate:
141
142 void TextServicesContextMenu::ExecuteCommand(int command_id, int event_flags) {
143 switch (command_id) {
144 case IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING:
145 delegate_->OnSpeakRequested();
146 break;
147 case IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING:
148 StopSpeaking();
149 break;
150 case IDC_CONTENT_CONTEXT_LOOK_UP:
151 delegate_->LookUpInDictionary();
152 break;
153 case IDC_WRITING_DIRECTION_DEFAULT:
154 case IDC_WRITING_DIRECTION_LTR:
155 case IDC_WRITING_DIRECTION_RTL:
156 delegate_->UpdateTextDirection(GetTextDirectionFromCommandId(command_id));
157 break;
158 default:
159 NOTREACHED();
160 }
161 }
162
163 bool TextServicesContextMenu::IsCommandIdChecked(int command_id) const {
164 switch (command_id) {
165 case IDC_WRITING_DIRECTION_DEFAULT:
166 case IDC_WRITING_DIRECTION_LTR:
167 case IDC_WRITING_DIRECTION_RTL:
168 return delegate_->IsTextDirectionChecked(
169 GetTextDirectionFromCommandId(command_id));
170 }
171 return false;
172 }
173
174 bool TextServicesContextMenu::IsCommandIdEnabled(int command_id) const {
175 switch (command_id) {
176 case IDC_CONTENT_CONTEXT_SPEECH_START_SPEAKING:
177 case IDC_CONTENT_CONTEXT_LOOK_UP:
178 // This is OK because the menu is not shown when it isn't
179 // appropriate.
180 return true;
181 case IDC_WRITING_DIRECTION_DEFAULT:
182 case IDC_WRITING_DIRECTION_LTR:
183 case IDC_WRITING_DIRECTION_RTL:
184 return delegate_->IsTextDirectionEnabled(
185 GetTextDirectionFromCommandId(command_id));
186 case IDC_CONTENT_CONTEXT_SPEECH_STOP_SPEAKING:
187 return IsSpeaking();
188 }
189
190 NOTREACHED();
191 return false;
192 }
193
194 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698