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
25
# 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
27
# Sanitize string, replacing bad characters with spaces:
28
for char in ":;!@#$%^&*()-+=_~`\\/?|[]{}<>,.\t\n\r\"'":
29
string = string.replace(char, " ")
30
words = string.strip().split(" ")
36
lowercaseWord = word.lower()
38
result += lowercaseWord
41
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()
45
"""Abstract base class representing a predicate function on nodes.
47
It's more than just a function in that it has data and can describe itself"""
48
def satisfiedByNode(self, node):
49
"""Pure virtual method returning a boolean if the predicate is satisfied by the node"""
50
raise NotImplementedError
52
def describeSearchResult(self, node):
53
raise NotImplementedError
55
def makeScriptMethodCall(self, isRecursive):
57
Method to generate a string containing a (hopefully) readable search
58
method call on a node (to be used when generating Python source code in
61
raise NotImplementedError
63
def makeScriptVariableName(self):
65
Method to generate a string containing a (hopefully) readable name
66
for a Node instance variable that would be the result of a search on
67
this predicate (to be used when generating Python source code in the
70
raise NotImplementedError
72
def __eq__(self, other):
74
Predicates are considered equal if they are of the same subclass and
77
# print "predeq: self:%s"%self
78
# print " other:%s"%other
79
# print "predeq: selfdict:%s"%self.__dict__
80
# print " otherdict:%s"%other.__dict__
82
if type(self)!=type(other):
85
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__
88
89
class IsAnApplicationNamed(Predicate):
89
"""Search subclass that looks for an application by name"""
90
def __init__(self, appName):
91
self.appName = TranslatableString(appName)
93
def satisfiedByNode(self, node):
94
return node.roleName=='application' and stringMatches(self.appName, node.name)
96
def describeSearchResult(self):
97
return '%s application'%self.appName
99
def makeScriptMethodCall(self, isRecursive):
100
# ignores the isRecursive parameter
101
return "application('%s')"%self.appName
103
def makeScriptVariableName(self):
104
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"
106
108
class GenericPredicate(Predicate):
107
"""SubtreePredicate subclass that takes various optional search fields"""
109
def __init__(self, name = None, roleName = None, description= None, label = None, debugName=None):
111
self.name = TranslatableString(name)
114
self.roleName = roleName
115
self.description = description
117
self.label = TranslatableString(label)
122
self.debugName = debugName
125
self.debugName = "labelled '%s'"%self.label
127
self.debugName = "child with"
129
self.debugName += " name=%s" % self.name
131
self.debugName += " roleName='%s'"%roleName
133
self.debugName += " description='%s'"%description
134
assert self.debugName
137
def satisfiedByNode(self, node):
138
# labelled nodes are handled specially:
140
# this reverses the search; we're looking for a node with LABELLED_BY
141
# and then checking the label, rather than looking for a label and
142
# then returning whatever LABEL_FOR targets
144
return stringMatches(self.label, node.labeller.name)
147
# Ensure the node matches any criteria that were set:
149
if not stringMatches(self.name,node.name): return False
151
if self.roleName!=node.roleName: return False
153
if self.description!=node.description: return False
156
def describeSearchResult(self):
157
return self.debugName
159
def makeScriptMethodCall(self, isRecursive):
161
args = "label='%s'"%label
165
args += " name='%s'"%self.name
167
args += " roleName='%s'"%self.roleName
169
args += " description='%s'"%self.description
170
return "child(%s%s)"%(args, makeScriptRecursiveArgument(isRecursive, True))
172
def makeScriptVariableName(self):
174
return makeCamel(self.label)+"Node"
177
return makeCamel(self.name)+"Node"
179
return makeCamel(self.roleName)+"Node"
181
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"
183
185
class IsNamed(Predicate):
184
"""Predicate subclass that looks simply by name"""
186
def __init__(self, name):
187
self.name = TranslatableString(name)
189
def satisfiedByNode(self, node):
190
return stringMatches(self.name, node.name)
192
def describeSearchResult(self):
193
return "named %s"%self.name
195
def makeScriptMethodCall(self, isRecursive):
196
return "child(name='%s'%s)"%(self.name, makeScriptRecursiveArgument(isRecursive, True))
197
def makeScriptVariableName(self):
198
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"
200
203
class IsAWindowNamed(Predicate):
201
"""Predicate subclass that looks for a top-level window by name"""
202
def __init__(self, windowName):
203
self.windowName = TranslatableString(windowName)
205
def satisfiedByNode(self, node):
206
return node.roleName=='frame' and stringMatches(self.windowName, node.name)
208
def describeSearchResult(self):
209
return "%s window"%self.windowName
211
def makeScriptMethodCall(self, isRecursive):
212
return "window('%s'%s)"%(self.windowName, makeScriptRecursiveArgument(isRecursive, False))
214
def makeScriptVariableName(self):
215
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"
217
221
class IsAWindow(Predicate):
218
"""Predicate subclass that looks for top-level windows"""
219
def satisfiedByNode(self, node):
220
return node.roleName=='frame'
222
"""Predicate subclass that looks for top-level windows"""
223
def satisfiedByNode(self, node):
224
return node.roleName=='frame'
222
def describeSearchResult(self):
226
def describeSearchResult(self):
225
229
class IsADialogNamed(Predicate):
226
"""Predicate subclass that looks for a top-level dialog by name"""
227
def __init__(self, dialogName):
228
self.dialogName = TranslatableString(dialogName)
230
def satisfiedByNode(self, node):
231
return node.roleName=='dialog' and stringMatches(self.dialogName, node.name)
233
def describeSearchResult(self):
234
return '%s dialog'%self.dialogName
236
def makeScriptMethodCall(self, isRecursive):
237
return "dialog('%s'%s)"%(self.dialogName, makeScriptRecursiveArgument(isRecursive, False))
239
def makeScriptVariableName(self):
240
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"
242
247
class IsLabelledBy(Predicate):
243
"""Predicate: is this node labelled by another node"""
248
"""Predicate: is this node labelled by another node"""
246
251
class IsLabelledAs(Predicate):
247
"""Predicate: is this node labelled with the text string (i.e. by another node with that as a name)"""
248
def __init__(self, labelText):
249
self.labelText = TranslatableString(labelText)
251
def satisfiedByNode(self, node):
254
return stringMatches(self.labelText, node.labeller.name)
257
def describeSearchResult(self):
258
return 'labelled %s'%self.labelText
260
def makeScriptMethodCall(self, isRecursive):
261
return "child(label='%s'%s)"%(self.labelText, makeScriptRecursiveArgument(isRecursive, True))
263
def makeScriptVariableName(self):
264
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"
266
272
class IsAMenuNamed(Predicate):
267
"""Predicate subclass that looks for a menu by name"""
268
def __init__(self, menuName):
269
self.menuName = TranslatableString(menuName)
271
def satisfiedByNode(self, node):
272
return node.roleName=='menu' and stringMatches(self.menuName, node.name)
274
def describeSearchResult(self):
275
return '%s menu'%(self.menuName)
277
def makeScriptMethodCall(self, isRecursive):
278
return "menu('%s'%s)"%(self.menuName, makeScriptRecursiveArgument(isRecursive, True))
280
def makeScriptVariableName(self):
281
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"
283
290
class IsAMenuItemNamed(Predicate):
284
"""Predicate subclass that looks for a menu item by name"""
285
def __init__(self, menuItemName):
286
self.menuItemName = TranslatableString(menuItemName)
288
def satisfiedByNode(self, node):
289
roleName = node.roleName
290
return (roleName=='menu item' or roleName=='check menu item' or roleName=='radio menu item') and stringMatches(self.menuItemName, node.name)
292
def describeSearchResult(self):
293
return '%s menuitem'%(self.menuItemName)
295
def makeScriptMethodCall(self, isRecursive):
296
return "menuItem('%s'%s)"%(self.menuItemName, makeScriptRecursiveArgument(isRecursive, True))
298
def makeScriptVariableName(self):
299
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"
301
309
class IsATextEntryNamed(Predicate):
302
"""Predicate subclass that looks for a text entry by name"""
303
def __init__(self, textEntryName):
304
self.textEntryName = TranslatableString(textEntryName)
306
def satisfiedByNode(self, node):
307
return node.roleName=='text' and stringMatches(self.textEntryName, node.name)
309
def describeSearchResult(self):
310
return '%s textentry'%(self.textEntryName)
312
def makeScriptMethodCall(self, isRecursive):
313
return "textentry('%s'%s)"%(self.textEntryName, makeScriptRecursiveArgument(isRecursive, True))
315
def makeScriptVariableName(self):
316
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"
318
327
class IsAButtonNamed(Predicate):
319
"""Predicate subclass that looks for a button by name"""
320
def __init__(self, buttonName):
321
self.buttonName = TranslatableString(buttonName)
323
def satisfiedByNode(self, node):
324
return node.roleName=='push button' and stringMatches(self.buttonName, node.name)
326
def describeSearchResult(self):
327
return '%s button'%(self.buttonName)
329
def makeScriptMethodCall(self, isRecursive):
330
return "button('%s'%s)"%(self.buttonName, makeScriptRecursiveArgument(isRecursive, True))
332
def makeScriptVariableName(self):
333
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"
335
345
class IsATabNamed(Predicate):
336
"""Predicate subclass that looks for a tab by name"""
337
def __init__(self, tabName):
338
self.tabName = TranslatableString(tabName)
340
def satisfiedByNode(self, node):
341
return node.roleName=='page tab' and stringMatches(self.tabName, node.name)
343
def describeSearchResult(self):
344
return '%s tab'%(self.tabName)
346
def makeScriptMethodCall(self, isRecursive):
347
return "tab('%s'%s)"%(self.tabName, makeScriptRecursiveArgument(isRecursive, True))
349
def makeScriptVariableName(self):
350
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"
352
363
class PredicateTests(unittest.TestCase):
353
def testCapitalization(self):
354
self.assertEquals(makeCamel("gnome-terminal"),"gnomeTerminal")
355
self.assertEquals(makeCamel("Evolution - Mail"), "evolutionMail")
356
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")
358
369
if __name__ == "__main__":