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

Side by Side Diff: chrome/common/extensions/extension_commands.cc

Issue 10387224: Rename ExtensionCommand* to Command* within the extension namespace. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 7 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/extensions/extension_commands.h"
6
7 #include "base/logging.h"
8 #include "base/string_number_conversions.h"
9 #include "base/string_split.h"
10 #include "base/values.h"
11 #include "chrome/common/extensions/extension_error_utils.h"
12 #include "chrome/common/extensions/extension_manifest_constants.h"
13 #include "grit/generated_resources.h"
14 #include "ui/base/l10n/l10n_util.h"
15
16 namespace errors = extension_manifest_errors;
17 namespace keys = extension_manifest_keys;
18 namespace values = extension_manifest_values;
19
20 namespace extensions {
21
22 Command::Command() {}
23
24 Command::~Command() {}
25
26 ui::Accelerator Command::ParseImpl(
27 const std::string& shortcut,
28 const std::string& platform_key,
29 int index,
30 string16* error) {
31 if (platform_key != values::kKeybindingPlatformWin &&
32 platform_key != values::kKeybindingPlatformMac &&
33 platform_key != values::kKeybindingPlatformChromeOs &&
34 platform_key != values::kKeybindingPlatformLinux &&
35 platform_key != values::kKeybindingPlatformDefault) {
36 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
37 errors::kInvalidKeyBindingUnknownPlatform,
38 base::IntToString(index),
39 platform_key);
40 return ui::Accelerator();
41 }
42
43 std::vector<std::string> tokens;
44 base::SplitString(shortcut, '+', &tokens);
45 if (tokens.size() < 2 || tokens.size() > 3) {
46 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
47 errors::kInvalidKeyBinding,
48 base::IntToString(index),
49 platform_key,
50 shortcut);
51 return ui::Accelerator();
52 }
53
54 // Now, parse it into an accelerator.
55 int modifiers = ui::EF_NONE;
56 ui::KeyboardCode key = ui::VKEY_UNKNOWN;
57 for (size_t i = 0; i < tokens.size(); i++) {
58 if (tokens[i] == "Ctrl") {
59 modifiers |= ui::EF_CONTROL_DOWN;
60 } else if (tokens[i] == "Alt") {
61 modifiers |= ui::EF_ALT_DOWN;
62 } else if (tokens[i] == "Shift") {
63 modifiers |= ui::EF_SHIFT_DOWN;
64 } else if (tokens[i] == "Command" && platform_key == "mac") {
65 // TODO(finnur): Implement for Mac.
66 } else if (tokens[i] == "Option" && platform_key == "mac") {
67 // TODO(finnur): Implement for Mac.
68 } else if (tokens[i].size() == 1 &&
69 tokens[i][0] >= 'A' && tokens[i][0] <= 'Z') {
70 if (key != ui::VKEY_UNKNOWN) {
71 // Multiple key assignments.
72 key = ui::VKEY_UNKNOWN;
73 break;
74 }
75
76 key = static_cast<ui::KeyboardCode>(ui::VKEY_A + (tokens[i][0] - 'A'));
77 } else {
78 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
79 errors::kInvalidKeyBinding,
80 base::IntToString(index),
81 platform_key,
82 shortcut);
83 return ui::Accelerator();
84 }
85 }
86 bool ctrl = (modifiers & ui::EF_CONTROL_DOWN) != 0;
87 bool alt = (modifiers & ui::EF_ALT_DOWN) != 0;
88 // We support Ctrl+foo, Alt+foo, Ctrl+Shift+foo, Alt+Shift+foo, but not
89 // Ctrl+Alt+foo. For a more detailed reason why we don't support Ctrl+Alt+foo:
90 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/29/101121.aspx.
91 if (key == ui::VKEY_UNKNOWN || (ctrl && alt)) {
92 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
93 errors::kInvalidKeyBinding,
94 base::IntToString(index),
95 platform_key,
96 shortcut);
97 return ui::Accelerator();
98 }
99
100 return ui::Accelerator(key, modifiers);
101 }
102
103 // static
104 std::string Command::CommandPlatform() {
105 #if defined(OS_WIN)
106 return values::kKeybindingPlatformWin;
107 #elif defined(OS_MACOSX)
108 return values::kKeybindingPlatformMac;
109 #elif defined(OS_CHROMEOS)
110 return values::kKeybindingPlatformChromeOs;
111 #elif defined(OS_LINUX)
112 return values::kKeybindingPlatformLinux;
113 #else
114 return "";
115 #endif
116 }
117
118 bool Command::Parse(DictionaryValue* command,
119 const std::string& command_name,
120 int index,
121 string16* error) {
122 DCHECK(!command_name.empty());
123
124 // We'll build up a map of platform-to-shortcut suggestions.
125 std::map<const std::string, std::string> suggestions;
126
127 // First try to parse the |suggested_key| as a dictionary.
128 DictionaryValue* suggested_key_dict;
129 if (command->GetDictionary(keys::kSuggestedKey, &suggested_key_dict)) {
130 DictionaryValue::key_iterator iter = suggested_key_dict->begin_keys();
131 for ( ; iter != suggested_key_dict->end_keys(); ++iter) {
132 // For each item in the dictionary, extract the platforms specified.
133 std::string suggested_key_string;
134 if (suggested_key_dict->GetString(*iter, &suggested_key_string) &&
135 !suggested_key_string.empty()) {
136 // Found a platform, add it to the suggestions list.
137 suggestions[*iter] = suggested_key_string;
138 } else {
139 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
140 errors::kInvalidKeyBinding,
141 base::IntToString(index),
142 keys::kSuggestedKey,
143 "Missing");
144 return false;
145 }
146 }
147 } else {
148 // No dictionary was found, fall back to using just a string, so developers
149 // don't have to specify a dictionary if they just want to use one default
150 // for all platforms.
151 std::string suggested_key_string;
152 if (command->GetString(keys::kSuggestedKey, &suggested_key_string) &&
153 !suggested_key_string.empty()) {
154 // If only a signle string is provided, it must be default for all.
155 suggestions["default"] = suggested_key_string;
156 } else {
157 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
158 errors::kInvalidKeyBinding,
159 base::IntToString(index),
160 keys::kSuggestedKey,
161 "Missing");
162 return false;
163 }
164 }
165
166 std::string platform = CommandPlatform();
167 std::string key = platform;
168 if (suggestions.find(key) == suggestions.end())
169 key = values::kKeybindingPlatformDefault;
170 if (suggestions.find(key) == suggestions.end()) {
171 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
172 errors::kInvalidKeyBindingMissingPlatform,
173 base::IntToString(index),
174 keys::kSuggestedKey,
175 platform);
176 return false; // No platform specified and no fallback. Bail.
177 }
178
179 // For developer convenience, we parse all the suggestions (and complain about
180 // errors for platforms other than the current one) but use only what we need.
181 std::map<const std::string, std::string>::const_iterator iter =
182 suggestions.begin();
183 for ( ; iter != suggestions.end(); ++iter) {
184 // Note that we pass iter->first to pretend we are on a platform we're not
185 // on.
186 ui::Accelerator accelerator =
187 ParseImpl(iter->second, iter->first, index, error);
188 if (accelerator.key_code() == ui::VKEY_UNKNOWN) {
189 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
190 errors::kInvalidKeyBinding,
191 base::IntToString(index),
192 iter->first,
193 iter->second);
194 return false;
195 }
196
197 if (iter->first == key) {
198 // This platform is our platform, so grab this key.
199 accelerator_ = accelerator;
200 command_name_ = command_name;
201
202 if (command_name !=
203 extension_manifest_values::kPageActionKeybindingEvent &&
204 command_name !=
205 extension_manifest_values::kBrowserActionKeybindingEvent) {
206 if (!command->GetString(keys::kDescription, &description_) ||
207 description_.empty()) {
208 *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
209 errors::kInvalidKeyBindingDescription,
210 base::IntToString(index));
211 return false;
212 }
213 }
214 }
215 }
216 return true;
217 }
218
219 DictionaryValue* Command::ToValue(const Extension* extension,
220 bool active) const {
221 DictionaryValue* extension_data = new DictionaryValue();
222
223 string16 command_description;
224 if (command_name() == values::kBrowserActionKeybindingEvent ||
225 command_name() == values::kPageActionKeybindingEvent) {
226 command_description =
227 l10n_util::GetStringUTF16(IDS_EXTENSION_COMMANDS_GENERIC_ACTIVATE);
228 } else {
229 command_description = description();
230 }
231 extension_data->SetString("description", command_description);
232 extension_data->SetBoolean("active", active);
233 extension_data->SetString("keybinding", accelerator().GetShortcutText());
234
235 return extension_data;
236 }
237
238 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/extension_commands.h ('k') | chrome/common/extensions/extension_commands_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698