aboutsummaryrefslogtreecommitdiffstats
path: root/build/lib.linux-x86_64-2.7/dogtail/procedural.py
diff options
context:
space:
mode:
Diffstat (limited to 'build/lib.linux-x86_64-2.7/dogtail/procedural.py')
-rw-r--r--build/lib.linux-x86_64-2.7/dogtail/procedural.py455
1 files changed, 455 insertions, 0 deletions
diff --git a/build/lib.linux-x86_64-2.7/dogtail/procedural.py b/build/lib.linux-x86_64-2.7/dogtail/procedural.py
new file mode 100644
index 00000000000..c87ae86181c
--- /dev/null
+++ b/build/lib.linux-x86_64-2.7/dogtail/procedural.py
@@ -0,0 +1,455 @@
+"""
+Dogtail's procedural UI
+All the classes here are intended to be single-instance, except for Action.
+"""
+__author__ = 'Zack Cerza <zcerza@redhat.com>'
+#
+#
+# WARNING: Here There Be Dragons (TM) #
+#
+# If you don't understand how to use this API, you almost certainly don't #
+# want to read the code first. We make use of some very non-intuitive #
+# features of Python in order to make the API very simplistic. Therefore, #
+# you should probably only read this code if you're already familiar with #
+# some of Python's advanced features. You have been warned. ;) #
+#
+#
+
+import tree
+import predicate
+from config import config
+from utils import Lock
+import rawinput
+
+#FocusError = "FocusError: %s not found"
+
+
+class FocusError(Exception):
+ pass
+
+import errors
+
+
+def focusFailed(pred):
+ errors.warn('The requested widget could not be focused: %s' %
+ pred.debugName)
+
+ENOARGS = "At least one argument is needed"
+
+
+class FocusBase(object):
+
+ """
+ The base for every class in the module. Does nothing special, really.
+ """
+ node = None
+
+ def __getattr__(self, name):
+ # Fold all the Node's AT-SPI properties into the Focus object.
+ try:
+ return getattr(self.node, name)
+ except AttributeError:
+ raise AttributeError(name)
+
+ def __setattr__(self, name, value):
+ # Fold all the Node's AT-SPI properties into the Focus object.
+ if name == 'node':
+ setattr(self.__class__, name, value)
+ else:
+ try:
+ setattr(self.node, name, value)
+ except AttributeError:
+ raise AttributeError(name)
+
+
+class FocusApplication (FocusBase):
+
+ """
+ Keeps track of which application is currently focused.
+ """
+ desktop = tree.root
+
+ def __call__(self, name):
+ """
+ Search for an application that matches and refocus on the given name.
+ """
+ try:
+ pred = predicate.IsAnApplicationNamed(name)
+ app = self.desktop.findChild(
+ pred, recursive=False, retry=False)
+ except tree.SearchError:
+ if config.fatalErrors:
+ raise FocusError(name)
+ else:
+ focusFailed(pred)
+ return False
+ if app:
+ FocusApplication.node = app
+ FocusDialog.node = None
+ FocusWindow.node = None
+ FocusWidget.node = None
+ return True
+
+
+class FocusDesktop (FocusBase):
+
+ """
+ This isn't used yet, and may never be used.
+ """
+ pass
+
+
+class FocusWindow (FocusBase):
+
+ """
+ Keeps track of which window is currently focused.
+ """
+
+ def __call__(self, name):
+ """
+ Search for a dialog that matches the given name and refocus on it.
+ """
+ result = None
+ pred = predicate.IsAWindowNamed(name)
+ try:
+ result = FocusApplication.node.findChild(
+ pred, requireResult=False, recursive=False)
+ except AttributeError:
+ pass
+ if result:
+ FocusWindow.node = result
+ FocusDialog.node = None
+ FocusWidget.node = None
+ else:
+ if config.fatalErrors:
+ raise FocusError(pred.debugName)
+ else:
+ focusFailed(pred)
+ return False
+ return True
+
+
+class FocusDialog (FocusBase):
+
+ """
+ Keeps track of which dialog is currently focused.
+ """
+
+ def __call__(self, name):
+ """
+ Search for a dialog that matches the given name and refocus on it.
+ """
+ result = None
+ pred = predicate.IsADialogNamed(name)
+ try:
+ result = FocusApplication.node.findChild(
+ pred, requireResult=False, recursive=False)
+ except AttributeError:
+ pass
+ if result:
+ FocusDialog.node = result
+ FocusWidget.node = None
+ else:
+ if config.fatalErrors:
+ raise FocusError(pred.debugName)
+ else:
+ focusFailed(pred)
+ return False
+ return True
+
+
+class FocusWidget (FocusBase):
+
+ """
+ Keeps track of which widget is currently focused.
+ """
+
+ def findByPredicate(self, pred):
+ result = None
+ try:
+ result = FocusWidget.node.findChild(
+ pred, requireResult=False, retry=False)
+ except AttributeError:
+ pass
+ if result:
+ FocusWidget.node = result
+ else:
+ try:
+ result = FocusDialog.node.findChild(
+ pred, requireResult=False, retry=False)
+ except AttributeError:
+ pass
+ if result:
+ FocusWidget.node = result
+ else:
+ try:
+ result = FocusWindow.node.findChild(
+ pred, requireResult=False, retry=False)
+ except AttributeError:
+ pass
+ if result:
+ FocusWidget.node = result
+ else:
+ try:
+ result = FocusApplication.node.findChild(
+ pred, requireResult=False, retry=False)
+ if result:
+ FocusWidget.node = result
+ except AttributeError:
+ if config.fatalErrors:
+ raise FocusError(pred)
+ else:
+ focusFailed(pred)
+ return False
+
+ if result is None:
+ FocusWidget.node = result
+ if config.fatalErrors:
+ raise FocusError(pred.debugName)
+ else:
+ focusFailed(pred)
+ return False
+ return True
+
+ def __call__(self, name='', roleName='', description=''):
+ """
+ If name, roleName or description are specified, search for a widget that matches and refocus on it.
+ """
+ if not name and not roleName and not description:
+ raise TypeError(ENOARGS)
+
+ # search for a widget.
+ pred = predicate.GenericPredicate(name=name,
+ roleName=roleName, description=description)
+ return self.findByPredicate(pred)
+
+
+class Focus (FocusBase):
+
+ """
+ The container class for the focused application, dialog and widget.
+ """
+
+ def __getattr__(self, name):
+ raise AttributeError(name)
+
+ def __setattr__(self, name, value):
+ if name in ('application', 'dialog', 'widget', 'window'):
+ self.__dict__[name] = value
+ else:
+ raise AttributeError(name)
+
+ desktop = tree.root
+ application = FocusApplication()
+ app = application # shortcut :)
+ dialog = FocusDialog()
+ window = FocusWindow()
+ frame = window
+ widget = FocusWidget()
+
+ def button(self, name):
+ """
+ A shortcut to self.widget.findByPredicate(predicate.IsAButtonNamed(name))
+ """
+ return self.widget.findByPredicate(predicate.IsAButtonNamed(name))
+
+ def icon(self, name):
+ """
+ A shortcut to self.widget(name, roleName = 'icon')
+ """
+ return self.widget(name=name, roleName='icon')
+
+ def menu(self, name):
+ """
+ A shortcut to self.widget.findByPredicate(predicate.IsAMenuNamed(name))
+ """
+ return self.widget.findByPredicate(predicate.IsAMenuNamed(name))
+
+ def menuItem(self, name):
+ """
+ A shortcut to self.widget.findByPredicate(predicate.IsAMenuItemNamed(name))
+ """
+ return self.widget.findByPredicate(predicate.IsAMenuItemNamed(name))
+
+ def table(self, name=''):
+ """
+ A shortcut to self.widget(name, roleName 'table')
+ """
+ return self.widget(name=name, roleName='table')
+
+ def tableCell(self, name=''):
+ """
+ A shortcut to self.widget(name, roleName 'table cell')
+ """
+ return self.widget(name=name, roleName='table cell')
+
+ def text(self, name=''):
+ """
+ A shortcut to self.widget.findByPredicate(IsATextEntryNamed(name))
+ """
+ return self.widget.findByPredicate(predicate.IsATextEntryNamed(name))
+
+
+class Action (FocusWidget):
+
+ """
+ Aids in executing AT-SPI actions, refocusing the widget if necessary.
+ """
+
+ def __init__(self, action):
+ """
+ action is a string with the same name as the AT-SPI action you wish to execute using this class.
+ """
+ self.action = action
+
+ def __call__(self, name='', roleName='', description='', delay=config.actionDelay):
+ """
+ If name, roleName or description are specified, first search for a widget that matches and refocus on it.
+ Then execute the action.
+ """
+ if name or roleName or description:
+ FocusWidget.__call__(
+ self, name=name, roleName=roleName, description=description)
+ self.node.doActionNamed(self.action)
+
+ def __getattr__(self, attr):
+ return getattr(FocusWidget.node, attr)
+
+ def __setattr__(self, attr, value):
+ if attr == 'action':
+ self.__dict__[attr] = value
+ else:
+ setattr(FocusWidget, attr, value)
+
+ def button(self, name):
+ """
+ A shortcut to self(name, roleName = 'push button')
+ """
+ self.__call__(name=name, roleName='push button')
+
+ def menu(self, name):
+ """
+ A shortcut to self(name, roleName = 'menu')
+ """
+ self.__call__(name=name, roleName='menu')
+
+ def menuItem(self, name):
+ """
+ A shortcut to self(name, roleName = 'menu item')
+ """
+ self.__call__(name=name, roleName='menu item')
+
+ def table(self, name=''):
+ """
+ A shortcut to self(name, roleName 'table')
+ """
+ self.__call__(name=name, roleName='table')
+
+ def tableCell(self, name=''):
+ """
+ A shortcut to self(name, roleName 'table cell')
+ """
+ self.__call__(name=name, roleName='table cell')
+
+ def text(self, name=''):
+ """
+ A shortcut to self(name, roleName = 'text')
+ """
+ self.__call__(name=name, roleName='text')
+
+
+class Click (Action):
+
+ """
+ A special case of Action, Click will eventually handle raw mouse events.
+ """
+ primary = 1
+ middle = 2
+ secondary = 3
+
+ def __init__(self):
+ Action.__init__(self, 'click')
+
+ def __call__(self, name='', roleName='', description='', raw=True, button=primary, delay=config.actionDelay):
+ """
+ By default, execute a raw mouse event.
+ If raw is False or if button evaluates to False, just pass the rest of
+ the arguments to Action.
+ """
+ if name or roleName or description:
+ FocusWidget.__call__(
+ self, name=name, roleName=roleName, description=description)
+ if raw and button:
+ # We're doing a raw mouse click
+ Click.node.click(button)
+ else:
+ Action.__call__(
+ self, name=name, roleName=roleName, description=description, delay=delay)
+
+
+class Select (Action):
+
+ """
+ Aids in selecting and deselecting widgets, i.e. page tabs
+ """
+ select = 'select'
+ deselect = 'deselect'
+
+ def __init__(self, action):
+ """
+ action must be 'select' or 'deselect'.
+ """
+ if action not in (self.select, self.deselect):
+ raise ValueError(action)
+ Action.__init__(self, action)
+
+ def __call__(self, name='', roleName='', description='', delay=config.actionDelay):
+ """
+ If name, roleName or description are specified, first search for a widget that matches and refocus on it.
+ Then execute the action.
+ """
+ if name or roleName or description:
+ FocusWidget.__call__(
+ self, name=name, roleName=roleName, description=description)
+ func = getattr(self.node, self.action)
+ func()
+
+
+def type(text):
+ if focus.widget.node:
+ focus.widget.node.typeText(text)
+ else:
+ rawinput.typeText(text)
+
+
+def keyCombo(combo):
+ if focus.widget.node:
+ focus.widget.node.keyCombo(combo)
+ else:
+ rawinput.keyCombo(combo)
+
+
+def run(application, arguments='', appName=''):
+ from utils import run as utilsRun
+ pid = utilsRun(application + ' ' + arguments, appName=appName)
+ focus.application(application)
+ return pid
+
+import os
+# tell sniff not to use auto-refresh while script using this module is running
+# may have already been locked by dogtail.tree
+if not os.path.exists('/tmp/sniff_refresh.lock'): # pragma: no cover
+ sniff_lock = Lock(lockname='sniff_refresh.lock', randomize=False)
+ try:
+ sniff_lock.lock()
+ except OSError:
+ pass # lock was already present from other script instance or leftover from killed instance
+ # lock should unlock automatically on script exit.
+
+focus = Focus()
+click = Click()
+activate = Action('activate')
+openItem = Action('open')
+menu = Action('menu')
+select = Select(Select.select)
+deselect = Select(Select.deselect)