# GUI Application automation and testing library # Copyright (C) 2006 Mark Mc Mahon # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation; either version 2.1 # of the License, or (at your option) any later version. # # This library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the # Free Software Foundation, Inc., # 59 Temple Place, # Suite 330, # Boston, MA 02111-1307 USA #import set from Test_RepeatedHotkey import GetHotkey controls = ( "&Hello", "&Exit", "&OK", "&Python", "&Ion Trail", "&Galaxy Quest", "&Xenon", "&Sierra", "&Zope", "&Sizzling", "Here &and Now", "&Later maybe", "&Scram", "Wo&w", "What is T&HAT", "&Mercury", "&Venus", "&Earth", "M&ercury", "Ven&us", "Ea&rth", "&Mercury", "&OK", "&Python", "&Ion Trail", "&Galaxy Quest", ) charIndex = {} hotkeyCtrls = {} allChars = set() for ctrl in controls: # try to build up information on the dialog first # e.g. if it's possible to fix at all # any controls that have a unique character hotkeyCtrls.setdefault(GetHotkey(ctrl)[1].lower(), []).append(ctrl) allChars = allChars.union(set(ctrl.lower())) for c in ctrl: if c in ' _&': continue charIndex.setdefault(c.lower(), []).append(ctrl) allChars.difference_update(" _&") freeChars = allChars.difference(hotkeyCtrls.keys()) print freeChars for c in hotkeyCtrls: print c for ctrl in hotkeyCtrls[c]: print "\t", ctrl if len(allChars) < len(controls): print "impossible to fix completely because there are more hotkeys then individual characters in the dialog" print "the following characters are free:" #for c in freeChars: # print "\t%s"% c # for ctrl in charIndex[c]: # print "\t\t%s" % ctrl usedChars = hotkeyCtrls.keys() changesMade = 1 while changesMade: changesMade = 0 for char, ctrls in charIndex.items(): # if there is only one control that has this character if len (ctrls) == 1: # get the control ctrl = ctrls[0] # find the hotkey for that control ctrlHotkey = GetHotkey(ctrl)[1].lower() print ctrlHotkey, `ctrl` # remove the control from the list hotkeyCtrls[ctrlHotkey].remove(ctrl) # if there are now now controls for that hotkey # remove it if len(hotkeyCtrls[ctrlHotkey]) == 0: del(hotkeyCtrls[ctrlHotkey]) # add the new changed one to the hotkeys hotkeyCtrls.setdefault(char, []).append(ctrl) changesMade = 1 else: for hotkey, ctrls in hotkeyCtrls.items(): if len(ctrls) > 1: for ctrl in ctrls: ctrlChars = set(ctrl.lower()).difference(" &_") if freeChars.intersection(ctrlChars): print "="*100 for c in hotkeyCtrls: print c for ctrl in hotkeyCtrls[c]: print "\t", ctrl #for x in charIndex: # print x, charIndex[x] for hotkey, ctrls in hotkeyCtrls.items(): if len(ctrls) > 1: print "***** BUG *****" print "\t", hotkey, ctrls # find the chars free for each control ctrlFree = [] for ctrl in ctrls: ctrlFree.append("".join(set(ctrl.lower()).intersection(freeChars))) # count the controls with no hotkey free countNotFree = len([c for c in ctrlFree if not c]) if countNotFree > 1: print "Cannot be fixed without possibly changing other controls also" for i, free in enumerate(ctrlFree): if not free: print "Must leave '%s' alone" %ctrls[i] import sys sys.exit() #================================================ #================================================ #================================================ #================================================ #================================================ # return the controls that have characters in common with # the control def GetCtrlsWithSameChars(ctrl, controls): ourChars = set(ctrl.lower()) ourChars.difference_update("& _") toRet = [] for control in controls: ctrlChars = set(control.lower()) if ourChars.intersection(ctrlChars): toRet.append(control) return toRet def GetFreeCharsForControls(allFree, controls): ctrlFree = [] allCtrlsFree = [] for ctrl in controls: curCtrlFree = set(ctrl.lower()).intersection(allFree) ctrlFree.append("".join(curCtrlFree)) allCtrlsFree.extend(curCtrlFree) return ctrlFree, "".join(allCtrlsFree) charIndex = {} hotkeyCtrls = {} for c in controls: hotkeyCtrls.setdefault(GetHotkey(c)[1].lower(), []).append(c) for char in c.lower(): charIndex.setdefault(char, []).append(c) hotkeys = set(hotkeyCtrls.keys()) allKeys = set("".join(controls).lower()) allKeys.difference_update("& _") freeKeys = allKeys.difference(hotkeys) print len(controls) if len(controls) > len(allKeys): print "**** Oops - more hotkeys than available characters :-( " for hotkey, ctrls in hotkeyCtrls.items(): if len(ctrls) > 1: print "**bug**" # can it be fixed simply by changing one or more of the controls # to another character within these controls ctrlsFreeChars, allFree = GetFreeCharsForControls(freeKeys, ctrls) # find out if we can use this method (0 or 1 controls with no free characters) noFreeCount = 0 for i, ctrl in enumerate(ctrls): if not ctrlsFreeChars[i]: noFreeCount += 1 # ok - so more than one control has no free chars - can't use the # simple method if noFreeCount > 1: print "cant use that method" continue if noFreeCount == 0: extraText = ' or leave the same' else: extraText = '' for i, ctrl in enumerate(ctrls): if len(ctrlsFreeChars[i]) > 1: print "Change '%s' to one of (%s)%s"% (ctrl, "".join(ctrlsFreeChars[i]), extraText) elif len(ctrlsFreeChars[i]) == 1: print "Change '%s' to %s%s"% (ctrl, "".join(ctrlsFreeChars[i]), extraText) else: print "do not change %s" % ctrl # # for curCtrl in ctrls: # # Get the letters that could be used # ctrlAvl = set(curCtrl.lower()).intersection(freeKeys) # # #changesNeeded = '' # # # if there are no free letters in that control # # try and find if any other control could have it's # # hotkey changed to free up for ourself # if len(ctrlAvl) == 0: # # # get the controls that share some letters # otherCtrls = GetCtrlsWithSameChars(c, controls) # # suggestedChanges = [] # # check if any of the letters in those controls can be freed up # for otherCtrl in otherCtrls: # if GetHotkey(otherCtrl)[1].lower() == hotkey: # freeOther = set(otherCtrl.lower()).intersection(freeKeys) # # if freeOther: # print "To Fix %s Free %s in %s by changing to any of (%s)"%(curCtrl, GetHotkey(otherCtrl)[1], otherCtrl, "".join(freeOther)) # # # ## posChange = set(c.lower()).intersection(allKeys) ## changesNeeded = "".join(posChange) ## ## for char in posChange: ## # get the controls that have that character ## otherCtrls = charIndex[char] ## # else: # print "To fix %s change %s to any of (%s)"% (curCtrl, c, "".join(ctrlAvl)) # # #print "bug", ctrls, "".join(freeKeys)