[pyatspi2] Added collection support
- From: Mike Gorse <mgorse src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [pyatspi2] Added collection support
- Date: Fri, 18 Dec 2009 17:08:50 +0000 (UTC)
commit 8d25a5581c406255cfb88880540ebde20dc06531
Author: Mike Gorse <mgorse novell com>
Date: Fri Dec 18 12:06:10 2009 -0500
Added collection support
pyatspi/accessible.py | 2 +-
pyatspi/collection.py | 192 +++++++++++++++++++++++++++------------
pyatspi/state.py | 16 +++
tests/pyatspi/collectiontest.py | 160 ++++++++++++++++++++++++++++++++
tests/pyatspi/runtests.sh | 1 +
5 files changed, 311 insertions(+), 60 deletions(-)
---
diff --git a/pyatspi/accessible.py b/pyatspi/accessible.py
index e98b62e..825b601 100644
--- a/pyatspi/accessible.py
+++ b/pyatspi/accessible.py
@@ -409,7 +409,7 @@ class Accessible(BaseProxy):
or raises a NotImplemented error if the given interface
is not supported.
"""
- if interface in self.interfaces:
+ if interface in self.interfaces or interface == "org.freedesktop.atspi.Collection":
return self.acc_factory.create_accessible(self.app_name,
self.acc_path,
interface,
diff --git a/pyatspi/collection.py b/pyatspi/collection.py
index d52b782..ffaa87c 100644
--- a/pyatspi/collection.py
+++ b/pyatspi/collection.py
@@ -16,51 +16,49 @@ from interfaces import *
from enum import Enum
from accessible import Accessible
+from dbus.types import UInt32
+
__all__ = [
- "Collection",
+ "Collection",
+ "MatchRule",
+ "SortOrder",
+ "MatchType",
+ "TreeTraversalType",
]
#------------------------------------------------------------------------------
-class Collection(Accessible):
-
- def createMatchRule(self, *args, **kwargs):
- func = self.get_dbus_method("CreateMatchRule", dbus_interface=ATSPI_COLLECTION)
- return func(*args, **kwargs)
-
- def freeMatchRule(self, *args, **kwargs):
- func = self.get_dbus_method("FreeMatchRule", dbus_interface=ATSPI_COLLECTION)
- return func(*args, **kwargs)
-
- def getActiveDescendant(self, *args, **kwargs):
- func = self.get_dbus_method("GetActiveDescendant", dbus_interface=ATSPI_COLLECTION)
- return func(*args, **kwargs)
+class MatchType(Enum):
+ _enum_lookup = {
+ 0:'MATCH_INVALID',
+ 1:'MATCH_ALL',
+ 2:'MATCH_ANY',
+ 3:'MATCH_NONE',
+ 4:'MATCH_EMPTY',
+ 5:'MATCH_LAST_DEFINED',
+ }
+
+class SortOrder(Enum):
+ _enum_lookup = {
+ 0:'SORT_ORDER_INVALID',
+ 1:'SORT_ORDER_CANONICAL',
+ 2:'SORT_ORDER_FLOW',
+ 3:'SORT_ORDER_TAB',
+ 4:'SORT_ORDER_REVERSE_CANONICAL',
+ 5:'SORT_ORDER_REVERSE_FLOW',
+ 6:'SORT_ORDER_REVERSE_TAB',
+ 7:'SORT_ORDER_LAST_DEFINED',
+ }
+
+class TreeTraversalType(Enum):
+ _enum_lookup = {
+ 0:'TREE_RESTRICT_CHILDREN',
+ 1:'TREE_RESTRICT_SIBLING',
+ 2:'TREE_INORDER',
+ 3:'TREE_LAST_DEFINED',
+ }
- def getMatches(self, *args, **kwargs):
- func = self.get_dbus_method("GetMatches", dbus_interface=ATSPI_COLLECTION)
- return func(*args, **kwargs)
-
- def getMatchesFrom(self, *args, **kwargs):
- func = self.get_dbus_method("GetMatchesFrom", dbus_interface=ATSPI_COLLECTION)
- return func(*args, **kwargs)
-
- def getMatchesTo(self, *args, **kwargs):
- func = self.get_dbus_method("GetMatchesTo", dbus_interface=ATSPI_COLLECTION)
- return func(*args, **kwargs)
-
- def isAncestorOf(self, *args, **kwargs):
- func = self.get_dbus_method("IsAncestorOf", dbus_interface=ATSPI_COLLECTION)
- return func(*args, **kwargs)
-
- class MatchType(Enum):
- _enum_lookup = {
- 0:'MATCH_INVALID',
- 1:'MATCH_ALL',
- 2:'MATCH_ANY',
- 3:'MATCH_NONE',
- 4:'MATCH_EMPTY',
- 5:'MATCH_LAST_DEFINED',
- }
+class Collection(Accessible):
MATCH_ALL = MatchType(1)
MATCH_ANY = MatchType(2)
@@ -69,18 +67,6 @@ class Collection(Accessible):
MATCH_LAST_DEFINED = MatchType(5)
MATCH_NONE = MatchType(3)
- class SortOrder(Enum):
- _enum_lookup = {
- 0:'SORT_ORDER_INVALID',
- 1:'SORT_ORDER_CANONICAL',
- 2:'SORT_ORDER_FLOW',
- 3:'SORT_ORDER_TAB',
- 4:'SORT_ORDER_REVERSE_CANONICAL',
- 5:'SORT_ORDER_REVERSE_FLOW',
- 6:'SORT_ORDER_REVERSE_TAB',
- 7:'SORT_ORDER_LAST_DEFINED',
- }
-
SORT_ORDER_CANONICAL = SortOrder(1)
SORT_ORDER_FLOW = SortOrder(2)
SORT_ORDER_INVALID = SortOrder(0)
@@ -90,17 +76,105 @@ class Collection(Accessible):
SORT_ORDER_REVERSE_TAB = SortOrder(6)
SORT_ORDER_TAB = SortOrder(3)
- class TreeTraversalType(Enum):
- _enum_lookup = {
- 0:'TREE_RESTRICT_CHILDREN',
- 1:'TREE_RESTRICT_SIBLING',
- 2:'TREE_INORDER',
- 3:'TREE_LAST_DEFINED',
- }
-
TREE_INORDER = TreeTraversalType(2)
TREE_LAST_DEFINED = TreeTraversalType(3)
TREE_RESTRICT_CHILDREN = TreeTraversalType(0)
TREE_RESTRICT_SIBLING = TreeTraversalType(1)
+ def isAncestorOf(self, object):
+ print "isAncestorOf unimplemented"
+ return False
+
+ def createMatchRule(self, states, stateMatchType, attributes, attributeMatchType, roles, roleMatchType, interfaces, interfaceMatchType, invert):
+ attributes_rule = str.join("\n", attributes)
+ roles_rule = [0, 0, 0, 0]
+ for role in roles:
+ roles_rule[role/32] |= (1<<(role%32))
+ for i in range(0,4):
+ roles_rule[i] = int(roles_rule[i])
+ return MatchRule(states, stateMatchType, attributes_rule, attributeMatchType, roles_rule, roleMatchType, interfaces, interfaceMatchType, invert)
+
+ def freeMatchRule(self, rule):
+ pass
+
+ def getAccessibles(self, ret):
+ for i in range(0, len(ret)):
+ (name, path) = ret[i]
+ if (name == ""):
+ name = self._app_name
+ ret[i] = self.acc_factory.create_accessible(name, path,
+ ATSPI_ACCESSIBLE)
+ return ret;
+
+ def getMatches(self, rule, sortby, count, traverse):
+ func = self.get_dbus_method("GetMatches", dbus_interface=ATSPI_COLLECTION)
+ ret = func(rule, sortby, count, traverse)
+ return self.getAccessibles (ret)
+
+ def getMatchesTo(self, current_object, rule, sortby, tree, recurse, count, traverse):
+ func = self.get_dbus_method("GetMatchesTo", dbus_interface=ATSPI_COLLECTION)
+ ret = func(current_object._acc_path, rule, sortby, tree, recurse, count, traverse)
+ return self.getAccessibles (ret)
+
+ def getMatchesFrom(self, current_object, rule, sortby, tree, count, traverse):
+ func = self.get_dbus_method("GetMatchesFrom", dbus_interface=ATSPI_COLLECTION)
+ ret = func(current_object._acc_path, rule, sortby, tree, count, traverse)
+ return self.getAccessibles (ret)
+
+ def getActiveDescendant(self):
+ print "getActiveDescendant unimplemented"
+ return
+
+class MatchRule(tuple):
+ def __new__(cls, states, stateMatchType, attributes, attributeMatchType, roles, roleMatchType, interfaces, interfaceMatchType, invert):
+ return tuple.__new__(cls, (states, int(stateMatchType), attributes, int(attributeMatchType), roles, int(roleMatchType), interfaces, int(interfaceMatchType), invert))
+ #def __init__(self, states, stateMatchType, attributes, attributeMatchType, roles, roleMatchType, interfaces, interfaceMatchType, invert):
+ #tuple.__init__(self, (states, int(stateMatchType), attributes, int(attributeMatchType), roles, int(roleMatchType), interfaces, int(interfaceMatchType), invert))
+
+ def _get_states(self):
+ return self[0]
+ def _set_states(self, val):
+ self[0] = val
+ states = property(fget=_get_states, fset=_set_states)
+ def _get_stateMatchType(self):
+ return self[1]
+ def _set_stateMatchType(self, val):
+ self[1] = val
+ stateMatchType = property(fget=_get_stateMatchType, fset=_set_stateMatchType)
+ def _get_attributes(self):
+ return self[2]
+ def _set_attributes(self, val):
+ self[2] = val
+ attributes = property(fget=_get_attributes, fset=_set_attributes)
+ def _get_attributeMatchType(self):
+ return self[3]
+ def _set_attributeMatchType(self, val):
+ self[3] = val
+ attributeMatchType = property(fget=_get_attributeMatchType, fset=_set_attributeMatchType)
+ def _get_roles(self):
+ return self[4]
+ def _set_roles(self, val):
+ self[4] = val
+ roles = property(fget=_get_roles, fset=_set_roles)
+ def _get_roleMatchType(self):
+ return self[5]
+ def _set_roleMatchType(self, val):
+ self[5] = val
+ roleMatchType = property(fget=_get_roleMatchType, fset=_set_roleMatchType)
+ def _get_interfaces(self):
+ return self[6]
+ def _set_interfaces(self, val):
+ self[6] = val
+ interfaces = property(fget=_get_interfaces, fset=_set_interfaces)
+ def _get_interfaceMatchType(self):
+ return self[7]
+ def _set_interfaceMatchType(self, val):
+ self[7] = val
+ interfaceMatchType = property(fget=_get_interfaceMatchType, fset=_set_interfaceMatchType)
+ def _get_invert(self):
+ return self[8]
+ def _set_invert(self, val):
+ self[8] = val
+ invert = property(fget=_get_invert, fset=_set_invert)
+
#END----------------------------------------------------------------------------
diff --git a/pyatspi/state.py b/pyatspi/state.py
index 0257a11..7703a4a 100644
--- a/pyatspi/state.py
+++ b/pyatspi/state.py
@@ -253,4 +253,20 @@ class StateSet(object):
"""
return list(self.states)
+ def raw(self):
+ """
+ Gets the sequence of all states in this set as a pair of
+ 32-bit flags, suitable for transmitting via dbus..
+
+ @return: List of two 32-bit flags representing the states
+ @rtype: list
+ """
+ lower = upper = 0
+ for i in range (0, 32):
+ if (self.contains(i)):
+ lower |= (1 << i)
+ for i in range (32, 64):
+ if (self.contains(i)):
+ upper |= (1 << (i - 32))
+ return [lower, upper]
#END----------------------------------------------------------------------------
diff --git a/tests/pyatspi/collectiontest.py b/tests/pyatspi/collectiontest.py
new file mode 100644
index 0000000..d4e8403
--- /dev/null
+++ b/tests/pyatspi/collectiontest.py
@@ -0,0 +1,160 @@
+import dbus
+import gobject
+import os.path
+
+from xml.dom import minidom
+import os
+
+from pasytest import PasyTest as _PasyTest
+
+import pyatspi
+from pyatspi import StateSet
+
+st = [pyatspi.STATE_MULTI_LINE,
+ pyatspi.STATE_MODAL,
+ pyatspi.STATE_INDETERMINATE,
+ pyatspi.STATE_SUPPORTS_AUTOCOMPLETION,
+ pyatspi.STATE_VERTICAL,]
+
+def _createNode(accessible, parentElement):
+ e = minidom.Element("accessible")
+
+ e.attributes["name"] = accessible.name
+ e.attributes["role"] = str(int(accessible.getRole()))
+ e.attributes["description"] = accessible.description
+
+ for i in range(0, accessible.childCount):
+ _createNode(accessible.getChildAtIndex(i), e)
+
+ parentElement.appendChild(e)
+
+class AccessibleTest(_PasyTest):
+
+ __tests__ = ["setup",
+ "test_basic",
+ "test_role",
+ "teardown",
+ ]
+
+ def __init__(self, bus, path):
+ _PasyTest.__init__(self, "Accessible", False)
+ self._bus = bus
+ self._path = path
+
+
+ def setup(self, test):
+ self._registry = pyatspi.Registry()
+ print self._path
+ self._desktop = self._registry.getDesktop(0)
+ print "dbg: getting root"
+ self.root = pyatspi.findDescendant (self._desktop, lambda x: x.name == "main" and x.getRole() == pyatspi.ROLE_WINDOW)
+ print "root: ", self.root
+
+ def assertObjects(self,test,obj,vars,msg):
+ test.assertEqual(len(obj), len(vars) / 2, msg + " length")
+ for i in range(0, len(vars), 2):
+ test.assertEqual (vars[i], obj[i/2].name, msg + "name" + "#" + str(i/2))
+ test.assertEqual(vars[i+1], obj[i/2].getRole(), msg + " role" + "#" + str(i/2))
+
+ # Used to help add new tests
+ def printAsserts(self,obj,msg):
+ print "\t\tself.assertObjects(test,ret,("
+ for i in range(0,len(obj)):
+ print "\t\t\t\"" + obj[i].name + "\", " + str(obj[i].getRole()) + ","
+ print "\t\t), \"", msg, "\")"
+
+ def test_basic(self, test):
+ collection = self.root.queryCollection()
+ stateSet = pyatspi.StateSet()
+ rule = collection.createMatchRule (stateSet.raw(),
+ collection.MATCH_NONE,
+ [], # attributes
+ collection.MATCH_NONE,
+ [], # role
+ collection.MATCH_NONE,
+ "", # interfaces
+ collection.MATCH_NONE,
+ False)
+
+ ret = collection.getMatches (rule, collection.SORT_ORDER_CANONICAL, 5, True)
+ self.assertObjects(test,ret,(
+ "gnome-settings-daemon", 79 ,
+ "gnome-panel", 79 ,
+ "Bottom Expanded Edge Panel", 25 ,
+ "Top Expanded Edge Panel", 25 ,
+ "nautilus", 79 ,
+ ), " 1 ")
+
+ ret = collection.getMatches (rule, collection.SORT_ORDER_REVERSE_CANONICAL, 5, True)
+ self.assertObjects(test,ret,(
+ "nautilus", 79,
+ "Top Expanded Edge Panel", 25,
+ "Bottom Expanded Edge Panel", 25,
+ "gnome-panel", 79,
+ "gnome-settings-daemon", 79,
+ ), " reverse canonical ")
+
+ obj=ret[2]
+ ret = collection.getMatchesTo (obj, rule, collection.SORT_ORDER_REVERSE_CANONICAL, collection.TREE_INORDER, True, 5, True)
+ self.assertObjects(test,ret,(
+ "gnome-settings-daemon", 79,
+ "gnome-panel", 79,
+ ), " getMatchesTo ")
+ ret = collection.getMatchesFrom (obj, rule, collection.SORT_ORDER_REVERSE_CANONICAL, collection.TREE_INORDER, 5, True)
+ self.assertObjects(test,ret,(
+ "tracker-applet", 79,
+ "metacity", 79,
+ "Desktop", 25,
+ "nautilus", 79,
+ "Top Expanded Edge Panel", 25,
+ ), " getMatchesFrom ")
+ obj = self.root.getChildAtIndex(1)
+ ret = collection.getMatchesFrom (obj, rule, collection.SORT_ORDER_CANONICAL, collection.TREE_RESTRICT_CHILDREN, 5, True)
+ self.assertObjects(test,ret,(
+ "Top Expanded Edge Panel", 25,
+ ), " Restrict Children ")
+
+ def test_role(self, test):
+ collection = self.root.queryCollection()
+ stateSet = pyatspi.StateSet()
+
+ rule = collection.createMatchRule (stateSet.raw(),
+ collection.MATCH_NONE,
+ [], # attributes
+ collection.MATCH_NONE,
+ [pyatspi.ROLE_RADIO_MENU_ITEM],
+ collection.MATCH_ANY,
+ "", # interfaces
+ collection.MATCH_NONE,
+ False)
+
+ ret = collection.getMatches (rule, collection.SORT_ORDER_CANONICAL, 5, True)
+ self.assertObjects(test,ret,(
+ "Activity Indicator", 45,
+ "Back", 45,
+ "Forward", 45,
+ "", 45,
+ "Reload", 45,
+ ), " role ")
+
+ rule = collection.createMatchRule (stateSet.raw(),
+ collection.MATCH_NONE,
+ [], # attributes
+ collection.MATCH_NONE,
+ [pyatspi.ROLE_ENTRY, pyatspi.ROLE_HTML_CONTAINER],
+ collection.MATCH_ANY,
+ "", # interfaces
+ collection.MATCH_NONE,
+ False)
+
+ ret = collection.getMatches (rule, collection.SORT_ORDER_CANONICAL, 5, True)
+ self.assertObjects(test,ret,(
+ "gnome-settings-daemon", 79,
+ "gnome-panel", 79,
+ "Bottom Expanded Edge Panel", 25,
+ "Top Expanded Edge Panel", 25,
+ "nautilus", 79,
+ ), " role #2")
+
+ def teardown(self, test):
+ pass
diff --git a/tests/pyatspi/runtests.sh b/tests/pyatspi/runtests.sh
index 397e310..7790462 100755
--- a/tests/pyatspi/runtests.sh
+++ b/tests/pyatspi/runtests.sh
@@ -7,6 +7,7 @@ export TEST_APPLICATION=$top_builddir/tests/apps/test-application
$PYTHON $top_srcdir/tests/pyatspi/testrunner -l libaccessibleapp.so -m accessibletest -n AccessibleTest
$PYTHON $top_srcdir/tests/pyatspi/testrunner -l libactionapp.so -m actiontest -n ActionTest
+$PYTHON $top_srcdir/tests/pyatspi/testrunner -l libaccessibleapp.so -m collectiontest -n AccessibleTest
$PYTHON $top_srcdir/tests/pyatspi/testrunner -l libcomponentapp.so -m componenttest -n ComponentTest
$PYTHON $top_srcdir/tests/pyatspi/testrunner -l librelationapp.so -m relationtest -n RelationTest
$PYTHON $top_srcdir/tests/pyatspi/testrunner -l libaccessibleapp.so -m statetest -n StateTest
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]