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 from gi.repository import GLib
8 from time import sleep
9 from logging import debugLogger as logger
10 from config import config
11
16
17
19 if isRecursive == defaultValue:
20 return ""
21 else:
22 return ", recursive=%s" % isRecursive
23
24
26 """
27 Convert string to camelCaps
28 """
29 string = str(string)
30
31
32
33
34 for char in ":;!@#$%^&*()-+=_~`\\/?|[]{}<>,.\t\n\r\"'":
35 string = string.replace(char, " ")
36 words = string.strip().split(" ")
37 for word in words:
38 word.strip
39 result = ""
40 firstWord = True
41 for word in words:
42 lowercaseWord = word.lower()
43 if firstWord:
44 result += lowercaseWord
45 firstWord = False
46 else:
47 result += lowercaseWord.capitalize()
48 return result
49
50
52
53 """Abstract base class representing a predicate function on nodes.
54
55 It's more than just a function in that it has data and can describe itself"""
56
58 """Pure virtual method returning a boolean if the predicate is satisfied by the node"""
59 raise NotImplementedError
60
62 raise NotImplementedError
63
65 """
66 Method to generate a string containing a (hopefully) readable search
67 method call on a node (to be used when generating Python source code in
68 the event recorder)
69 """
70 raise NotImplementedError
71
73 """
74 Method to generate a string containing a (hopefully) readable name
75 for a Node instance variable that would be the result of a search on
76 this predicate (to be used when generating Python source code in the
77 event recorder).
78 """
79 raise NotImplementedError
80
82 """
83 Predicates are considered equal if they are of the same subclass and
84 have the same data
85 """
86
87
88
89
90
91 if type(self) != type(other):
92 return False
93 else:
94 return self.__dict__ == other.__dict__
95
96
98
99 """Search subclass that looks for an application by name"""
100
105
107 def satisfiedByNode(node):
108 try:
109 return node.roleName == 'application' and stringMatches(self.appName, node.name)
110 except GLib.GError as e:
111 if 'name :1.0 was not provided' in e.message:
112 logger.log("Dogtail: warning: omiting possibly broken at-spi application record")
113 return False
114 else:
115 try:
116 sleep(config.defaults['searchWarningThreshold'])
117 return node.roleName == 'application' and stringMatches(self.appName, node.name)
118 except GLib.GError:
119 logger.log("Dogtail: warning: application may be hanging")
120 return False
121 return satisfiedByNode
122
124 return '%s application' % self.appName
125
127
128 return "application(%s)" % self.appName
129
132
133
135
136 """SubtreePredicate subclass that takes various optional search fields"""
137
138 - def __init__(self, name=None, roleName=None, description=None, label=None, debugName=None):
166
197 return satisfiedByNode
198
201
215
226
227
229
230 """Predicate subclass that looks simply by name"""
231
236
240 return satisfiedByNode
241
243 return "named %s" % self.name
244
247
250
251
253
254 """Predicate subclass that looks for a top-level window by name"""
255
260
264 return satisfiedByNode
265
267 return "%s window" % self.windowName
268
271
273 return makeCamel(self.windowName) + "Win"
274
275
277
278 """Predicate subclass that looks for top-level windows"""
279
282
285
286
288
289 """Predicate subclass that looks for a top-level dialog by name"""
290
295
299 return satisfiedByNode
300
302 return '%s dialog' % self.dialogName
303
306
308 return makeCamel(self.dialogName) + "Dlg"
309
310
312
313 """Predicate: is this node labelled by another node"""
314 pass
315
316
318
319 """Predicate: is this node labelled with the text string (i.e. by another node with that as a name)"""
320
325
327 def satisfiedByNode(node):
328
329 if node.labeller:
330 return stringMatches(self.labelText, node.labeller.name)
331 else:
332 return False
333 return satisfiedByNode
334
336 return 'labelled %s' % self.labelText
337
340
342 return makeCamel(self.labelText) + "Node"
343
344
346
347 """Predicate subclass that looks for a menu by name"""
348
354
356 return '%s menu' % (self.menuName)
357
360
363
364
366
367 """Predicate subclass that looks for a menu item by name"""
368
375
377 return '%s menuitem' % (self.menuItemName)
378
381
383 return makeCamel(self.menuItemName) + "MenuItem"
384
385
386 -class IsATextEntryNamed(Predicate):
387
388 """Predicate subclass that looks for a text entry by name"""
389
390 - def __init__(self, textEntryName):
391 self.textEntryName = TranslatableString(textEntryName)
392 self.debugName = self.describeSearchResult()
393 self.satisfiedByNode = lambda node: node.roleName == 'text' and \
394 stringMatches(self.textEntryName, node.name)
395
397 return '%s textentry' % (self.textEntryName)
398
399 - def makeScriptMethodCall(self, isRecursive):
400 return "textentry(%s%s)" % (self.textEntryName, makeScriptRecursiveArgument(isRecursive, True))
401
403 return makeCamel(self.textEntryName) + "Entry"
404
405
424
425
427
428 """Predicate subclass that looks for a tab by name"""
429
435
437 return '%s tab' % (self.tabName)
438
441
444