1#!/usr/bin/env python 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 4# found in the LICENSE file. 5 6'''Stuff to prevent conflicting shortcuts. 7''' 8 9from grit import lazy_re 10 11 12class ShortcutGroup(object): 13 '''Manages a list of cliques that belong together in a single shortcut 14 group. Knows how to detect conflicting shortcut keys. 15 ''' 16 17 # Matches shortcut keys, e.g. &J 18 SHORTCUT_RE = lazy_re.compile('([^&]|^)(&[A-Za-z])') 19 20 def __init__(self, name): 21 self.name = name 22 # Map of language codes to shortcut keys used (which is a map of 23 # shortcut keys to counts). 24 self.keys_by_lang = {} 25 # List of cliques in this group 26 self.cliques = [] 27 28 def AddClique(self, c): 29 for existing_clique in self.cliques: 30 if existing_clique.GetId() == c.GetId(): 31 # This happens e.g. when we have e.g. 32 # <if expr1><structure 1></if> <if expr2><structure 2></if> 33 # where only one will really be included in the output. 34 return 35 36 self.cliques.append(c) 37 for (lang, msg) in c.clique.items(): 38 if lang not in self.keys_by_lang: 39 self.keys_by_lang[lang] = {} 40 keymap = self.keys_by_lang[lang] 41 42 content = msg.GetRealContent() 43 keys = [groups[1] for groups in self.SHORTCUT_RE.findall(content)] 44 for key in keys: 45 key = key.upper() 46 if key in keymap: 47 keymap[key] += 1 48 else: 49 keymap[key] = 1 50 51 def GenerateWarnings(self, tc_project): 52 # For any language that has more than one occurrence of any shortcut, 53 # make a list of the conflicting shortcuts. 54 problem_langs = {} 55 for (lang, keys) in self.keys_by_lang.items(): 56 for (key, count) in keys.items(): 57 if count > 1: 58 if lang not in problem_langs: 59 problem_langs[lang] = [] 60 problem_langs[lang].append(key) 61 62 warnings = [] 63 if len(problem_langs): 64 warnings.append("WARNING - duplicate keys exist in shortcut group %s" % 65 self.name) 66 for (lang,keys) in problem_langs.items(): 67 warnings.append(" %6s duplicates: %s" % (lang, ', '.join(keys))) 68 return warnings 69 70 71def GenerateDuplicateShortcutsWarnings(uberclique, tc_project): 72 '''Given an UberClique and a project name, will print out helpful warnings 73 if there are conflicting shortcuts within shortcut groups in the provided 74 UberClique. 75 76 Args: 77 uberclique: clique.UberClique() 78 tc_project: 'MyProjectNameInTheTranslationConsole' 79 80 Returns: 81 ['warning line 1', 'warning line 2', ...] 82 ''' 83 warnings = [] 84 groups = {} 85 for c in uberclique.AllCliques(): 86 for group in c.shortcut_groups: 87 if group not in groups: 88 groups[group] = ShortcutGroup(group) 89 groups[group].AddClique(c) 90 for group in groups.values(): 91 warnings += group.GenerateWarnings(tc_project) 92 return warnings 93 94