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/common/extensions/command.h" | 5 #include "chrome/common/extensions/command.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
9 #include "base/strings/string_split.h" | 9 #include "base/strings/string_split.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
22 using extensions::ErrorUtils; | 22 using extensions::ErrorUtils; |
23 using extensions::Command; | 23 using extensions::Command; |
24 | 24 |
25 namespace { | 25 namespace { |
26 | 26 |
27 static const char kMissing[] = "Missing"; | 27 static const char kMissing[] = "Missing"; |
28 | 28 |
29 static const char kCommandKeyNotSupported[] = | 29 static const char kCommandKeyNotSupported[] = |
30 "Command key is not supported. Note: Ctrl means Command on Mac"; | 30 "Command key is not supported. Note: Ctrl means Command on Mac"; |
31 | 31 |
32 bool IsNamedCommand(const std::string& command_name) { | |
33 return command_name != values::kPageActionCommandEvent && | |
34 command_name != values::kBrowserActionCommandEvent && | |
35 command_name != values::kScriptBadgeCommandEvent; | |
36 } | |
37 | |
32 ui::Accelerator ParseImpl(const std::string& accelerator, | 38 ui::Accelerator ParseImpl(const std::string& accelerator, |
33 const std::string& platform_key, | 39 const std::string& platform_key, |
34 int index, | 40 int index, |
41 bool should_parse_media_keys, | |
35 string16* error) { | 42 string16* error) { |
36 if (platform_key != values::kKeybindingPlatformWin && | 43 if (platform_key != values::kKeybindingPlatformWin && |
37 platform_key != values::kKeybindingPlatformMac && | 44 platform_key != values::kKeybindingPlatformMac && |
38 platform_key != values::kKeybindingPlatformChromeOs && | 45 platform_key != values::kKeybindingPlatformChromeOs && |
39 platform_key != values::kKeybindingPlatformLinux && | 46 platform_key != values::kKeybindingPlatformLinux && |
40 platform_key != values::kKeybindingPlatformDefault) { | 47 platform_key != values::kKeybindingPlatformDefault) { |
41 *error = ErrorUtils::FormatErrorMessageUTF16( | 48 *error = ErrorUtils::FormatErrorMessageUTF16( |
42 errors::kInvalidKeyBindingUnknownPlatform, | 49 errors::kInvalidKeyBindingUnknownPlatform, |
43 base::IntToString(index), | 50 base::IntToString(index), |
44 platform_key); | 51 platform_key); |
45 return ui::Accelerator(); | 52 return ui::Accelerator(); |
46 } | 53 } |
47 | 54 |
55 if (should_parse_media_keys) { | |
56 if (accelerator == values::kKeyMediaNextTrack) | |
57 return ui::Accelerator(ui::VKEY_MEDIA_NEXT_TRACK, ui::EF_NONE); | |
58 if (accelerator == values::kKeyMediaPlayPause) | |
59 return ui::Accelerator(ui::VKEY_MEDIA_PLAY_PAUSE, ui::EF_NONE); | |
60 if (accelerator == values::kKeyMediaPrevTrack) | |
61 return ui::Accelerator(ui::VKEY_MEDIA_PREV_TRACK, ui::EF_NONE); | |
62 if (accelerator == values::kKeyMediaStop) | |
63 return ui::Accelerator(ui::VKEY_MEDIA_STOP, ui::EF_NONE); | |
Finnur
2013/08/28 14:15:16
This seems a bit ad-hoc. Also, I think we need to
| |
64 } | |
65 | |
48 std::vector<std::string> tokens; | 66 std::vector<std::string> tokens; |
49 base::SplitString(accelerator, '+', &tokens); | 67 base::SplitString(accelerator, '+', &tokens); |
50 if (tokens.size() < 2 || tokens.size() > 3) { | 68 if (tokens.size() < 2 || tokens.size() > 3) { |
zhchbin
2013/08/29 06:20:14
Note: if the size of tokens is 1, it will fail and
Finnur
2013/08/29 11:20:52
Yes, change this if statement to become:
if (toke
zhchbin
2013/08/29 14:27:11
Done.
| |
51 *error = ErrorUtils::FormatErrorMessageUTF16( | 69 *error = ErrorUtils::FormatErrorMessageUTF16( |
52 errors::kInvalidKeyBinding, | 70 errors::kInvalidKeyBinding, |
53 base::IntToString(index), | 71 base::IntToString(index), |
54 platform_key, | 72 platform_key, |
55 accelerator); | 73 accelerator); |
56 return ui::Accelerator(); | 74 return ui::Accelerator(); |
57 } | 75 } |
58 | 76 |
59 // Now, parse it into an accelerator. | 77 // Now, parse it into an accelerator. |
60 int modifiers = ui::EF_NONE; | 78 int modifiers = ui::EF_NONE; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 key = ui::VKEY_DELETE; | 142 key = ui::VKEY_DELETE; |
125 } else if (tokens[i] == values::kKeyHome) { | 143 } else if (tokens[i] == values::kKeyHome) { |
126 key = ui::VKEY_HOME; | 144 key = ui::VKEY_HOME; |
127 } else if (tokens[i] == values::kKeyEnd) { | 145 } else if (tokens[i] == values::kKeyEnd) { |
128 key = ui::VKEY_END; | 146 key = ui::VKEY_END; |
129 } else if (tokens[i] == values::kKeyPgUp) { | 147 } else if (tokens[i] == values::kKeyPgUp) { |
130 key = ui::VKEY_PRIOR; | 148 key = ui::VKEY_PRIOR; |
131 } else if (tokens[i] == values::kKeyPgDwn) { | 149 } else if (tokens[i] == values::kKeyPgDwn) { |
132 key = ui::VKEY_NEXT; | 150 key = ui::VKEY_NEXT; |
133 } else if (tokens[i] == values::kKeyTab) { | 151 } else if (tokens[i] == values::kKeyTab) { |
134 key = ui::VKEY_TAB; | 152 key = ui::VKEY_TAB; |
Finnur
2013/08/28 14:15:16
Add values::kKeyMediaNextTrack (and the other medi
zhchbin
2013/08/29 14:27:11
Done.
| |
135 } else if (tokens[i].size() == 1 && | 153 } else if (tokens[i].size() == 1 && |
136 tokens[i][0] >= 'A' && tokens[i][0] <= 'Z') { | 154 tokens[i][0] >= 'A' && tokens[i][0] <= 'Z') { |
137 key = static_cast<ui::KeyboardCode>(ui::VKEY_A + (tokens[i][0] - 'A')); | 155 key = static_cast<ui::KeyboardCode>(ui::VKEY_A + (tokens[i][0] - 'A')); |
138 } else if (tokens[i].size() == 1 && | 156 } else if (tokens[i].size() == 1 && |
139 tokens[i][0] >= '0' && tokens[i][0] <= '9') { | 157 tokens[i][0] >= '0' && tokens[i][0] <= '9') { |
140 key = static_cast<ui::KeyboardCode>(ui::VKEY_0 + (tokens[i][0] - '0')); | 158 key = static_cast<ui::KeyboardCode>(ui::VKEY_0 + (tokens[i][0] - '0')); |
141 } else { | 159 } else { |
142 key = ui::VKEY_UNKNOWN; | 160 key = ui::VKEY_UNKNOWN; |
143 break; | 161 break; |
144 } | 162 } |
(...skipping 18 matching lines...) Expand all Loading... | |
163 // On Mac Command can also be used in combination with Shift or on its own, | 181 // On Mac Command can also be used in combination with Shift or on its own, |
164 // as a modifier. | 182 // as a modifier. |
165 if (key == ui::VKEY_UNKNOWN || (ctrl && alt) || (command && alt) || | 183 if (key == ui::VKEY_UNKNOWN || (ctrl && alt) || (command && alt) || |
166 (shift && !ctrl && !alt && !command)) { | 184 (shift && !ctrl && !alt && !command)) { |
167 *error = ErrorUtils::FormatErrorMessageUTF16( | 185 *error = ErrorUtils::FormatErrorMessageUTF16( |
168 errors::kInvalidKeyBinding, | 186 errors::kInvalidKeyBinding, |
169 base::IntToString(index), | 187 base::IntToString(index), |
170 platform_key, | 188 platform_key, |
171 accelerator); | 189 accelerator); |
172 return ui::Accelerator(); | 190 return ui::Accelerator(); |
173 } | 191 } |
Finnur
2013/08/28 14:15:16
Add an if clause:
if ((key == ui::VKEY_MEDIA_NEXT
zhchbin
2013/08/29 14:27:11
Done.
| |
174 | 192 |
175 return ui::Accelerator(key, modifiers); | 193 return ui::Accelerator(key, modifiers); |
176 } | 194 } |
177 | 195 |
178 // For Mac, we convert "Ctrl" to "Command" and "MacCtrl" to "Ctrl". Other | 196 // For Mac, we convert "Ctrl" to "Command" and "MacCtrl" to "Ctrl". Other |
179 // platforms leave the shortcut untouched. | 197 // platforms leave the shortcut untouched. |
180 std::string NormalizeShortcutSuggestion(const std::string& suggestion, | 198 std::string NormalizeShortcutSuggestion(const std::string& suggestion, |
181 const std::string& platform) { | 199 const std::string& platform) { |
182 bool normalize = false; | 200 bool normalize = false; |
183 if (platform == values::kKeybindingPlatformMac) { | 201 if (platform == values::kKeybindingPlatformMac) { |
(...skipping 23 matching lines...) Expand all Loading... | |
207 namespace extensions { | 225 namespace extensions { |
208 | 226 |
209 Command::Command() {} | 227 Command::Command() {} |
210 | 228 |
211 Command::Command(const std::string& command_name, | 229 Command::Command(const std::string& command_name, |
212 const string16& description, | 230 const string16& description, |
213 const std::string& accelerator) | 231 const std::string& accelerator) |
214 : command_name_(command_name), | 232 : command_name_(command_name), |
215 description_(description) { | 233 description_(description) { |
216 string16 error; | 234 string16 error; |
217 accelerator_ = ParseImpl(accelerator, CommandPlatform(), 0, &error); | 235 accelerator_ = ParseImpl(accelerator, CommandPlatform(), 0, |
236 IsNamedCommand(command_name), &error); | |
218 } | 237 } |
219 | 238 |
220 Command::~Command() {} | 239 Command::~Command() {} |
221 | 240 |
222 // static | 241 // static |
223 std::string Command::CommandPlatform() { | 242 std::string Command::CommandPlatform() { |
224 #if defined(OS_WIN) | 243 #if defined(OS_WIN) |
225 return values::kKeybindingPlatformWin; | 244 return values::kKeybindingPlatformWin; |
226 #elif defined(OS_MACOSX) | 245 #elif defined(OS_MACOSX) |
227 return values::kKeybindingPlatformMac; | 246 return values::kKeybindingPlatformMac; |
228 #elif defined(OS_CHROMEOS) | 247 #elif defined(OS_CHROMEOS) |
229 return values::kKeybindingPlatformChromeOs; | 248 return values::kKeybindingPlatformChromeOs; |
230 #elif defined(OS_LINUX) | 249 #elif defined(OS_LINUX) |
231 return values::kKeybindingPlatformLinux; | 250 return values::kKeybindingPlatformLinux; |
232 #else | 251 #else |
233 return ""; | 252 return ""; |
234 #endif | 253 #endif |
235 } | 254 } |
236 | 255 |
237 // static | 256 // static |
238 ui::Accelerator Command::StringToAccelerator(const std::string& accelerator) { | 257 ui::Accelerator Command::StringToAccelerator(const std::string& accelerator, |
258 const std::string& command_name) { | |
239 string16 error; | 259 string16 error; |
240 Command command; | |
241 ui::Accelerator parsed = | 260 ui::Accelerator parsed = |
242 ParseImpl(accelerator, Command::CommandPlatform(), 0, &error); | 261 ParseImpl(accelerator, Command::CommandPlatform(), 0, |
262 IsNamedCommand(command_name), &error); | |
243 return parsed; | 263 return parsed; |
244 } | 264 } |
245 | 265 |
246 // static | 266 // static |
247 std::string Command::AcceleratorToString(const ui::Accelerator& accelerator) { | 267 std::string Command::AcceleratorToString(const ui::Accelerator& accelerator) { |
248 std::string shortcut; | 268 std::string shortcut; |
249 | 269 |
250 // Ctrl and Alt are mutually exclusive. | 270 // Ctrl and Alt are mutually exclusive. |
251 if (accelerator.IsCtrlDown()) | 271 if (accelerator.IsCtrlDown()) |
252 shortcut += values::kKeyCtrl; | 272 shortcut += values::kKeyCtrl; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 break; | 325 break; |
306 case ui::VKEY_PRIOR: | 326 case ui::VKEY_PRIOR: |
307 shortcut += values::kKeyPgUp; | 327 shortcut += values::kKeyPgUp; |
308 break; | 328 break; |
309 case ui::VKEY_NEXT: | 329 case ui::VKEY_NEXT: |
310 shortcut += values::kKeyPgDwn; | 330 shortcut += values::kKeyPgDwn; |
311 break; | 331 break; |
312 case ui::VKEY_TAB: | 332 case ui::VKEY_TAB: |
313 shortcut += values::kKeyTab; | 333 shortcut += values::kKeyTab; |
314 break; | 334 break; |
335 case ui::VKEY_MEDIA_NEXT_TRACK: | |
336 shortcut += values::kKeyMediaNextTrack; | |
337 break; | |
338 case ui::VKEY_MEDIA_PLAY_PAUSE: | |
339 shortcut += values::kKeyMediaPlayPause; | |
340 break; | |
341 case ui::VKEY_MEDIA_PREV_TRACK: | |
342 shortcut += values::kKeyMediaPrevTrack; | |
343 break; | |
344 case ui::VKEY_MEDIA_STOP: | |
345 shortcut += values::kKeyMediaStop; | |
346 break; | |
315 default: | 347 default: |
316 return ""; | 348 return ""; |
317 } | 349 } |
318 } | 350 } |
319 return shortcut; | 351 return shortcut; |
320 } | 352 } |
321 | 353 |
322 bool Command::Parse(const base::DictionaryValue* command, | 354 bool Command::Parse(const base::DictionaryValue* command, |
323 const std::string& command_name, | 355 const std::string& command_name, |
324 int index, | 356 int index, |
325 string16* error) { | 357 string16* error) { |
326 DCHECK(!command_name.empty()); | 358 DCHECK(!command_name.empty()); |
327 | 359 |
328 string16 description; | 360 string16 description; |
329 if (command_name != values::kPageActionCommandEvent && | 361 if (IsNamedCommand(command_name)) { |
330 command_name != values::kBrowserActionCommandEvent && | |
331 command_name != values::kScriptBadgeCommandEvent) { | |
332 if (!command->GetString(keys::kDescription, &description) || | 362 if (!command->GetString(keys::kDescription, &description) || |
333 description.empty()) { | 363 description.empty()) { |
334 *error = ErrorUtils::FormatErrorMessageUTF16( | 364 *error = ErrorUtils::FormatErrorMessageUTF16( |
335 errors::kInvalidKeyBindingDescription, | 365 errors::kInvalidKeyBindingDescription, |
336 base::IntToString(index)); | 366 base::IntToString(index)); |
337 return false; | 367 return false; |
338 } | 368 } |
339 } | 369 } |
340 | 370 |
341 // We'll build up a map of platform-to-shortcut suggestions. | 371 // We'll build up a map of platform-to-shortcut suggestions. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
412 | 442 |
413 // For developer convenience, we parse all the suggestions (and complain about | 443 // For developer convenience, we parse all the suggestions (and complain about |
414 // errors for platforms other than the current one) but use only what we need. | 444 // errors for platforms other than the current one) but use only what we need. |
415 std::map<const std::string, std::string>::const_iterator iter = | 445 std::map<const std::string, std::string>::const_iterator iter = |
416 suggestions.begin(); | 446 suggestions.begin(); |
417 for ( ; iter != suggestions.end(); ++iter) { | 447 for ( ; iter != suggestions.end(); ++iter) { |
418 ui::Accelerator accelerator; | 448 ui::Accelerator accelerator; |
419 if (!iter->second.empty()) { | 449 if (!iter->second.empty()) { |
420 // Note that we pass iter->first to pretend we are on a platform we're not | 450 // Note that we pass iter->first to pretend we are on a platform we're not |
421 // on. | 451 // on. |
422 accelerator = ParseImpl(iter->second, iter->first, index, error); | 452 accelerator = ParseImpl(iter->second, iter->first, index, |
453 IsNamedCommand(command_name), error); | |
423 if (accelerator.key_code() == ui::VKEY_UNKNOWN) { | 454 if (accelerator.key_code() == ui::VKEY_UNKNOWN) { |
424 *error = ErrorUtils::FormatErrorMessageUTF16( | 455 *error = ErrorUtils::FormatErrorMessageUTF16( |
425 errors::kInvalidKeyBinding, | 456 errors::kInvalidKeyBinding, |
426 base::IntToString(index), | 457 base::IntToString(index), |
427 iter->first, | 458 iter->first, |
428 iter->second); | 459 iter->second); |
429 return false; | 460 return false; |
430 } | 461 } |
431 } | 462 } |
432 | 463 |
(...skipping 23 matching lines...) Expand all Loading... | |
456 extension_data->SetString("description", command_description); | 487 extension_data->SetString("description", command_description); |
457 extension_data->SetBoolean("active", active); | 488 extension_data->SetBoolean("active", active); |
458 extension_data->SetString("keybinding", accelerator().GetShortcutText()); | 489 extension_data->SetString("keybinding", accelerator().GetShortcutText()); |
459 extension_data->SetString("command_name", command_name()); | 490 extension_data->SetString("command_name", command_name()); |
460 extension_data->SetString("extension_id", extension->id()); | 491 extension_data->SetString("extension_id", extension->id()); |
461 | 492 |
462 return extension_data; | 493 return extension_data; |
463 } | 494 } |
464 | 495 |
465 } // namespace extensions | 496 } // namespace extensions |
OLD | NEW |