8
8
from i18n import TranslatableString
10
10
def stringMatches(scriptName, reportedName):
11
assert isinstance(scriptName, TranslatableString)
13
return scriptName.matchedBy(reportedName)
11
assert isinstance(scriptName, TranslatableString)
13
return scriptName.matchedBy(reportedName)
15
15
def makeScriptRecursiveArgument(isRecursive, defaultValue):
16
if isRecursive==defaultValue:
19
return ", recursive=%s"%isRecursive
16
if isRecursive==defaultValue:
19
return ", recursive=%s"%isRecursive
21
21
def makeCamel(string):
23
Convert string to camelCaps
26
# FIXME: this function is probably really fragile, lots of difficult cases here
23
Convert string to camelCaps
26
# FIXME: this function is probably really fragile, lots of difficult cases here
28
# Sanitize string, replacing bad characters with spaces:
29
for char in ":;!@#$%^&*()-+=_~`\\/?|[]{}<>,.\t\n\r\"'":
30
string = string.replace(char, " ")
31
words = string.strip().split(" ")
37
lowercaseWord = word.lower()
39
result += lowercaseWord
42
result += lowercaseWord.capitalize()
28
# Sanitize string, replacing bad characters with spaces:
29
for char in ":;!@#$%^&*()-+=_~`\\/?|[]{}<>,.\t\n\r\"'":
30
string = string.replace(char, " ")
31
words = string.strip().split(" ")
37
lowercaseWord = word.lower()
39
result += lowercaseWord
42
result += lowercaseWord.capitalize()
46
"""Abstract base class representing a predicate function on nodes.
48
It's more than just a function in that it has data and can describe itself"""
49
def satisfiedByNode(self, node):
50
"""Pure virtual method returning a boolean if the predicate is satisfied by the node"""
51
raise NotImplementedError
53
def describeSearchResult(self, node):
54
raise NotImplementedError
56
def makeScriptMethodCall(self, isRecursive):
58
Method to generate a string containing a (hopefully) readable search
59
method call on a node (to be used when generating Python source code in
62
raise NotImplementedError
64
def makeScriptVariableName(self):
66
Method to generate a string containing a (hopefully) readable name
67
for a Node instance variable that would be the result of a search on
68
this predicate (to be used when generating Python source code in the
71
raise NotImplementedError
73
def __eq__(self, other):
75
Predicates are considered equal if they are of the same subclass and
78
# print "predeq: self:%s"%self
79
# print " other:%s"%other
80
# print "predeq: selfdict:%s"%self.__dict__
81
# print " otherdict:%s"%other.__dict__
83
if type(self)!=type(other):
86
return self.__dict__ == other.__dict__
46
"""Abstract base class representing a predicate function on nodes.
48
It's more than just a function in that it has data and can describe itself"""
49
def satisfiedByNode(self, node):
50
"""Pure virtual method returning a boolean if the predicate is satisfied by the node"""
51
raise NotImplementedError
53
def describeSearchResult(self, node):
54
raise NotImplementedError
56
def makeScriptMethodCall(self, isRecursive):
58
Method to generate a string containing a (hopefully) readable search
59
method call on a node (to be used when generating Python source code in
62
raise NotImplementedError
64
def makeScriptVariableName(self):
66
Method to generate a string containing a (hopefully) readable name
67
for a Node instance variable that would be the result of a search on
68
this predicate (to be used when generating Python source code in the
71
raise NotImplementedError
73
def __eq__(self, other):
75
Predicates are considered equal if they are of the same subclass and
78
# print "predeq: self:%s"%self
79
# print " other:%s"%other
80
# print "predeq: selfdict:%s"%self.__dict__
81
# print " otherdict:%s"%other.__dict__
83
if type(self)!=type(other):
86
return self.__dict__ == other.__dict__
89
89
class IsAnApplicationNamed(Predicate):
90
"""Search subclass that looks for an application by name"""
91
def __init__(self, appName):
92
self.appName = TranslatableString(appName)
94
def satisfiedByNode(self, node):
95
return node.roleName=='application' and stringMatches(self.appName, node.name)
97
def describeSearchResult(self):
98
return '%s application'%self.appName
100
def makeScriptMethodCall(self, isRecursive):
101
# ignores the isRecursive parameter
102
return "application('%s')"%self.appName
104
def makeScriptVariableName(self):
105
return makeCamel(self.appName)+"App"
90
"""Search subclass that looks for an application by name"""
91
def __init__(self, appName):
92
self.appName = TranslatableString(appName)
93
self.debugName = self.describeSearchResult()
95
def satisfiedByNode(self, node):
96
return node.roleName=='application' and stringMatches(self.appName, node.name)
98
def describeSearchResult(self):
99
return '%s application'%self.appName
101
def makeScriptMethodCall(self, isRecursive):
102
# ignores the isRecursive parameter
103
return "application(%s)"%self.appName
105
def makeScriptVariableName(self):
106
return makeCamel(self.appName)+"App"
107
108
class GenericPredicate(Predicate):
108
"""SubtreePredicate subclass that takes various optional search fields"""
110
def __init__(self, name = None, roleName = None, description= None, label = None, debugName=None):
112
self.name = TranslatableString(name)
115
self.roleName = roleName
116
self.description = description
118
self.label = TranslatableString(label)
123
self.debugName = debugName
126
self.debugName = "labelled '%s'"%self.label
128
self.debugName = "child with"
130
self.debugName += " name=%s" % self.name
132
self.debugName += " roleName='%s'"%roleName
134
self.debugName += " description='%s'"%description
135
assert self.debugName
138
def satisfiedByNode(self, node):
139
# labelled nodes are handled specially:
141
# this reverses the search; we're looking for a node with LABELLED_BY
142
# and then checking the label, rather than looking for a label and
143
# then returning whatever LABEL_FOR targets
145
return stringMatches(self.label, node.labeller.name)
148
# Ensure the node matches any criteria that were set:
150
if not stringMatches(self.name,node.name): return False
152
if self.roleName!=node.roleName: return False
154
if self.description!=node.description: return False
157
def describeSearchResult(self):
158
return self.debugName
160
def makeScriptMethodCall(self, isRecursive):
162
args = "label='%s'"%label
166
args += " name='%s'"%self.name
168
args += " roleName='%s'"%self.roleName
170
args += " description='%s'"%self.description
171
return "child(%s%s)"%(args, makeScriptRecursiveArgument(isRecursive, True))
173
def makeScriptVariableName(self):
175
return makeCamel(self.label)+"Node"
178
return makeCamel(self.name)+"Node"
180
return makeCamel(self.roleName)+"Node"
182
return makeCamel(self.description)+"Node"
109
"""SubtreePredicate subclass that takes various optional search fields"""
111
def __init__(self, name = None, roleName = None, description= None, label = None, debugName=None):
113
self.name = TranslatableString(name)
116
self.roleName = roleName
117
self.description = description
119
self.label = TranslatableString(label)
124
self.debugName = debugName
127
self.debugName = "labelled '%s'"%self.label
129
self.debugName = "child with"
131
self.debugName += " name=%s" % self.name
133
self.debugName += " roleName='%s'"%roleName
135
self.debugName += " description='%s'"%description
136
assert self.debugName
139
def satisfiedByNode(self, node):
140
# labelled nodes are handled specially:
142
# this reverses the search; we're looking for a node with LABELLED_BY
143
# and then checking the label, rather than looking for a label and
144
# then returning whatever LABEL_FOR targets
146
return stringMatches(self.label, node.labeller.name)
149
# Ensure the node matches any criteria that were set:
151
if not stringMatches(self.name,node.name): return False
153
if self.roleName!=node.roleName: return False
155
if self.description!=node.description: return False
158
def describeSearchResult(self):
159
return self.debugName
161
def makeScriptMethodCall(self, isRecursive):
163
args = "label=%s"%label
167
args += " name=%s"%self.name
169
args += " roleName=%s"%self.roleName
171
args += " description=%s"%self.description
172
return "child(%s%s)"%(args, makeScriptRecursiveArgument(isRecursive, True))
174
def makeScriptVariableName(self):
176
return makeCamel(self.label)+"Node"
179
return makeCamel(self.name)+"Node"
181
return makeCamel(self.roleName)+"Node"
183
return makeCamel(self.description)+"Node"
184
185
class IsNamed(Predicate):
185
"""Predicate subclass that looks simply by name"""
187
def __init__(self, name):
188
self.name = TranslatableString(name)
190
def satisfiedByNode(self, node):
191
return stringMatches(self.name, node.name)
193
def describeSearchResult(self):
194
return "named %s"%self.name
196
def makeScriptMethodCall(self, isRecursive):
197
return "child(name='%s'%s)"%(self.name, makeScriptRecursiveArgument(isRecursive, True))
198
def makeScriptVariableName(self):
199
return makeCamel(self.name)+"Node"
186
"""Predicate subclass that looks simply by name"""
188
def __init__(self, name):
189
self.name = TranslatableString(name)
190
self.debugName = self.describeSearchResult()
192
def satisfiedByNode(self, node):
193
return stringMatches(self.name, node.name)
195
def describeSearchResult(self):
196
return "named %s"%self.name
198
def makeScriptMethodCall(self, isRecursive):
199
return "child(name=%s%s)"%(self.name, makeScriptRecursiveArgument(isRecursive, True))
200
def makeScriptVariableName(self):
201
return makeCamel(self.name)+"Node"
201
203
class IsAWindowNamed(Predicate):
202
"""Predicate subclass that looks for a top-level window by name"""
203
def __init__(self, windowName):
204
self.windowName = TranslatableString(windowName)
206
def satisfiedByNode(self, node):
207
return node.roleName=='frame' and stringMatches(self.windowName, node.name)
209
def describeSearchResult(self):
210
return "%s window"%self.windowName
212
def makeScriptMethodCall(self, isRecursive):
213
return "window('%s'%s)"%(self.windowName, makeScriptRecursiveArgument(isRecursive, False))
215
def makeScriptVariableName(self):
216
return makeCamel(self.windowName)+"Win"
204
"""Predicate subclass that looks for a top-level window by name"""
205
def __init__(self, windowName):
206
self.windowName = TranslatableString(windowName)
207
self.debugName = self.describeSearchResult()
209
def satisfiedByNode(self, node):
210
return node.roleName=='frame' and stringMatches(self.windowName, node.name)
212
def describeSearchResult(self):
213
return "%s window"%self.windowName
215
def makeScriptMethodCall(self, isRecursive):
216
return "window(%s%s)"%(self.windowName, makeScriptRecursiveArgument(isRecursive, False))
218
def makeScriptVariableName(self):
219
return makeCamel(self.windowName)+"Win"
218
221
class IsAWindow(Predicate):
219
"""Predicate subclass that looks for top-level windows"""
220
def satisfiedByNode(self, node):
221
return node.roleName=='frame'
222
"""Predicate subclass that looks for top-level windows"""
223
def satisfiedByNode(self, node):
224
return node.roleName=='frame'
223
def describeSearchResult(self):
226
def describeSearchResult(self):
226
229
class IsADialogNamed(Predicate):
227
"""Predicate subclass that looks for a top-level dialog by name"""
228
def __init__(self, dialogName):
229
self.dialogName = TranslatableString(dialogName)
231
def satisfiedByNode(self, node):
232
return node.roleName=='dialog' and stringMatches(self.dialogName, node.name)
234
def describeSearchResult(self):
235
return '%s dialog'%self.dialogName
237
def makeScriptMethodCall(self, isRecursive):
238
return "dialog('%s'%s)"%(self.dialogName, makeScriptRecursiveArgument(isRecursive, False))
240
def makeScriptVariableName(self):
241
return makeCamel(self.dialogName)+"Dlg"
230
"""Predicate subclass that looks for a top-level dialog by name"""
231
def __init__(self, dialogName):
232
self.dialogName = TranslatableString(dialogName)
233
self.debugName = self.describeSearchResult()
235
def satisfiedByNode(self, node):
236
return node.roleName=='dialog' and stringMatches(self.dialogName, node.name)
238
def describeSearchResult(self):
239
return '%s dialog'%self.dialogName
241
def makeScriptMethodCall(self, isRecursive):
242
return "dialog(%s%s)"%(self.dialogName, makeScriptRecursiveArgument(isRecursive, False))
244
def makeScriptVariableName(self):
245
return makeCamel(self.dialogName)+"Dlg"
243
247
class IsLabelledBy(Predicate):
244
"""Predicate: is this node labelled by another node"""
248
"""Predicate: is this node labelled by another node"""
247
251
class IsLabelledAs(Predicate):
248
"""Predicate: is this node labelled with the text string (i.e. by another node with that as a name)"""
249
def __init__(self, labelText):
250
self.labelText = TranslatableString(labelText)
252
def satisfiedByNode(self, node):
255
return stringMatches(self.labelText, node.labeller.name)
258
def describeSearchResult(self):
259
return 'labelled %s'%self.labelText
261
def makeScriptMethodCall(self, isRecursive):
262
return "child(label='%s'%s)"%(self.labelText, makeScriptRecursiveArgument(isRecursive, True))
264
def makeScriptVariableName(self):
265
return makeCamel(self.labelText)+"Node"
252
"""Predicate: is this node labelled with the text string (i.e. by another node with that as a name)"""
253
def __init__(self, labelText):
254
self.labelText = TranslatableString(labelText)
255
self.debugName = self.describeSearchResult()
257
def satisfiedByNode(self, node):
260
return stringMatches(self.labelText, node.labeller.name)
263
def describeSearchResult(self):
264
return 'labelled %s'%self.labelText
266
def makeScriptMethodCall(self, isRecursive):
267
return "child(label=%s%s)"%(self.labelText, makeScriptRecursiveArgument(isRecursive, True))
269
def makeScriptVariableName(self):
270
return makeCamel(self.labelText)+"Node"
267
272
class IsAMenuNamed(Predicate):
268
"""Predicate subclass that looks for a menu by name"""
269
def __init__(self, menuName):
270
self.menuName = TranslatableString(menuName)
272
def satisfiedByNode(self, node):
273
return node.roleName=='menu' and stringMatches(self.menuName, node.name)
275
def describeSearchResult(self):
276
return '%s menu'%(self.menuName)
278
def makeScriptMethodCall(self, isRecursive):
279
return "menu('%s'%s)"%(self.menuName, makeScriptRecursiveArgument(isRecursive, True))
281
def makeScriptVariableName(self):
282
return makeCamel(self.menuName)+"Menu"
273
"""Predicate subclass that looks for a menu by name"""
274
def __init__(self, menuName):
275
self.menuName = TranslatableString(menuName)
276
self.debugName = self.describeSearchResult()
278
def satisfiedByNode(self, node):
279
return node.roleName=='menu' and stringMatches(self.menuName, node.name)
281
def describeSearchResult(self):
282
return '%s menu'%(self.menuName)
284
def makeScriptMethodCall(self, isRecursive):
285
return "menu(%s%s)"%(self.menuName, makeScriptRecursiveArgument(isRecursive, True))
287
def makeScriptVariableName(self):
288
return makeCamel(self.menuName)+"Menu"
284
290
class IsAMenuItemNamed(Predicate):
285
"""Predicate subclass that looks for a menu item by name"""
286
def __init__(self, menuItemName):
287
self.menuItemName = TranslatableString(menuItemName)
289
def satisfiedByNode(self, node):
290
roleName = node.roleName
291
return (roleName=='menu item' or roleName=='check menu item' or roleName=='radio menu item') and stringMatches(self.menuItemName, node.name)
293
def describeSearchResult(self):
294
return '%s menuitem'%(self.menuItemName)
296
def makeScriptMethodCall(self, isRecursive):
297
return "menuItem('%s'%s)"%(self.menuItemName, makeScriptRecursiveArgument(isRecursive, True))
299
def makeScriptVariableName(self):
300
return makeCamel(self.menuItemName)+"MenuItem"
291
"""Predicate subclass that looks for a menu item by name"""
292
def __init__(self, menuItemName):
293
self.menuItemName = TranslatableString(menuItemName)
294
self.debugName = self.describeSearchResult()
296
def satisfiedByNode(self, node):
297
roleName = node.roleName
298
return (roleName=='menu item' or roleName=='check menu item' or roleName=='radio menu item') and stringMatches(self.menuItemName, node.name)
300
def describeSearchResult(self):
301
return '%s menuitem'%(self.menuItemName)
303
def makeScriptMethodCall(self, isRecursive):
304
return "menuItem(%s%s)"%(self.menuItemName, makeScriptRecursiveArgument(isRecursive, True))
306
def makeScriptVariableName(self):
307
return makeCamel(self.menuItemName)+"MenuItem"
302
309
class IsATextEntryNamed(Predicate):
303
"""Predicate subclass that looks for a text entry by name"""
304
def __init__(self, textEntryName):
305
self.textEntryName = TranslatableString(textEntryName)
307
def satisfiedByNode(self, node):
308
return node.roleName=='text' and stringMatches(self.textEntryName, node.name)
310
def describeSearchResult(self):
311
return '%s textentry'%(self.textEntryName)
313
def makeScriptMethodCall(self, isRecursive):
314
return "textentry('%s'%s)"%(self.textEntryName, makeScriptRecursiveArgument(isRecursive, True))
316
def makeScriptVariableName(self):
317
return makeCamel(self.textEntryName)+"Entry"
310
"""Predicate subclass that looks for a text entry by name"""
311
def __init__(self, textEntryName):
312
self.textEntryName = TranslatableString(textEntryName)
313
self.debugName = self.describeSearchResult()
315
def satisfiedByNode(self, node):
316
return node.roleName=='text' and stringMatches(self.textEntryName, node.name)
318
def describeSearchResult(self):
319
return '%s textentry'%(self.textEntryName)
321
def makeScriptMethodCall(self, isRecursive):
322
return "textentry(%s%s)"%(self.textEntryName, makeScriptRecursiveArgument(isRecursive, True))
324
def makeScriptVariableName(self):
325
return makeCamel(self.textEntryName)+"Entry"
319
327
class IsAButtonNamed(Predicate):
320
"""Predicate subclass that looks for a button by name"""
321
def __init__(self, buttonName):
322
self.buttonName = TranslatableString(buttonName)
324
def satisfiedByNode(self, node):
325
return node.roleName=='push button' and stringMatches(self.buttonName, node.name)
327
def describeSearchResult(self):
328
return '%s button'%(self.buttonName)
330
def makeScriptMethodCall(self, isRecursive):
331
return "button('%s'%s)"%(self.buttonName, makeScriptRecursiveArgument(isRecursive, True))
333
def makeScriptVariableName(self):
334
return makeCamel(self.buttonName)+"Button"
328
"""Predicate subclass that looks for a button by name"""
329
def __init__(self, buttonName):
330
self.buttonName = TranslatableString(buttonName)
331
self.debugName = self.describeSearchResult()
333
def satisfiedByNode(self, node):
334
return node.roleName=='push button' and stringMatches(self.buttonName, node.name)
336
def describeSearchResult(self):
337
return '%s button'%(self.buttonName)
339
def makeScriptMethodCall(self, isRecursive):
340
return "button(%s%s)"%(self.buttonName, makeScriptRecursiveArgument(isRecursive, True))
342
def makeScriptVariableName(self):
343
return makeCamel(self.buttonName)+"Button"
336
345
class IsATabNamed(Predicate):
337
"""Predicate subclass that looks for a tab by name"""
338
def __init__(self, tabName):
339
self.tabName = TranslatableString(tabName)
341
def satisfiedByNode(self, node):
342
return node.roleName=='page tab' and stringMatches(self.tabName, node.name)
344
def describeSearchResult(self):
345
return '%s tab'%(self.tabName)
347
def makeScriptMethodCall(self, isRecursive):
348
return "tab('%s'%s)"%(self.tabName, makeScriptRecursiveArgument(isRecursive, True))
350
def makeScriptVariableName(self):
351
return makeCamel(self.tabName)+"Tab"
346
"""Predicate subclass that looks for a tab by name"""
347
def __init__(self, tabName):
348
self.tabName = TranslatableString(tabName)
349
self.debugName = self.describeSearchResult()
351
def satisfiedByNode(self, node):
352
return node.roleName=='page tab' and stringMatches(self.tabName, node.name)
354
def describeSearchResult(self):
355
return '%s tab'%(self.tabName)
357
def makeScriptMethodCall(self, isRecursive):
358
return "tab(%s%s)"%(self.tabName, makeScriptRecursiveArgument(isRecursive, True))
360
def makeScriptVariableName(self):
361
return makeCamel(self.tabName)+"Tab"
353
363
class PredicateTests(unittest.TestCase):
354
def testCapitalization(self):
355
self.assertEquals(makeCamel("gnome-terminal"),"gnomeTerminal")
356
self.assertEquals(makeCamel("Evolution - Mail"), "evolutionMail")
357
self.assertEquals(makeCamel('self.assertEquals(makeCamel("Evolution - Mail"), "evolutionMail")'), "selfAssertequalsMakecamelEvolutionMailEvolutionmail")
364
def testCapitalization(self):
365
self.assertEquals(makeCamel("gnome-terminal"),"gnomeTerminal")
366
self.assertEquals(makeCamel("Evolution - Mail"), "evolutionMail")
367
self.assertEquals(makeCamel('self.assertEquals(makeCamel("Evolution - Mail"), "evolutionMail")'), "selfAssertequalsMakecamelEvolutionMailEvolutionmail")
359
369
if __name__ == "__main__":