Package dogtail :: Module predicate
[hide private]
[frames] | no frames]

Source Code for Module dogtail.predicate

  1  """Predicates that can be used when searching for nodes. 
  2   
  3  Author: David Malcolm <dmalcolm@redhat.com>""" 
  4  __author__ = 'David Malcolm <dmalcolm@redhat.com>' 
  5   
  6  from i18n import TranslatableString 
  7   
  8   
9 -def stringMatches(scriptName, reportedName):
10 assert isinstance(scriptName, TranslatableString) 11 12 return scriptName.matchedBy(reportedName)
13 14
15 -def makeScriptRecursiveArgument(isRecursive, defaultValue):
16 if isRecursive == defaultValue: 17 return "" 18 else: 19 return ", recursive=%s" % isRecursive
20 21
22 -def makeCamel(string):
23 """ 24 Convert string to camelCaps 25 """ 26 string = str(string) 27 # FIXME: this function is probably really fragile, lots of difficult cases 28 # here 29 30 # Sanitize string, replacing bad characters with spaces: 31 for char in ":;!@#$%^&*()-+=_~`\\/?|[]{}<>,.\t\n\r\"'": 32 string = string.replace(char, " ") 33 words = string.strip().split(" ") 34 for word in words: 35 word.strip 36 result = "" 37 firstWord = True 38 for word in words: 39 lowercaseWord = word.lower() 40 if firstWord: 41 result += lowercaseWord 42 firstWord = False 43 else: 44 result += lowercaseWord.capitalize() 45 return result
46 47
48 -class Predicate(object):
49 50 """Abstract base class representing a predicate function on nodes. 51 52 It's more than just a function in that it has data and can describe itself""" 53
54 - def satisfiedByNode(self, node):
55 """Pure virtual method returning a boolean if the predicate is satisfied by the node""" 56 raise NotImplementedError
57
58 - def describeSearchResult(self, node):
59 raise NotImplementedError
60
61 - def makeScriptMethodCall(self, isRecursive):
62 """ 63 Method to generate a string containing a (hopefully) readable search 64 method call on a node (to be used when generating Python source code in 65 the event recorder) 66 """ 67 raise NotImplementedError
68
69 - def makeScriptVariableName(self):
70 """ 71 Method to generate a string containing a (hopefully) readable name 72 for a Node instance variable that would be the result of a search on 73 this predicate (to be used when generating Python source code in the 74 event recorder). 75 """ 76 raise NotImplementedError
77
78 - def __eq__(self, other):
79 """ 80 Predicates are considered equal if they are of the same subclass and 81 have the same data 82 """ 83 # print "predeq: self:%s"%self 84 # print " other:%s"%other 85 # print "predeq: selfdict:%s"%self.__dict__ 86 # print " otherdict:%s"%other.__dict__ 87 88 if type(self) != type(other): 89 return False 90 else: 91 return self.__dict__ == other.__dict__
92 93
94 -class IsAnApplicationNamed(Predicate):
95 96 """Search subclass that looks for an application by name""" 97
98 - def __init__(self, appName):
99 self.appName = TranslatableString(appName) 100 self.debugName = self.describeSearchResult() 101 self.satisfiedByNode = self._genCompareFunc()
102
103 - def _genCompareFunc(self):
104 def satisfiedByNode(node): 105 return node.roleName == 'application' and stringMatches(self.appName, node.name)
106 return satisfiedByNode
107
108 - def describeSearchResult(self):
109 return '%s application' % self.appName
110
111 - def makeScriptMethodCall(self, isRecursive):
112 # ignores the isRecursive parameter 113 return "application(%s)" % self.appName
114
115 - def makeScriptVariableName(self):
116 return makeCamel(self.appName) + "App"
117 118
119 -class GenericPredicate(Predicate):
120 121 """SubtreePredicate subclass that takes various optional search fields""" 122
123 - def __init__(self, name=None, roleName=None, description=None, label=None, debugName=None):
124 if name: 125 self.name = TranslatableString(name) 126 else: 127 self.name = None 128 self.roleName = roleName 129 self.description = description 130 if label: 131 self.label = TranslatableString(label) 132 else: 133 self.label = None 134 135 if debugName: 136 self.debugName = debugName 137 else: 138 if label: 139 self.debugName = "labelled '%s'" % self.label 140 else: 141 self.debugName = "child with" 142 if name: 143 self.debugName += " name=%s" % self.name 144 if roleName: 145 self.debugName += " roleName='%s'" % roleName 146 if description: 147 self.debugName += " description='%s'" % description 148 assert self.debugName 149 150 self.satisfiedByNode = self._genCompareFunc()
151
152 - def _genCompareFunc(self):
153 def satisfiedByNode(node): 154 # labelled nodes are handled specially: 155 if self.label: 156 # this reverses the search; we're looking for a node with LABELLED_BY 157 # and then checking the label, rather than looking for a label and 158 # then returning whatever LABEL_FOR targets 159 if node.labeller: 160 return stringMatches(self.label, node.labeller.name) 161 else: 162 return False 163 else: 164 # Ensure the node matches any criteria that were set: 165 if self.name: 166 if not stringMatches(self.name, node.name): 167 return False 168 if self.roleName: 169 if self.roleName != node.roleName: 170 return False 171 if self.description: 172 if self.description != node.description: 173 return False 174 return True
175 return satisfiedByNode
176
177 - def describeSearchResult(self):
178 return self.debugName
179
180 - def makeScriptMethodCall(self, isRecursive):
181 if self.label: 182 args = "label=%s" % self.label 183 else: 184 args = "" 185 if self.name: 186 print(self.name) 187 args += " name=%s" % self.name 188 if self.roleName: 189 args += " roleName='%s'" % self.roleName 190 if self.description: 191 args += " description='%s'" % self.description 192 return "child(%s%s)" % (args, makeScriptRecursiveArgument(isRecursive, True))
193
194 - def makeScriptVariableName(self):
195 if self.label: 196 return makeCamel(self.label) + "Node" 197 else: 198 if self.name: 199 return makeCamel(self.name) + "Node" 200 if self.roleName: 201 return makeCamel(self.roleName) + "Node" 202 if self.description: 203 return makeCamel(self.description) + "Node"
204 205
206 -class IsNamed(Predicate):
207 208 """Predicate subclass that looks simply by name""" 209
210 - def __init__(self, name):
214
215 - def _genCompareFunc(self):
216 def satisfiedByNode(node): 217 return stringMatches(self.name, node.name)
218 return satisfiedByNode
219
220 - def describeSearchResult(self):
221 return "named %s" % self.name
222
223 - def makeScriptMethodCall(self, isRecursive):
224 return "child(name=%s%s)" % (self.name, makeScriptRecursiveArgument(isRecursive, True))
225
226 - def makeScriptVariableName(self):
227 return makeCamel(self.name) + "Node"
228 229
230 -class IsAWindowNamed(Predicate):
231 232 """Predicate subclass that looks for a top-level window by name""" 233
234 - def __init__(self, windowName):
235 self.windowName = TranslatableString(windowName) 236 self.debugName = self.describeSearchResult() 237 self.satisfiedByNode = self._genCompareFunc()
238
239 - def _genCompareFunc(self):
240 def satisfiedByNode(node): 241 return node.roleName == 'frame' and stringMatches(self.windowName, node.name)
242 return satisfiedByNode
243
244 - def describeSearchResult(self):
245 return "%s window" % self.windowName
246
247 - def makeScriptMethodCall(self, isRecursive):
248 return "window(%s%s)" % (self.windowName, makeScriptRecursiveArgument(isRecursive, False))
249
250 - def makeScriptVariableName(self):
251 return makeCamel(self.windowName) + "Win"
252 253
254 -class IsAWindow(Predicate):
255 256 """Predicate subclass that looks for top-level windows""" 257
258 - def __init__(self):
259 self.satisfiedByNode = lambda node: node.roleName == 'frame'
260
261 - def describeSearchResult(self):
262 return "window"
263 264
265 -class IsADialogNamed(Predicate):
266 267 """Predicate subclass that looks for a top-level dialog by name""" 268
269 - def __init__(self, dialogName):
270 self.dialogName = TranslatableString(dialogName) 271 self.debugName = self.describeSearchResult() 272 self.satisfiedByNode = self._genCompareFunc()
273
274 - def _genCompareFunc(self):
275 def satisfiedByNode(node): 276 return node.roleName == 'dialog' and stringMatches(self.dialogName, node.name)
277 return satisfiedByNode
278
279 - def describeSearchResult(self):
280 return '%s dialog' % self.dialogName
281
282 - def makeScriptMethodCall(self, isRecursive):
283 return "dialog(%s%s)" % (self.dialogName, makeScriptRecursiveArgument(isRecursive, False))
284
285 - def makeScriptVariableName(self):
286 return makeCamel(self.dialogName) + "Dlg"
287 288
289 -class IsLabelledBy(Predicate):
290 291 """Predicate: is this node labelled by another node""" 292 pass
293 294
295 -class IsLabelledAs(Predicate):
296 297 """Predicate: is this node labelled with the text string (i.e. by another node with that as a name)""" 298
299 - def __init__(self, labelText):
300 self.labelText = TranslatableString(labelText) 301 self.debugName = self.describeSearchResult() 302 self.satisfiedByNode = self._genCompareFunc()
303
304 - def _genCompareFunc(self):
305 def satisfiedByNode(node): 306 # FIXME 307 if node.labeller: 308 return stringMatches(self.labelText, node.labeller.name) 309 else: 310 return False
311 return satisfiedByNode
312
313 - def describeSearchResult(self):
314 return 'labelled %s' % self.labelText
315
316 - def makeScriptMethodCall(self, isRecursive):
317 return "child(label=%s%s)" % (self.labelText, makeScriptRecursiveArgument(isRecursive, True))
318
319 - def makeScriptVariableName(self):
320 return makeCamel(self.labelText) + "Node"
321 322
323 -class IsAMenuNamed(Predicate):
324 325 """Predicate subclass that looks for a menu by name""" 326
327 - def __init__(self, menuName):
328 self.menuName = TranslatableString(menuName) 329 self.debugName = self.describeSearchResult() 330 self.satisfiedByNode = lambda node: node.roleName == 'menu' and \ 331 stringMatches(self.menuName, node.name)
332
333 - def describeSearchResult(self):
334 return '%s menu' % (self.menuName)
335
336 - def makeScriptMethodCall(self, isRecursive):
337 return "menu(%s%s)" % (self.menuName, makeScriptRecursiveArgument(isRecursive, True))
338
339 - def makeScriptVariableName(self):
340 return makeCamel(self.menuName) + "Menu"
341 342
343 -class IsAMenuItemNamed(Predicate):
344 345 """Predicate subclass that looks for a menu item by name""" 346
347 - def __init__(self, menuItemName):
348 self.menuItemName = TranslatableString(menuItemName) 349 self.debugName = self.describeSearchResult() 350 self.satisfiedByNode = lambda node: \ 351 node.roleName.endswith('menu item') and \ 352 stringMatches(self.menuItemName, node.name)
353
354 - def describeSearchResult(self):
355 return '%s menuitem' % (self.menuItemName)
356
357 - def makeScriptMethodCall(self, isRecursive):
358 return "menuItem(%s%s)" % (self.menuItemName, makeScriptRecursiveArgument(isRecursive, True))
359
360 - def makeScriptVariableName(self):
361 return makeCamel(self.menuItemName) + "MenuItem"
362 363
364 -class IsATextEntryNamed(Predicate):
365 366 """Predicate subclass that looks for a text entry by name""" 367
368 - def __init__(self, textEntryName):
369 self.textEntryName = TranslatableString(textEntryName) 370 self.debugName = self.describeSearchResult() 371 self.satisfiedByNode = lambda node: node.roleName == 'text' and \ 372 stringMatches(self.textEntryName, node.name)
373
374 - def describeSearchResult(self):
375 return '%s textentry' % (self.textEntryName)
376
377 - def makeScriptMethodCall(self, isRecursive):
378 return "textentry(%s%s)" % (self.textEntryName, makeScriptRecursiveArgument(isRecursive, True))
379
380 - def makeScriptVariableName(self):
381 return makeCamel(self.textEntryName) + "Entry"
382 383
384 -class IsAButtonNamed(Predicate):
385 386 """Predicate subclass that looks for a button by name""" 387
388 - def __init__(self, buttonName):
389 self.buttonName = TranslatableString(buttonName) 390 self.debugName = self.describeSearchResult() 391 self.satisfiedByNode = lambda node: node.roleName == 'push button' \ 392 and stringMatches(self.buttonName, node.name)
393
394 - def describeSearchResult(self):
395 return '%s button' % (self.buttonName)
396
397 - def makeScriptMethodCall(self, isRecursive):
398 return "button(%s%s)" % (self.buttonName, makeScriptRecursiveArgument(isRecursive, True))
399
400 - def makeScriptVariableName(self):
401 return makeCamel(self.buttonName) + "Button"
402 403
404 -class IsATabNamed(Predicate):
405 406 """Predicate subclass that looks for a tab by name""" 407
408 - def __init__(self, tabName):
409 self.tabName = TranslatableString(tabName) 410 self.debugName = self.describeSearchResult() 411 self.satisfiedByNode = lambda node: node.roleName == 'page tab' and \ 412 stringMatches(self.tabName, node.name)
413
414 - def describeSearchResult(self):
415 return '%s tab' % (self.tabName)
416
417 - def makeScriptMethodCall(self, isRecursive):
418 return "tab(%s%s)" % (self.tabName, makeScriptRecursiveArgument(isRecursive, True))
419
420 - def makeScriptVariableName(self):
421 return makeCamel(self.tabName) + "Tab"
422