OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Generate keyboard layout and hotkey data for the keyboard overlay. | 6 """Generate keyboard layout and hotkey data for the keyboard overlay. |
7 | 7 |
8 This script fetches data from the keyboard layout and hotkey data spreadsheet, | 8 This script fetches data from the keyboard layout and hotkey data spreadsheet, |
9 and output the data depending on the option. | 9 and output the data depending on the option. |
10 | 10 |
11 --cc: Rewrites a part of C++ code in | 11 --cc: Rewrites a part of C++ code in |
12 chrome/browser/chromeos/webui/keyboard_overlay_ui.cc | 12 chrome/browser/chromeos/webui/keyboard_overlay_ui.cc |
13 | 13 |
14 --grd: Rewrites a part of grd messages in | 14 --grd: Rewrites a part of grd messages in |
15 chrome/app/generated_resources.grd | 15 chrome/app/generated_resources.grd |
16 | 16 |
17 --js: Rewrites the entire JavaScript code in | 17 --js: Rewrites the entire JavaScript code in |
18 chrome/browser/resources/keyboard_overlay/keyboard_overlay_data.js | 18 chrome/browser/resources/keyboard_overlay/keyboard_overlay_data.js |
19 | 19 |
20 --altgr: Rewrites a list of layouts in | |
21 chrome/browser/chromeos/input_method/xkeyboard.cc | |
22 | |
23 These options can be specified at the same time. | 20 These options can be specified at the same time. |
24 | 21 |
25 e.g. | 22 e.g. |
26 python gen_keyboard_overlay_data.py --cc --grd --js | 23 python gen_keyboard_overlay_data.py --cc --grd --js |
27 | 24 |
28 The output directory of the generated files can be changed with --outdir. | 25 The output directory of the generated files can be changed with --outdir. |
29 | 26 |
30 e.g. (This will generate tmp/xkeyboard.cc) | 27 e.g. (This will generate tmp/keyboard_overlay.js) |
31 python gen_keyboard_overlay_data.py --outdir=tmp --altgr | 28 python gen_keyboard_overlay_data.py --outdir=tmp --js |
32 """ | 29 """ |
33 | 30 |
34 import cStringIO | 31 import cStringIO |
35 import datetime | 32 import datetime |
36 import gdata.spreadsheet.service | 33 import gdata.spreadsheet.service |
37 import getpass | 34 import getpass |
38 import json | 35 import json |
39 import optparse | 36 import optparse |
40 import os | 37 import os |
41 import re | 38 import re |
42 import sys | 39 import sys |
43 | 40 |
44 MODIFIER_SHIFT = 1 << 0 | 41 MODIFIER_SHIFT = 1 << 0 |
45 MODIFIER_CTRL = 1 << 1 | 42 MODIFIER_CTRL = 1 << 1 |
46 MODIFIER_ALT = 1 << 2 | 43 MODIFIER_ALT = 1 << 2 |
47 | 44 |
48 KEYBOARD_GLYPH_SPREADSHEET_KEY = '0Ao3KldW9piwEdExLbGR6TmZ2RU9aUjFCMmVxWkVqVmc' | 45 KEYBOARD_GLYPH_SPREADSHEET_KEY = '0Ao3KldW9piwEdExLbGR6TmZ2RU9aUjFCMmVxWkVqVmc' |
49 HOTKEY_SPREADSHEET_KEY = '0AqzoqbAMLyEPdE1RQXdodk1qVkFyTWtQbUxROVM1cXc' | 46 HOTKEY_SPREADSHEET_KEY = '0AqzoqbAMLyEPdE1RQXdodk1qVkFyTWtQbUxROVM1cXc' |
50 CC_OUTDIR = 'chrome/browser/ui/webui/chromeos' | 47 CC_OUTDIR = 'chrome/browser/ui/webui/chromeos' |
51 CC_FILENAME = 'keyboard_overlay_ui.cc' | 48 CC_FILENAME = 'keyboard_overlay_ui.cc' |
52 GRD_OUTDIR = 'chrome/app' | 49 GRD_OUTDIR = 'chrome/app' |
53 GRD_FILENAME = 'generated_resources.grd' | 50 GRD_FILENAME = 'generated_resources.grd' |
54 JS_OUTDIR = 'chrome/browser/resources/chromeos' | 51 JS_OUTDIR = 'chrome/browser/resources/chromeos' |
55 JS_FILENAME = 'keyboard_overlay_data.js' | 52 JS_FILENAME = 'keyboard_overlay_data.js' |
56 ALTGR_OUTDIR = 'chrome/browser/chromeos/input_method' | |
57 ALTGR_FILENAME = 'xkeyboard_data.h' | |
58 CC_START = r'IDS_KEYBOARD_OVERLAY_INSTRUCTIONS_HIDE },' | 53 CC_START = r'IDS_KEYBOARD_OVERLAY_INSTRUCTIONS_HIDE },' |
59 CC_END = r'};' | 54 CC_END = r'};' |
60 GRD_START = """Escape to hide | 55 GRD_START = """Escape to hide |
61 </message>""" | 56 </message>""" |
62 GRD_END = r' </if>' | 57 GRD_END = r' </if>' |
63 | 58 |
64 LABEL_MAP = { | 59 LABEL_MAP = { |
65 'glyph_arrow_down': 'down', | 60 'glyph_arrow_down': 'down', |
66 'glyph_arrow_left': 'left', | 61 'glyph_arrow_left': 'left', |
67 'glyph_arrow_right': 'right', | 62 'glyph_arrow_right': 'right', |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 # A snippet for grd file | 164 # A snippet for grd file |
170 GRD_SNIPPET_TEMPLATE=""" <message name="%s" desc="%s"> | 165 GRD_SNIPPET_TEMPLATE=""" <message name="%s" desc="%s"> |
171 %s | 166 %s |
172 </message> | 167 </message> |
173 """ | 168 """ |
174 | 169 |
175 # A snippet for C++ file | 170 # A snippet for C++ file |
176 CC_SNIPPET_TEMPLATE=""" { "%s", %s }, | 171 CC_SNIPPET_TEMPLATE=""" { "%s", %s }, |
177 """ | 172 """ |
178 | 173 |
179 ALTGR_TEMPLATE=( | |
180 """// This file was generated by 'gen_keyboard_overlay_data.py --altgr' | |
181 | |
182 #ifndef CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_DATA_H_ | |
183 #define CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_DATA_H_ | |
184 | |
185 namespace chromeos { | |
186 namespace input_method { | |
187 | |
188 // These are the input method IDs that shouldn't remap the right alt key. | |
189 const char* kKeepRightAltInputMethods[] = { | |
190 %s | |
191 }; | |
192 | |
193 // These are the overlay names with caps lock remapped | |
194 const char* kCapsLockRemapped[] = { | |
195 %s | |
196 }; | |
197 | |
198 } // input_method | |
199 } // chromeos | |
200 | |
201 #endif // CHROME_BROWSER_CHROMEOS_INPUT_METHOD_XKEYBOARD_DATA_H_ | |
202 """) | |
203 | 174 |
204 def SplitBehavior(behavior): | 175 def SplitBehavior(behavior): |
205 """Splits the behavior to compose a message or i18n-content value. | 176 """Splits the behavior to compose a message or i18n-content value. |
206 | 177 |
207 Examples: | 178 Examples: |
208 'Activate last tab' => ['Activate', 'last', 'tab'] | 179 'Activate last tab' => ['Activate', 'last', 'tab'] |
209 'Close tab' => ['Close', 'tab'] | 180 'Close tab' => ['Close', 'tab'] |
210 """ | 181 """ |
211 return [x for x in re.split('[ ()"-.,]', behavior) if len(x) > 0] | 182 return [x for x in re.split('[ ()"-.,]', behavior) if len(x) > 0] |
212 | 183 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 parser.add_option('--password', dest='password', | 249 parser.add_option('--password', dest='password', |
279 help='Your password.') | 250 help='Your password.') |
280 parser.add_option('--account_type', default='GOOGLE', dest='account_type', | 251 parser.add_option('--account_type', default='GOOGLE', dest='account_type', |
281 help='Account type used for gdata login (default: GOOGLE)') | 252 help='Account type used for gdata login (default: GOOGLE)') |
282 parser.add_option('--js', dest='js', default=False, action='store_true', | 253 parser.add_option('--js', dest='js', default=False, action='store_true', |
283 help='Output js file.') | 254 help='Output js file.') |
284 parser.add_option('--grd', dest='grd', default=False, action='store_true', | 255 parser.add_option('--grd', dest='grd', default=False, action='store_true', |
285 help='Output resource file.') | 256 help='Output resource file.') |
286 parser.add_option('--cc', dest='cc', default=False, action='store_true', | 257 parser.add_option('--cc', dest='cc', default=False, action='store_true', |
287 help='Output cc file.') | 258 help='Output cc file.') |
288 parser.add_option('--altgr', dest='altgr', default=False, action='store_true', | |
289 help='Output altgr file.') | |
290 parser.add_option('--outdir', dest='outdir', default=None, | 259 parser.add_option('--outdir', dest='outdir', default=None, |
291 help='Specify the directory files are generated.') | 260 help='Specify the directory files are generated.') |
292 (options, unused_args) = parser.parse_args() | 261 (options, unused_args) = parser.parse_args() |
293 | 262 |
294 if not options.username.endswith('google.com'): | 263 if not options.username.endswith('google.com'): |
295 print 'google.com account is necessary to use this script.' | 264 print 'google.com account is necessary to use this script.' |
296 sys.exit(-1) | 265 sys.exit(-1) |
297 | 266 |
298 if (not (options.js or options.grd or options.cc or options.altgr)): | 267 if (not (options.js or options.grd or options.cc)): |
299 print 'Either --js, --grd, --cc or --altgr needs to be specified.' | 268 print 'Either --js, --grd, or --cc needs to be specified.' |
300 sys.exit(-1) | 269 sys.exit(-1) |
301 | 270 |
302 # Get the password from the terminal, if needed. | 271 # Get the password from the terminal, if needed. |
303 if not options.password: | 272 if not options.password: |
304 options.password = getpass.getpass( | 273 options.password = getpass.getpass( |
305 'Application specific password for %s: ' % options.username) | 274 'Application specific password for %s: ' % options.username) |
306 return options | 275 return options |
307 | 276 |
308 | 277 |
309 def InitClient(options): | 278 def InitClient(options): |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 output = CC_SNIPPET_TEMPLATE % (Toi18nContent(behavior), message_name) | 497 output = CC_SNIPPET_TEMPLATE % (Toi18nContent(behavior), message_name) |
529 # Break the line if the line is longer than 80 characters | 498 # Break the line if the line is longer than 80 characters |
530 if len(output) > 80: | 499 if len(output) > 80: |
531 output = output.replace(' ' + message_name, '\n %s' % message_name) | 500 output = output.replace(' ' + message_name, '\n %s' % message_name) |
532 snippet.write(output) | 501 snippet.write(output) |
533 | 502 |
534 RewriteFile(CC_START, CC_END, CC_OUTDIR, CC_FILENAME, snippet.getvalue(), | 503 RewriteFile(CC_START, CC_END, CC_OUTDIR, CC_FILENAME, snippet.getvalue(), |
535 outdir) | 504 outdir) |
536 | 505 |
537 | 506 |
538 def OutputAltGr(keyboard_glyph_data, outdir): | |
539 """Outputs the keyboard overlay data as a JSON file.""" | |
540 altgr_output = [] | |
541 caps_lock_output = [] | |
542 | |
543 for input_method_id, layout in INPUT_METHOD_ID_TO_OVERLAY_ID.iteritems(): | |
544 try: | |
545 # If left and right alt have different values, this layout to the list of | |
546 # layouts that don't remap the right alt key. | |
547 right_alt = keyboard_glyph_data[layout]["keys"]["E0 38"]["label"].strip() | |
548 left_alt = keyboard_glyph_data[layout]["keys"]["38"]["label"].strip() | |
549 if right_alt.lower() != left_alt.lower(): | |
550 altgr_output.append(' "%s",' % input_method_id) | |
551 except KeyError: | |
552 pass | |
553 | |
554 try: | |
555 caps_lock = keyboard_glyph_data[layout]["keys"]["E0 5B"]["label"].strip() | |
556 if caps_lock.lower() != "search": | |
557 caps_lock_output.append(' "%s",' % input_method_id) | |
558 except KeyError: | |
559 pass | |
560 | |
561 if not outdir: | |
562 outdir = ALTGR_OUTDIR | |
563 outpath = GetPath(os.path.join(outdir, ALTGR_FILENAME)) | |
564 snippet = ALTGR_TEMPLATE % ("\n".join(sorted(altgr_output)), | |
565 "\n".join(sorted(caps_lock_output))) | |
566 OutputFile(outpath, snippet) | |
567 | |
568 | |
569 def main(): | 507 def main(): |
570 options = ParseOptions() | 508 options = ParseOptions() |
571 client = InitClient(options) | 509 client = InitClient(options) |
572 hotkey_data = FetchHotkeyData(client) | 510 hotkey_data = FetchHotkeyData(client) |
573 | 511 |
574 if options.js or options.altgr: | 512 if options.js: |
575 keyboard_glyph_data = FetchKeyboardGlyphData(client) | 513 keyboard_glyph_data = FetchKeyboardGlyphData(client) |
576 | 514 |
577 if options.js: | 515 if options.js: |
578 layouts = FetchLayoutsData(client) | 516 layouts = FetchLayoutsData(client) |
579 OutputJson(keyboard_glyph_data, hotkey_data, layouts, 'keyboardOverlayData', | 517 OutputJson(keyboard_glyph_data, hotkey_data, layouts, 'keyboardOverlayData', |
580 options.outdir) | 518 options.outdir) |
581 if options.grd: | 519 if options.grd: |
582 OutputGrd(hotkey_data, options.outdir) | 520 OutputGrd(hotkey_data, options.outdir) |
583 if options.cc: | 521 if options.cc: |
584 OutputCC(hotkey_data, options.outdir) | 522 OutputCC(hotkey_data, options.outdir) |
585 if options.altgr: | |
586 OutputAltGr(keyboard_glyph_data, options.outdir) | |
587 | 523 |
588 | 524 |
589 if __name__ == '__main__': | 525 if __name__ == '__main__': |
590 main() | 526 main() |
OLD | NEW |