pywinauto/sandbox/playing_RepeatedHotkeyFixing.py
2006-01-05 18:20:19 +00:00

316 lines
7.6 KiB
Python

# 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)