From 77e0f05b669f34a8ff16311269e356018f8ee216 Mon Sep 17 00:00:00 2001 From: Mark Doffman Date: Thu, 16 Oct 2008 20:44:03 +0100 Subject: [PATCH] 2008-10-13 Mark Doffman * pyatspi/* Fix some horrible whitespace issues in all pyatspi files. --- pyatspi/accessible.py | 114 ++--- pyatspi/action.py | 142 +++--- pyatspi/application.py | 192 ++++---- pyatspi/base.py | 246 +++++----- pyatspi/cache.py | 296 ++++++------ pyatspi/collection.py | 177 ++++---- pyatspi/component.py | 298 ++++++------ pyatspi/desktop.py | 638 +++++++++++++------------- pyatspi/document.py | 90 ++-- pyatspi/editabletext.py | 208 ++++----- pyatspi/event.py | 420 ++++++++--------- pyatspi/factory.py | 66 +-- pyatspi/hyperlink.py | 164 +++---- pyatspi/hypertext.py | 80 ++-- pyatspi/image.py | 158 +++---- pyatspi/loginhelper.py | 242 +++++----- pyatspi/registry.py | 846 +++++++++++++++++----------------- pyatspi/relation.py | 154 +++---- pyatspi/role.py | 186 ++++---- pyatspi/selection.py | 210 ++++----- pyatspi/selector.py | 260 ++++++----- pyatspi/state.py | 338 +++++++------- pyatspi/streamablecontent.py | 237 +++++----- pyatspi/table.py | 698 ++++++++++++++-------------- pyatspi/test.py | 60 +-- pyatspi/text.py | 1035 +++++++++++++++++++++--------------------- pyatspi/utils.py | 542 +++++++++++----------- pyatspi/value.py | 96 ++-- 28 files changed, 4067 insertions(+), 4126 deletions(-) diff --git a/pyatspi/accessible.py b/pyatspi/accessible.py index 39584ca..ae0f548 100644 --- a/pyatspi/accessible.py +++ b/pyatspi/accessible.py @@ -20,16 +20,16 @@ from relation import _marshal_relation_set from role import Role __all__ = [ - "LOCALE_TYPE", - "LOCALE_TYPE_COLLATE", - "LOCALE_TYPE_CTYPE", - "LOCALE_TYPE_MESSAGES", - "LOCALE_TYPE_MONETARY", - "LOCALE_TYPE_NUMERIC", - "LOCALE_TYPE_TIME", - "BoundingBox", - "Accessible", - ] + "LOCALE_TYPE", + "LOCALE_TYPE_COLLATE", + "LOCALE_TYPE_CTYPE", + "LOCALE_TYPE_MESSAGES", + "LOCALE_TYPE_MONETARY", + "LOCALE_TYPE_NUMERIC", + "LOCALE_TYPE_TIME", + "BoundingBox", + "Accessible", + ] #------------------------------------------------------------------------------ @@ -59,8 +59,8 @@ class BoundingBox(list): list.__init__(self, (x, y, width, height)) def __str__(self): - return ("(%d, %d, %d, %d)" % (self.x, self.y, self.width, self.height)) - + return ("(%d, %d, %d, %d)" % (self.x, self.y, self.width, self.height)) + def _get_x(self): return self[0] def _set_x(self, val): @@ -93,27 +93,27 @@ class Accessible(BaseProxy): """ def __nonzero__(self): - return True + return True def __len__(self): - return self.getChildCount() + return self.getChildCount() def __getitem__(self, index): - return self.getChildAtIndex(index) - + return self.getChildAtIndex(index) + def getApplication(self): """ Get the containing Application for this object. @return the Application instance to which this object belongs. """ - application_root = self._cache[self._app_name]._get_root() - #TODO Set the desktop object as the parent of this. - return create_accessible(self._cache, - self._app_name, - application_root, - ATSPI_APPLICATION, - connection=self._cache._connection) - + application_root = self._cache[self._app_name]._get_root() + #TODO Set the desktop object as the parent of this. + return create_accessible(self._cache, + self._app_name, + application_root, + ATSPI_APPLICATION, + connection=self._cache._connection) + def getAttributes(self): """ Get a list of properties applied to this object as a whole, as @@ -143,7 +143,7 @@ class Accessible(BaseProxy): @return : An AttributeSet encapsulating any "attribute values" currently defined for the object. An attribute set is a list of strings - with each string comprising an name-value pair format 'name:value'. + with each string comprising an name-value pair format 'name:value'. """ func = self.get_dbus_method("getAttributes", dbus_interface=ATSPI_ACCESSIBLE) return func() @@ -155,25 +155,25 @@ class Accessible(BaseProxy): an in parameter indicating which child is requested (zero-indexed). @return : the 'nth' Accessible child of this object. """ - path = self.cached_data.children[index] - return create_accessible(self._cache, - self._app_name, - path, - ATSPI_ACCESSIBLE, - connection=self._cache._connection) - + path = self.cached_data.children[index] + return create_accessible(self._cache, + self._app_name, + path, + ATSPI_ACCESSIBLE, + connection=self._cache._connection) + def getIndexInParent(self): """ Get the index of this object in its parent's child list. @return : a long integer indicating this object's index in the parent's list. """ - for i in range(0, self.parent.childCount): - child = self.parent.getChildAtIndex(i) - if self.isEqual(child): - return i - raise AccessibleObjectNoLongerExists("Child not found within parent") - + for i in range(0, self.parent.childCount): + child = self.parent.getChildAtIndex(i) + if self.isEqual(child): + return i + raise AccessibleObjectNoLongerExists("Child not found within parent") + def getLocalizedRoleName(self): """ Get a string indicating the type of UI role played by this object, @@ -183,7 +183,7 @@ class Accessible(BaseProxy): """ func = self.get_dbus_method("getLocalizedRoleName", dbus_interface=ATSPI_ACCESSIBLE) return func() - + def getRelationSet(self): """ Get a set defining this object's relationship to other accessible @@ -193,7 +193,7 @@ class Accessible(BaseProxy): func = self.get_dbus_method("getRelationSet", dbus_interface=ATSPI_ACCESSIBLE) relation_set = func() return _marshal_relation_set(self._cache, self._app_name, relation_set) - + def getRole(self): """ Get the Role indicating the type of UI role played by this object. @@ -201,7 +201,7 @@ class Accessible(BaseProxy): object. """ return Role(self.cached_data.role) - + def getRoleName(self): """ Get a string indicating the type of UI role played by this object. @@ -210,7 +210,7 @@ class Accessible(BaseProxy): """ func = self.get_dbus_method("getRoleName", dbus_interface=ATSPI_ACCESSIBLE) return func() - + def getState(self): """ Get the current state of the object as a StateSet. @@ -219,8 +219,8 @@ class Accessible(BaseProxy): """ func = self.get_dbus_method("getState", dbus_interface=ATSPI_ACCESSIBLE) bitfield = func() - return _marshal_state_set(bitfield) - + return _marshal_state_set(bitfield) + def isEqual(self, accessible): """ Determine whether an Accessible refers to the same object as @@ -234,9 +234,9 @@ class Accessible(BaseProxy): point to the same object. """ return (self._app_name == accessible._app_name) and \ - (self._acc_path == accessible._acc_path) + (self._acc_path == accessible._acc_path) + - def get_childCount(self): return len(self.cached_data.children) _childCountDoc = \ @@ -246,7 +246,7 @@ class Accessible(BaseProxy): childCount = property(fget=get_childCount, doc=_childCountDoc) getChildCount = get_childCount - + def get_description(self): return self.cached_data.description _descriptionDoc = \ @@ -254,7 +254,7 @@ class Accessible(BaseProxy): a string describing the object in more detail than name. """ description = property(fget=get_description, doc=_descriptionDoc) - + def get_name(self): return self.cached_data.name _nameDoc = \ @@ -262,16 +262,16 @@ class Accessible(BaseProxy): a (short) string representing the object's name. """ name = property(fget=get_name, doc=_nameDoc) - + def get_parent(self): - if self._parent: - return self._parent - else: - return create_accessible(self._cache, - self._app_name, - self.cached_data.parent, - ATSPI_ACCESSIBLE, - connection=self._cache._connection) + if self._parent: + return self._parent + else: + return create_accessible(self._cache, + self._app_name, + self.cached_data.parent, + ATSPI_ACCESSIBLE, + connection=self._cache._connection) _parentDoc = \ """ diff --git a/pyatspi/action.py b/pyatspi/action.py index 4d0c6d4..5668555 100644 --- a/pyatspi/action.py +++ b/pyatspi/action.py @@ -17,83 +17,83 @@ from base import BaseProxy from factory import create_accessible, add_accessible_class __all__ = [ - "Action", - ] + "Action", + ] #------------------------------------------------------------------------------ class Action(BaseProxy): - """ - An interface through which a user-actionable user interface component - can be manipulated. Components which react to mouse or keyboard - input from the user, (with the exception of pure text entry fields - with no other function), should implement this interface. Typical - actions include "click", "press", "release" (for instance for - buttons), "menu" (for objects which have context menus invokable - from mouse or keyboard), "open" for icons representing files - folders, and others. - """ - - def doAction(self, index): """ - doAction: - @param : index - the 0-based index of the action to perform. - Causes the object to perform the specified action. - @return : a boolean indicating success or failure. + An interface through which a user-actionable user interface component + can be manipulated. Components which react to mouse or keyboard + input from the user, (with the exception of pure text entry fields + with no other function), should implement this interface. Typical + actions include "click", "press", "release" (for instance for + buttons), "menu" (for objects which have context menus invokable + from mouse or keyboard), "open" for icons representing files + folders, and others. """ - func = self.get_dbus_method("doAction") - return func(index) - - def getDescription(self, index): - """ - getDescription: - @param : index - the index of the action for which a description is desired. - Get the description of the specified action. The description - of an action may provide information about the result of action - invocation, unlike the action name. - @return : a string containing the description of the specified - action. - """ - func = self.get_dbus_method("getDescription") - return func(index) - - def getKeyBinding(self, index): - """ - getKeyBinding: - @param : index - the 0-based index of the action for which a key binding is requested. - Get the key binding associated with a specific action. - @return : a string containing the key binding for the specified - action, or an empty string ("") if none exists. - """ - func = self.get_dbus_method("getKeyBinding") - return func(index) - - def getName(self, index): - """ - getName: - @param : index - the index of the action whose name is requested. - Get the name of the specified action. Action names generally - describe the user action, i.e. "click" or "press", rather then - the result of invoking the action. - @return : a string containing the name of the specified action. - """ - func = self.get_dbus_method("getName") - return func(index) - - def get_nActions(self): - return self._pgetter(self._dbus_interface, "nActions") - def set_nActions(self, value): - self._psetter(self._dbus_interface, "nActions", value) - _nActionsDoc = \ - """ - nActions: a long containing the number of actions this object - supports. - """ - nActions = property(fget=get_nActions, fset=set_nActions, doc=_nActionsDoc) + + def doAction(self, index): + """ + doAction: + @param : index + the 0-based index of the action to perform. + Causes the object to perform the specified action. + @return : a boolean indicating success or failure. + """ + func = self.get_dbus_method("doAction") + return func(index) + + def getDescription(self, index): + """ + getDescription: + @param : index + the index of the action for which a description is desired. + Get the description of the specified action. The description + of an action may provide information about the result of action + invocation, unlike the action name. + @return : a string containing the description of the specified + action. + """ + func = self.get_dbus_method("getDescription") + return func(index) + + def getKeyBinding(self, index): + """ + getKeyBinding: + @param : index + the 0-based index of the action for which a key binding is requested. + Get the key binding associated with a specific action. + @return : a string containing the key binding for the specified + action, or an empty string ("") if none exists. + """ + func = self.get_dbus_method("getKeyBinding") + return func(index) + + def getName(self, index): + """ + getName: + @param : index + the index of the action whose name is requested. + Get the name of the specified action. Action names generally + describe the user action, i.e. "click" or "press", rather then + the result of invoking the action. + @return : a string containing the name of the specified action. + """ + func = self.get_dbus_method("getName") + return func(index) + + def get_nActions(self): + return self._pgetter(self._dbus_interface, "nActions") + def set_nActions(self, value): + self._psetter(self._dbus_interface, "nActions", value) + _nActionsDoc = \ + """ + nActions: a long containing the number of actions this object + supports. + """ + nActions = property(fget=get_nActions, fset=set_nActions, doc=_nActionsDoc) # Register the Accessible class with the accessible factory. add_accessible_class(interfaces.ATSPI_ACTION, Action) diff --git a/pyatspi/application.py b/pyatspi/application.py index 12abe5a..3cc2a7d 100644 --- a/pyatspi/application.py +++ b/pyatspi/application.py @@ -18,108 +18,108 @@ from factory import add_accessible_class from accessible import Accessible __all__ = [ - "Application", - ] + "Application", + ] #------------------------------------------------------------------------------ class Application(Accessible): - """ - An interface identifying an object which is the root of the user - interface Accessible hierarchy associated with a running application. - Children of Application are typically, but not exclusively, top-level - windows. - """ - - def getLocale(self, *args, **kwargs): """ - Gets the locale in which the application is currently operating. - For the current message locale, use lctype LOCALE_TYPE_MESSAGES. - @param : lctype - The LocaleType for which the locale is queried. - @return a string compliant with the POSIX standard for locale - description. + An interface identifying an object which is the root of the user + interface Accessible hierarchy associated with a running application. + Children of Application are typically, but not exclusively, top-level + windows. """ - func = self.get_dbus_method("getLocale") - return func(*args, **kwargs) - - def pause(self, *args, **kwargs): - """ - Request that the application temporarily stop sending events. - In most cases this should pause the application's main event - loop. - @return : true if the request succeeded, false otherwise. - """ - func = self.get_dbus_method("pause") - return func(*args, **kwargs) - - def registerObjectEventListener(self, *args, **kwargs): - """ - registerObjectEventListener: - @param : listener - an EventListener object which will receive the requested events - @param : eventName - a UTF-8 string indicating the type of (toolkit-specific) event - being requested. Register with this application toolkit for "Accessibility::Accessible" - event notifications. - """ - func = self.get_dbus_method("registerObjectEventListener") - return func(*args, **kwargs) - - def registerToolkitEventListener(self, *args, **kwargs): - """ - @param : listener - an EventListener object which will receive the requested events - from the application's toolkits via toolit 'bridges' - @param : eventName - a UTF-8 string indicating the type of (toolkit-specific) event - being requested. Not all applications can generate toolkit events - of a given type. - Register with this application's toolkit for "toolkit-specific" - event notifications. - """ - func = self.get_dbus_method("registerToolkitEventListener") - return func(*args, **kwargs) - - def resume(self, *args, **kwargs): - """ - Request that the application resume sending events. - @return : True if the request succeeded, False otherwise. - """ - func = self.get_dbus_method("resume") - return func(*args, **kwargs) - - def get_id(self): - return self._pgetter(self._dbus_interface, "id") - def set_id(self, value): - self._psetter(self._dbus_interface, "id", value) - _idDoc = \ - """ - The application instance's unique ID as assigned by the registry. - """ - id = property(fget=get_id, fset=set_id, doc=_idDoc) - - def get_toolkitName(self): - return self._pgetter(self._dbus_interface, "toolkitName") - def set_toolkitName(self, value): - self._psetter(self._dbus_interface, "toolkitName", value) - _toolkitNameDoc = \ - """ - A string indicating the type of user interface toolkit which - is used by the application. - """ - toolkitName = property(fget=get_toolkitName, fset=set_toolkitName, doc=_toolkitNameDoc) - - def get_version(self): - return self._pgetter(self._dbus_interface, "version") - def set_version(self, value): - self._psetter(self._dbus_interface, "version", value) - _versionDoc = \ - """ - A string indicating the version number of the application's accessibility - bridge implementation. - """ - version = property(fget=get_version, fset=set_version, doc=_versionDoc) + + def getLocale(self, *args, **kwargs): + """ + Gets the locale in which the application is currently operating. + For the current message locale, use lctype LOCALE_TYPE_MESSAGES. + @param : lctype + The LocaleType for which the locale is queried. + @return a string compliant with the POSIX standard for locale + description. + """ + func = self.get_dbus_method("getLocale") + return func(*args, **kwargs) + + def pause(self, *args, **kwargs): + """ + Request that the application temporarily stop sending events. + In most cases this should pause the application's main event + loop. + @return : true if the request succeeded, false otherwise. + """ + func = self.get_dbus_method("pause") + return func(*args, **kwargs) + + def registerObjectEventListener(self, *args, **kwargs): + """ + registerObjectEventListener: + @param : listener + an EventListener object which will receive the requested events + @param : eventName + a UTF-8 string indicating the type of (toolkit-specific) event + being requested. Register with this application toolkit for "Accessibility::Accessible" + event notifications. + """ + func = self.get_dbus_method("registerObjectEventListener") + return func(*args, **kwargs) + + def registerToolkitEventListener(self, *args, **kwargs): + """ + @param : listener + an EventListener object which will receive the requested events + from the application's toolkits via toolit 'bridges' + @param : eventName + a UTF-8 string indicating the type of (toolkit-specific) event + being requested. Not all applications can generate toolkit events + of a given type. + Register with this application's toolkit for "toolkit-specific" + event notifications. + """ + func = self.get_dbus_method("registerToolkitEventListener") + return func(*args, **kwargs) + + def resume(self, *args, **kwargs): + """ + Request that the application resume sending events. + @return : True if the request succeeded, False otherwise. + """ + func = self.get_dbus_method("resume") + return func(*args, **kwargs) + + def get_id(self): + return self._pgetter(self._dbus_interface, "id") + def set_id(self, value): + self._psetter(self._dbus_interface, "id", value) + _idDoc = \ + """ + The application instance's unique ID as assigned by the registry. + """ + id = property(fget=get_id, fset=set_id, doc=_idDoc) + + def get_toolkitName(self): + return self._pgetter(self._dbus_interface, "toolkitName") + def set_toolkitName(self, value): + self._psetter(self._dbus_interface, "toolkitName", value) + _toolkitNameDoc = \ + """ + A string indicating the type of user interface toolkit which + is used by the application. + """ + toolkitName = property(fget=get_toolkitName, fset=set_toolkitName, doc=_toolkitNameDoc) + + def get_version(self): + return self._pgetter(self._dbus_interface, "version") + def set_version(self, value): + self._psetter(self._dbus_interface, "version", value) + _versionDoc = \ + """ + A string indicating the version number of the application's accessibility + bridge implementation. + """ + version = property(fget=get_version, fset=set_version, doc=_versionDoc) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_APPLICATION, Application) diff --git a/pyatspi/base.py b/pyatspi/base.py index c950ec8..46a4ecc 100644 --- a/pyatspi/base.py +++ b/pyatspi/base.py @@ -20,143 +20,143 @@ import interfaces from factory import create_accessible __all__ = [ - "AccessibleObjectNoLongerExists", - "Enum", - "BaseProxy", - ] + "AccessibleObjectNoLongerExists", + "Enum", + "BaseProxy", + ] class AccessibleObjectNoLongerExists(Exception): - pass + pass #------------------------------------------------------------------------------ class Enum(int): - def __str__(self): - return self._enum_lookup[int(self)] + def __str__(self): + return self._enum_lookup[int(self)] #------------------------------------------------------------------------------ class BaseProxyMeta(type): - def __new__(meta, *args, **kwargs): - cls = type.__new__(meta, *args, **kwargs) - - queryable_interfaces = { - 'Accessible':interfaces.ATSPI_ACCESSIBLE, - 'Action':interfaces.ATSPI_ACTION, - 'Application':interfaces.ATSPI_APPLICATION, - 'Collection':interfaces.ATSPI_COLLECTION, - 'Component':interfaces.ATSPI_COMPONENT, - 'Desktop':interfaces.ATSPI_DESKTOP, - 'Document':interfaces.ATSPI_DOCUMENT, - 'EditableText':interfaces.ATSPI_EDITABLE_TEXT, - 'Hypertext':interfaces.ATSPI_HYPERTEXT, - 'Hyperlink':interfaces.ATSPI_HYPERLINK, - 'Image':interfaces.ATSPI_IMAGE, - 'Selection':interfaces.ATSPI_SELECTION, - 'StreamableContent':interfaces.ATSPI_STREAMABLE_CONTENT, - 'Table':interfaces.ATSPI_TABLE, - 'Text':interfaces.ATSPI_TEXT, - 'Value':interfaces.ATSPI_VALUE, - } - - def return_query(interface): - def new_query(self): - return self.queryInterface(interface) - return new_query - - for interface in queryable_interfaces.keys(): - name = 'query%s' % interface - setattr(cls, name, return_query(queryable_interfaces[interface])) - - return cls + def __new__(meta, *args, **kwargs): + cls = type.__new__(meta, *args, **kwargs) + + queryable_interfaces = { + 'Accessible':interfaces.ATSPI_ACCESSIBLE, + 'Action':interfaces.ATSPI_ACTION, + 'Application':interfaces.ATSPI_APPLICATION, + 'Collection':interfaces.ATSPI_COLLECTION, + 'Component':interfaces.ATSPI_COMPONENT, + 'Desktop':interfaces.ATSPI_DESKTOP, + 'Document':interfaces.ATSPI_DOCUMENT, + 'EditableText':interfaces.ATSPI_EDITABLE_TEXT, + 'Hypertext':interfaces.ATSPI_HYPERTEXT, + 'Hyperlink':interfaces.ATSPI_HYPERLINK, + 'Image':interfaces.ATSPI_IMAGE, + 'Selection':interfaces.ATSPI_SELECTION, + 'StreamableContent':interfaces.ATSPI_STREAMABLE_CONTENT, + 'Table':interfaces.ATSPI_TABLE, + 'Text':interfaces.ATSPI_TEXT, + 'Value':interfaces.ATSPI_VALUE, + } + + def return_query(interface): + def new_query(self): + return self.queryInterface(interface) + return new_query + + for interface in queryable_interfaces.keys(): + name = 'query%s' % interface + setattr(cls, name, return_query(queryable_interfaces[interface])) + + return cls #------------------------------------------------------------------------------ class BaseProxy(Interface): - """ - The base D-Bus proxy for a remote object that implements one or more - of the AT-SPI interfaces. - """ - - __metaclass__ = BaseProxyMeta - - def __init__(self, cache, app_name, acc_path, interface, dbus_object=None, connection=None, parent=None): - """ - Create a D-Bus Proxy for an ATSPI interface. - - cache - ApplicationCache, where the cached data for the accessible can be obtained. - app_name - D-Bus bus name of the application this accessible belongs to. - acc_path - D-Bus object path of the server side accessible object. - parent - Parent accessible. - interface - D-Bus interface of the object. Used to decide which accessible class to instanciate. - dbus_object(kwarg) - The D-Bus proxy object used by the accessible for D-Bus method calls. - """ - self._cache = cache - self._app_name = app_name - self._acc_path = acc_path - self._parent = parent - - if not dbus_object: - dbus_object = connection.get_object(self._app_name, self._acc_path, introspect=False) - self._dbus_object = dbus_object - - Interface.__init__(self, self._dbus_object, interface) - - self._pgetter = self.get_dbus_method("Get", dbus_interface="org.freedesktop.DBus.Properties") - self._psetter = self.get_dbus_method("Set", dbus_interface="org.freedesktop.DBus.Properties") - - def __getattr__(self, attr): - raise AttributeError("\'%s\' has no attribute \'%s\'" % (self.__class__.__name__, attr)) - - def __str__(self): - try: - return '[%s | %s]' % (self.getRoleName(), self.name) - except Exception: - return '[DEAD]' - - def get_dbus_method(self, *args, **kwargs): - method = Interface.get_dbus_method(self, *args, **kwargs) - - def dbus_method_func(*args, **kwargs): - # TODO Need to throw an AccessibleObjectNoLongerExists exception - # on D-Bus error of the same type. - try: - return method(*args, **kwargs) - except UnknownMethodException, e: - raise NotImplementedError(e) - except DBusException, e: - raise LookupError(e) - - return dbus_method_func - - @property - def cached_data(self): - try: - return self._cache[self._app_name][self._acc_path] - except KeyError: - raise AccessibleObjectNoLongerExists, \ - 'Cache data cannot be found for path %s in app %s' % (self._acc_path, self._app_name) - - @property - def interfaces(self): - return self.cached_data.interfaces - - def queryInterface(self, interface): - """ - Gets a different accessible interface for this object - or raises a NotImplemented error if the given interface - is not supported. - """ - if interface in self.interfaces: - return create_accessible(self._cache, - self._app_name, - self._acc_path, - interface, - dbus_object=self._dbus_object) - else: - raise NotImplementedError( - "%s not supported by accessible object at path %s" - % (interface, self._acc_path)) + """ + The base D-Bus proxy for a remote object that implements one or more + of the AT-SPI interfaces. + """ + + __metaclass__ = BaseProxyMeta + + def __init__(self, cache, app_name, acc_path, interface, dbus_object=None, connection=None, parent=None): + """ + Create a D-Bus Proxy for an ATSPI interface. + + cache - ApplicationCache, where the cached data for the accessible can be obtained. + app_name - D-Bus bus name of the application this accessible belongs to. + acc_path - D-Bus object path of the server side accessible object. + parent - Parent accessible. + interface - D-Bus interface of the object. Used to decide which accessible class to instanciate. + dbus_object(kwarg) - The D-Bus proxy object used by the accessible for D-Bus method calls. + """ + self._cache = cache + self._app_name = app_name + self._acc_path = acc_path + self._parent = parent + + if not dbus_object: + dbus_object = connection.get_object(self._app_name, self._acc_path, introspect=False) + self._dbus_object = dbus_object + + Interface.__init__(self, self._dbus_object, interface) + + self._pgetter = self.get_dbus_method("Get", dbus_interface="org.freedesktop.DBus.Properties") + self._psetter = self.get_dbus_method("Set", dbus_interface="org.freedesktop.DBus.Properties") + + def __getattr__(self, attr): + raise AttributeError("\'%s\' has no attribute \'%s\'" % (self.__class__.__name__, attr)) + + def __str__(self): + try: + return '[%s | %s]' % (self.getRoleName(), self.name) + except Exception: + return '[DEAD]' + + def get_dbus_method(self, *args, **kwargs): + method = Interface.get_dbus_method(self, *args, **kwargs) + + def dbus_method_func(*args, **kwargs): + # TODO Need to throw an AccessibleObjectNoLongerExists exception + # on D-Bus error of the same type. + try: + return method(*args, **kwargs) + except UnknownMethodException, e: + raise NotImplementedError(e) + except DBusException, e: + raise LookupError(e) + + return dbus_method_func + + @property + def cached_data(self): + try: + return self._cache[self._app_name][self._acc_path] + except KeyError: + raise AccessibleObjectNoLongerExists, \ + 'Cache data cannot be found for path %s in app %s' % (self._acc_path, self._app_name) + + @property + def interfaces(self): + return self.cached_data.interfaces + + def queryInterface(self, interface): + """ + Gets a different accessible interface for this object + or raises a NotImplemented error if the given interface + is not supported. + """ + if interface in self.interfaces: + return create_accessible(self._cache, + self._app_name, + self._acc_path, + interface, + dbus_object=self._dbus_object) + else: + raise NotImplementedError( + "%s not supported by accessible object at path %s" + % (interface, self._acc_path)) #END---------------------------------------------------------------------------- diff --git a/pyatspi/cache.py b/pyatspi/cache.py index e744ca5..8b2bde9 100644 --- a/pyatspi/cache.py +++ b/pyatspi/cache.py @@ -19,157 +19,157 @@ from event import Event as _Event #------------------------------------------------------------------------------ class _CacheData(object): - __slots__ = [ - 'parent', - 'interfaces', - 'children', - 'role', - 'name', - 'description', - ] - - def __init__(self, data): - self._update(data) - - def _update(self, data): - #Don't cache the path here, used as lookup in cache object dict. - (path, - self.parent, - self.children, - self.interfaces, - self.name, - self.role, - self.description) = data + __slots__ = [ + 'parent', + 'interfaces', + 'children', + 'role', + 'name', + 'description', + ] + + def __init__(self, data): + self._update(data) + + def _update(self, data): + #Don't cache the path here, used as lookup in cache object dict. + (path, + self.parent, + self.children, + self.interfaces, + self.name, + self.role, + self.description) = data #------------------------------------------------------------------------------ class AccessibleCache(object): - """ - There is one accessible cache per application. - For each application the accessible cache stores - data on every accessible object within the app. - - It also acts as the factory for creating client - side proxies for these accessible objects. - - connection - DBus connection. - busName - Name of DBus connection where cache interface resides. - """ - - _PATH = '/org/freedesktop/atspi/tree' - _INTERFACE = 'org.freedesktop.atspi.Tree' - _GET_METHOD = 'getTree' - _UPDATE_SIGNAL = 'updateTree' - - def __init__(self, registry, connection, bus_name): - """ - Creates a cache. - - connection - DBus connection. - busName - Name of DBus connection where cache interface resides. - """ - self._registry = registry - self._connection = connection - self._bus_name = bus_name - - obj = connection.get_object(bus_name, self._PATH, introspect=False) - itf = _dbus.Interface(obj, self._INTERFACE) - - self._objects = {} - - get_method = itf.get_dbus_method(self._GET_METHOD) - self._update_objects(get_method()) - - self._signalMatch = itf.connect_to_signal(self._UPDATE_SIGNAL, self._update_handler) - - obj = connection.get_object(self._bus_name, self._PATH, introspect=False) - itf = _dbus.Interface(obj, self._INTERFACE) - - self._root = itf.getRoot() - - def __getitem__(self, key): - return self._objects[key] - - def __contains__(self, key): - return key in self._objects - - def _update_cache_dispatch_events(self, cachedata, data): - (path, - parent, - children, - interfaces, - name, - role, - description) = data - - # TODO The 'self._registry._cache' statement makes me think - # I have serious modularization FAIL here. - - if name != cachedata.name: - event = _Event(self._registry._cache, - path, - self._bus_name, - "org.freedesktop.atspi.Event.Object", - "property-change", - ("name", 0, 0, name)) - self._registry._notifyNameChange(event) - - if description != cachedata.description: - event = _Event(self._registry._cache, - path, - self._bus_name, - "org.freedesktop.atspi.Event.Object", - "property-change", - ("description", 0, 0, description)) - self._registry._notifyDescriptionChange(event) - - if parent != cachedata.parent: - event = _Event(self._registry._cache, - path, - self._bus_name, - "org.freedesktop.atspi.Event.Object", - "property-change", - ("parent", 0, 0, "")) - self._registry._notifyParentChange(event) - - if children != cachedata.children: - event = _Event(self._registry._cache, - path, - self._bus_name, - "org.freedesktop.atspi.Event.Object", - "children-changed", - ("", 0, 0, "")) - self._registry._notifyChildrenChange(event) - - cachedata._update(data) - - def _update_handler(self, update, remove): - self._remove_objects(remove) - self._update_objects(update) - - def _update_objects(self, objects): - for data in objects: - #First element is the object path. - path = data[0] - if path in self._objects: - cachedata = self._objects[path] - self._update_cache_dispatch_events(cachedata, data) - else: - self._objects[path] = _CacheData(data) - - def _remove_objects(self, paths): - for path in paths: - # TODO I'm squashing a possible error here - # I've seen things appear to be deleted twice - # which needs investigation - try: - del(self._objects[path]) - except KeyError: - pass - - def _get_root(self): - return self._root - - root = property(fget=_get_root) + """ + There is one accessible cache per application. + For each application the accessible cache stores + data on every accessible object within the app. + + It also acts as the factory for creating client + side proxies for these accessible objects. + + connection - DBus connection. + busName - Name of DBus connection where cache interface resides. + """ + + _PATH = '/org/freedesktop/atspi/tree' + _INTERFACE = 'org.freedesktop.atspi.Tree' + _GET_METHOD = 'getTree' + _UPDATE_SIGNAL = 'updateTree' + + def __init__(self, registry, connection, bus_name): + """ + Creates a cache. + + connection - DBus connection. + busName - Name of DBus connection where cache interface resides. + """ + self._registry = registry + self._connection = connection + self._bus_name = bus_name + + obj = connection.get_object(bus_name, self._PATH, introspect=False) + itf = _dbus.Interface(obj, self._INTERFACE) + + self._objects = {} + + get_method = itf.get_dbus_method(self._GET_METHOD) + self._update_objects(get_method()) + + self._signalMatch = itf.connect_to_signal(self._UPDATE_SIGNAL, self._update_handler) + + obj = connection.get_object(self._bus_name, self._PATH, introspect=False) + itf = _dbus.Interface(obj, self._INTERFACE) + + self._root = itf.getRoot() + + def __getitem__(self, key): + return self._objects[key] + + def __contains__(self, key): + return key in self._objects + + def _update_cache_dispatch_events(self, cachedata, data): + (path, + parent, + children, + interfaces, + name, + role, + description) = data + + # TODO The 'self._registry._cache' statement makes me think + # I have serious modularization FAIL here. + + if name != cachedata.name: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "property-change", + ("name", 0, 0, name)) + self._registry._notifyNameChange(event) + + if description != cachedata.description: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "property-change", + ("description", 0, 0, description)) + self._registry._notifyDescriptionChange(event) + + if parent != cachedata.parent: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "property-change", + ("parent", 0, 0, "")) + self._registry._notifyParentChange(event) + + if children != cachedata.children: + event = _Event(self._registry._cache, + path, + self._bus_name, + "org.freedesktop.atspi.Event.Object", + "children-changed", + ("", 0, 0, "")) + self._registry._notifyChildrenChange(event) + + cachedata._update(data) + + def _update_handler(self, update, remove): + self._remove_objects(remove) + self._update_objects(update) + + def _update_objects(self, objects): + for data in objects: + #First element is the object path. + path = data[0] + if path in self._objects: + cachedata = self._objects[path] + self._update_cache_dispatch_events(cachedata, data) + else: + self._objects[path] = _CacheData(data) + + def _remove_objects(self, paths): + for path in paths: + # TODO I'm squashing a possible error here + # I've seen things appear to be deleted twice + # which needs investigation + try: + del(self._objects[path]) + except KeyError: + pass + + def _get_root(self): + return self._root + + root = property(fget=_get_root) #END--------------------------------------------------------------------------- diff --git a/pyatspi/collection.py b/pyatspi/collection.py index d3b4f11..2a8e66f 100644 --- a/pyatspi/collection.py +++ b/pyatspi/collection.py @@ -17,106 +17,91 @@ from base import BaseProxy, Enum from factory import add_accessible_class __all__ = [ - "Collection", - ] + "Collection", + ] #------------------------------------------------------------------------------ class Collection(BaseProxy): - - def createMatchRule(self, *args, **kwargs): - func = self.get_dbus_method("createMatchRule") - return func(*args, **kwargs) - - def freeMatchRule(self, *args, **kwargs): - func = self.get_dbus_method("freeMatchRule") - return func(*args, **kwargs) - - def getActiveDescendant(self, *args, **kwargs): - func = self.get_dbus_method("getActiveDescendant") - return func(*args, **kwargs) - - def getMatches(self, *args, **kwargs): - func = self.get_dbus_method("getMatches") - return func(*args, **kwargs) - - def getMatchesFrom(self, *args, **kwargs): - func = self.get_dbus_method("getMatchesFrom") - return func(*args, **kwargs) - - def getMatchesTo(self, *args, **kwargs): - func = self.get_dbus_method("getMatchesTo") - return func(*args, **kwargs) - - def isAncestorOf(self, *args, **kwargs): - func = self.get_dbus_method("isAncestorOf") - 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', - } - - MATCH_ALL = MatchType(1) - - MATCH_ANY = MatchType(2) - - MATCH_EMPTY = MatchType(4) - - MATCH_INVALID = MatchType(0) - - 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) - - SORT_ORDER_LAST_DEFINED = SortOrder(7) - - SORT_ORDER_REVERSE_CANONICAL = SortOrder(4) - - SORT_ORDER_REVERSE_FLOW = SortOrder(5) - - 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 createMatchRule(self, *args, **kwargs): + func = self.get_dbus_method("createMatchRule") + return func(*args, **kwargs) + + def freeMatchRule(self, *args, **kwargs): + func = self.get_dbus_method("freeMatchRule") + return func(*args, **kwargs) + + def getActiveDescendant(self, *args, **kwargs): + func = self.get_dbus_method("getActiveDescendant") + return func(*args, **kwargs) + + def getMatches(self, *args, **kwargs): + func = self.get_dbus_method("getMatches") + return func(*args, **kwargs) + + def getMatchesFrom(self, *args, **kwargs): + func = self.get_dbus_method("getMatchesFrom") + return func(*args, **kwargs) + + def getMatchesTo(self, *args, **kwargs): + func = self.get_dbus_method("getMatchesTo") + return func(*args, **kwargs) + + def isAncestorOf(self, *args, **kwargs): + func = self.get_dbus_method("isAncestorOf") + 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', + } + + MATCH_ALL = MatchType(1) + MATCH_ANY = MatchType(2) + MATCH_EMPTY = MatchType(4) + MATCH_INVALID = MatchType(0) + 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) + SORT_ORDER_LAST_DEFINED = SortOrder(7) + SORT_ORDER_REVERSE_CANONICAL = SortOrder(4) + SORT_ORDER_REVERSE_FLOW = SortOrder(5) + 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) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_COLLECTION, Collection) diff --git a/pyatspi/component.py b/pyatspi/component.py index 5641c79..ff39600 100644 --- a/pyatspi/component.py +++ b/pyatspi/component.py @@ -20,29 +20,29 @@ from accessible import BoundingBox from dbus.types import Int16 __all__ = [ - "CoordType", - "XY_SCREEN", - "XY_WINDOW", - "ComponentLayer", - "Component", - "LAYER_BACKGROUND", - "LAYER_CANVAS", - "LAYER_INVALID", - "LAYER_LAST_DEFINED", - "LAYER_MDI", - "LAYER_OVERLAY", - "LAYER_POPUP", - "LAYER_WIDGET", - "LAYER_WINDOW", - ] + "CoordType", + "XY_SCREEN", + "XY_WINDOW", + "ComponentLayer", + "Component", + "LAYER_BACKGROUND", + "LAYER_CANVAS", + "LAYER_INVALID", + "LAYER_LAST_DEFINED", + "LAYER_MDI", + "LAYER_OVERLAY", + "LAYER_POPUP", + "LAYER_WIDGET", + "LAYER_WINDOW", + ] #------------------------------------------------------------------------------ class CoordType(Enum): - _enum_lookup = { - 0:'XY_SCREEN', - 1:'XY_WINDOW', - } + _enum_lookup = { + 0:'XY_SCREEN', + 1:'XY_WINDOW', + } XY_SCREEN = CoordType(0) XY_WINDOW = CoordType(1) @@ -50,17 +50,17 @@ XY_WINDOW = CoordType(1) #------------------------------------------------------------------------------ class ComponentLayer(Enum): - _enum_lookup = { - 0:'LAYER_INVALID', - 1:'LAYER_BACKGROUND', - 2:'LAYER_CANVAS', - 3:'LAYER_WIDGET', - 4:'LAYER_MDI', - 5:'LAYER_POPUP', - 6:'LAYER_OVERLAY', - 7:'LAYER_WINDOW', - 8:'LAYER_LAST_DEFINED', - } + _enum_lookup = { + 0:'LAYER_INVALID', + 1:'LAYER_BACKGROUND', + 2:'LAYER_CANVAS', + 3:'LAYER_WIDGET', + 4:'LAYER_MDI', + 5:'LAYER_POPUP', + 6:'LAYER_OVERLAY', + 7:'LAYER_WINDOW', + 8:'LAYER_LAST_DEFINED', + } LAYER_BACKGROUND = ComponentLayer(1) LAYER_CANVAS = ComponentLayer(2) @@ -75,127 +75,127 @@ LAYER_WINDOW = ComponentLayer(7) #------------------------------------------------------------------------------ class Component(BaseProxy): - """ - The Component interface is implemented by objects which occupy - on-screen space, e.g. objects which have onscreen visual representations. - The methods in Component allow clients to identify where the - objects lie in the onscreen coordinate system, their relative - size, stacking order, and position. It also provides a mechanism - whereby keyboard focus may be transferred to specific user interface - elements programmatically. This is a 2D API, coordinates of 3D - objects are projected into the 2-dimensional screen view for - purposes of this interface. - """ - - def contains(self, *args, **kwargs): """ - @return True if the specified point lies within the Component's - bounding box, False otherwise. + The Component interface is implemented by objects which occupy + on-screen space, e.g. objects which have onscreen visual representations. + The methods in Component allow clients to identify where the + objects lie in the onscreen coordinate system, their relative + size, stacking order, and position. It also provides a mechanism + whereby keyboard focus may be transferred to specific user interface + elements programmatically. This is a 2D API, coordinates of 3D + objects are projected into the 2-dimensional screen view for + purposes of this interface. """ - func = self.get_dbus_method("contains") - return func(*args, **kwargs) - - def deregisterFocusHandler(self, *args, **kwargs): - """ - Request that an EventListener registered via registerFocusHandler - no longer be notified when this object receives keyboard focus. - """ - func = self.get_dbus_method("deregisterFocusHandler") - return func(*args, **kwargs) - - def getAccessibleAtPoint(self, *args, **kwargs): - """ - @return the Accessible child whose bounding box contains the - specified point. - """ - func = self.get_dbus_method("getAccessibleAtPoint") - return func(*args, **kwargs) - - def getAlpha(self, *args, **kwargs): - """ - Obtain the alpha value of the component. An alpha value of 1.0 - or greater indicates that the object is fully opaque, and an - alpha value of 0.0 indicates that the object is fully transparent. - Negative alpha values have no defined meaning at this time. - """ - func = self.get_dbus_method("getAlpha") - return func(*args, **kwargs) - - def getExtents(self, coord_type): - """ - Obtain the Component's bounding box, in pixels, relative to the - specified coordinate system. - @param coord_type - @return a BoundingBox which entirely contains the object's onscreen - visual representation. - """ - func = self.get_dbus_method("getExtents") - extents = func(Int16(coord_type)) - return BoundingBox(*extents) - - def getLayer(self, *args, **kwargs): - """ - @return the ComponentLayer in which this object resides. - """ - func = self.get_dbus_method("getLayer") - return ComponentLayer(func(*args, **kwargs)) - - def getMDIZOrder(self): - """ - Obtain the relative stacking order (i.e. 'Z' order) of an object. - Larger values indicate that an object is on "top" of the stack, - therefore objects with smaller MDIZOrder may be obscured by objects - with a larger MDIZOrder, but not vice-versa. - @return an integer indicating the object's place in the stacking - order. - """ - func = self.get_dbus_method("getMDIZOrder") - return func() - - def getPosition(self, coord_type): - """ - Obtain the position of the current component in the coordinate - system specified by coord_type. - @param : coord_type - @param : x - an out parameter which will be back-filled with the returned - x coordinate. - @param : y - an out parameter which will be back-filled with the returned - y coordinate. - """ - func = self.get_dbus_method("getPosition") - return func(Int16(coord_type)) - - def getSize(self, *args, **kwargs): - """ - Obtain the size, in the coordinate system specified by coord_type, - of the rectangular area which fully contains the object's visual - representation, without accounting for viewport clipping. - @param : width - the object's horizontal extents in the specified coordinate system. - @param : height - the object's vertical extents in the specified coordinate system. - """ - func = self.get_dbus_method("getSize") - return func(*args, **kwargs) - - def grabFocus(self, *args, **kwargs): - """ - Request that the object obtain keyboard focus. - @return True if keyboard focus was successfully transferred to - the Component. - """ - func = self.get_dbus_method("grabFocus") - return func(*args, **kwargs) - - def registerFocusHandler(self, *args, **kwargs): - """ - Register an EventListener for notification when this object receives - keyboard focus. - """ - func = self.get_dbus_method("registerFocusHandler") - return func(*args, **kwargs) + + def contains(self, *args, **kwargs): + """ + @return True if the specified point lies within the Component's + bounding box, False otherwise. + """ + func = self.get_dbus_method("contains") + return func(*args, **kwargs) + + def deregisterFocusHandler(self, *args, **kwargs): + """ + Request that an EventListener registered via registerFocusHandler + no longer be notified when this object receives keyboard focus. + """ + func = self.get_dbus_method("deregisterFocusHandler") + return func(*args, **kwargs) + + def getAccessibleAtPoint(self, *args, **kwargs): + """ + @return the Accessible child whose bounding box contains the + specified point. + """ + func = self.get_dbus_method("getAccessibleAtPoint") + return func(*args, **kwargs) + + def getAlpha(self, *args, **kwargs): + """ + Obtain the alpha value of the component. An alpha value of 1.0 + or greater indicates that the object is fully opaque, and an + alpha value of 0.0 indicates that the object is fully transparent. + Negative alpha values have no defined meaning at this time. + """ + func = self.get_dbus_method("getAlpha") + return func(*args, **kwargs) + + def getExtents(self, coord_type): + """ + Obtain the Component's bounding box, in pixels, relative to the + specified coordinate system. + @param coord_type + @return a BoundingBox which entirely contains the object's onscreen + visual representation. + """ + func = self.get_dbus_method("getExtents") + extents = func(Int16(coord_type)) + return BoundingBox(*extents) + + def getLayer(self, *args, **kwargs): + """ + @return the ComponentLayer in which this object resides. + """ + func = self.get_dbus_method("getLayer") + return ComponentLayer(func(*args, **kwargs)) + + def getMDIZOrder(self): + """ + Obtain the relative stacking order (i.e. 'Z' order) of an object. + Larger values indicate that an object is on "top" of the stack, + therefore objects with smaller MDIZOrder may be obscured by objects + with a larger MDIZOrder, but not vice-versa. + @return an integer indicating the object's place in the stacking + order. + """ + func = self.get_dbus_method("getMDIZOrder") + return func() + + def getPosition(self, coord_type): + """ + Obtain the position of the current component in the coordinate + system specified by coord_type. + @param : coord_type + @param : x + an out parameter which will be back-filled with the returned + x coordinate. + @param : y + an out parameter which will be back-filled with the returned + y coordinate. + """ + func = self.get_dbus_method("getPosition") + return func(Int16(coord_type)) + + def getSize(self, *args, **kwargs): + """ + Obtain the size, in the coordinate system specified by coord_type, + of the rectangular area which fully contains the object's visual + representation, without accounting for viewport clipping. + @param : width + the object's horizontal extents in the specified coordinate system. + @param : height + the object's vertical extents in the specified coordinate system. + """ + func = self.get_dbus_method("getSize") + return func(*args, **kwargs) + + def grabFocus(self, *args, **kwargs): + """ + Request that the object obtain keyboard focus. + @return True if keyboard focus was successfully transferred to + the Component. + """ + func = self.get_dbus_method("grabFocus") + return func(*args, **kwargs) + + def registerFocusHandler(self, *args, **kwargs): + """ + Register an EventListener for notification when this object receives + keyboard focus. + """ + func = self.get_dbus_method("registerFocusHandler") + return func(*args, **kwargs) # Register the Accessible class with the accessible factory. add_accessible_class(interfaces.ATSPI_COMPONENT, Component) diff --git a/pyatspi/desktop.py b/pyatspi/desktop.py index 1cbf1e8..e09b97b 100644 --- a/pyatspi/desktop.py +++ b/pyatspi/desktop.py @@ -21,347 +21,347 @@ from role import ROLE_UNKNOWN from component import LAYER_WIDGET __all__ = [ - "Desktop", - ] + "Desktop", + ] #------------------------------------------------------------------------------ class ApplicationCache(object): - def __init__(self, connection, bus_name): - self._connection = connection - self._bus_name = bus_name - self._accessible_cache = AccessibleCache(connection, bus_name) + def __init__(self, connection, bus_name): + self._connection = connection + self._bus_name = bus_name + self._accessible_cache = AccessibleCache(connection, bus_name) - def __getitem__(self, key): - return self._accessible_cache + def __getitem__(self, key): + return self._accessible_cache - def __contains__(self, key): - if key == self._bus_name: - return True - else: - return False + def __contains__(self, key): + if key == self._bus_name: + return True + else: + return False - def get_application_at_index(self, index): - pass + def get_application_at_index(self, index): + pass - def get_application_count(self): - return 1 + def get_application_count(self): + return 1 #------------------------------------------------------------------------------ class DesktopComponent(object): - """ - The Component interface is implemented by objects which occupy - on-screen space, e.g. objects which have onscreen visual representations. - The methods in Component allow clients to identify where the - objects lie in the onscreen coordinate system, their relative - size, stacking order, and position. It also provides a mechanism - whereby keyboard focus may be transferred to specific user interface - elements programmatically. This is a 2D API, coordinates of 3D - objects are projected into the 2-dimensional screen view for - purposes of this interface. - """ - - def contains(self, *args, **kwargs): """ - @return True if the specified point lies within the Component's - bounding box, False otherwise. + The Component interface is implemented by objects which occupy + on-screen space, e.g. objects which have onscreen visual representations. + The methods in Component allow clients to identify where the + objects lie in the onscreen coordinate system, their relative + size, stacking order, and position. It also provides a mechanism + whereby keyboard focus may be transferred to specific user interface + elements programmatically. This is a 2D API, coordinates of 3D + objects are projected into the 2-dimensional screen view for + purposes of this interface. """ - return False - - def deregisterFocusHandler(self, *args, **kwargs): - """ - Request that an EventListener registered via registerFocusHandler - no longer be notified when this object receives keyboard focus. - """ - pass - - def getAccessibleAtPoint(self, *args, **kwargs): - """ - @return the Accessible child whose bounding box contains the - specified point. - """ - return None - - def getAlpha(self, *args, **kwargs): - """ - Obtain the alpha value of the component. An alpha value of 1.0 - or greater indicates that the object is fully opaque, and an - alpha value of 0.0 indicates that the object is fully transparent. - Negative alpha values have no defined meaning at this time. - """ - return 1.0 - - def getExtents(self, coord_type): - """ - Obtain the Component's bounding box, in pixels, relative to the - specified coordinate system. - @param coord_type - @return a BoundingBox which entirely contains the object's onscreen - visual representation. - """ - #TODO This needs to return the window size - return BoundingBox(*(0,0,1024,768)) - - def getLayer(self, *args, **kwargs): - """ - @return the ComponentLayer in which this object resides. - """ - return LAYER_WIDGET - - def getMDIZOrder(self): - """ - Obtain the relative stacking order (i.e. 'Z' order) of an object. - Larger values indicate that an object is on "top" of the stack, - therefore objects with smaller MDIZOrder may be obscured by objects - with a larger MDIZOrder, but not vice-versa. - @return an integer indicating the object's place in the stacking - order. - """ - return 0 - - def getPosition(self, coord_type): - """ - Obtain the position of the current component in the coordinate - system specified by coord_type. - @param : coord_type - @param : x - an out parameter which will be back-filled with the returned - x coordinate. - @param : y - an out parameter which will be back-filled with the returned - y coordinate. - """ - return (0,0) - - def getSize(self, *args, **kwargs): - """ - Obtain the size, in the coordinate system specified by coord_type, - of the rectangular area which fully contains the object's visual - representation, without accounting for viewport clipping. - @param : width - the object's horizontal extents in the specified coordinate system. - @param : height - the object's vertical extents in the specified coordinate system. - """ - #TODO Need to return window size - return (1024, 768) - - def grabFocus(self, *args, **kwargs): - """ - Request that the object obtain keyboard focus. - @return True if keyboard focus was successfully transferred to - the Component. - """ - return False - - def registerFocusHandler(self, *args, **kwargs): - """ - Register an EventListener for notification when this object receives - keyboard focus. - """ - pass + + def contains(self, *args, **kwargs): + """ + @return True if the specified point lies within the Component's + bounding box, False otherwise. + """ + return False + + def deregisterFocusHandler(self, *args, **kwargs): + """ + Request that an EventListener registered via registerFocusHandler + no longer be notified when this object receives keyboard focus. + """ + pass + + def getAccessibleAtPoint(self, *args, **kwargs): + """ + @return the Accessible child whose bounding box contains the + specified point. + """ + return None + + def getAlpha(self, *args, **kwargs): + """ + Obtain the alpha value of the component. An alpha value of 1.0 + or greater indicates that the object is fully opaque, and an + alpha value of 0.0 indicates that the object is fully transparent. + Negative alpha values have no defined meaning at this time. + """ + return 1.0 + + def getExtents(self, coord_type): + """ + Obtain the Component's bounding box, in pixels, relative to the + specified coordinate system. + @param coord_type + @return a BoundingBox which entirely contains the object's onscreen + visual representation. + """ + #TODO This needs to return the window size + return BoundingBox(*(0,0,1024,768)) + + def getLayer(self, *args, **kwargs): + """ + @return the ComponentLayer in which this object resides. + """ + return LAYER_WIDGET + + def getMDIZOrder(self): + """ + Obtain the relative stacking order (i.e. 'Z' order) of an object. + Larger values indicate that an object is on "top" of the stack, + therefore objects with smaller MDIZOrder may be obscured by objects + with a larger MDIZOrder, but not vice-versa. + @return an integer indicating the object's place in the stacking + order. + """ + return 0 + + def getPosition(self, coord_type): + """ + Obtain the position of the current component in the coordinate + system specified by coord_type. + @param : coord_type + @param : x + an out parameter which will be back-filled with the returned + x coordinate. + @param : y + an out parameter which will be back-filled with the returned + y coordinate. + """ + return (0,0) + + def getSize(self, *args, **kwargs): + """ + Obtain the size, in the coordinate system specified by coord_type, + of the rectangular area which fully contains the object's visual + representation, without accounting for viewport clipping. + @param : width + the object's horizontal extents in the specified coordinate system. + @param : height + the object's vertical extents in the specified coordinate system. + """ + #TODO Need to return window size + return (1024, 768) + + def grabFocus(self, *args, **kwargs): + """ + Request that the object obtain keyboard focus. + @return True if keyboard focus was successfully transferred to + the Component. + """ + return False + + def registerFocusHandler(self, *args, **kwargs): + """ + Register an EventListener for notification when this object receives + keyboard focus. + """ + pass #------------------------------------------------------------------------------ class Desktop(object): - """ - The base interface which is implemented by all accessible objects. - All objects support interfaces for querying their contained - 'children' and position in the accessible-object hierarchy, - whether or not they actually have children. - """ - - __metaclass__ = BaseProxyMeta - - def __init__(self, cache): - """ - Creates a desktop object. There should be one single desktop - object for the Registry object. - - @param cache - The application cache. - @kwarf application - The application D-Bus name - - If the application name is provided the Desktop is being used for - test and will only report the application provided as its single child. - """ - self._cache = cache - self._app_name = '/' - - def __nonzero__(self): - return True - - def __len__(self): - return self.getChildCount() - - def __getitem__(self, index): - return self.getChildAtIndex(index) - - def getApplication(self): - """ - Get the containing Application for this object. - @return the Application instance to which this object belongs. - """ - return None - - def getAttributes(self): - """ - Get a list of properties applied to this object as a whole, as - an AttributeSet consisting of name-value pairs. As such these - attributes may be considered weakly-typed properties or annotations, - as distinct from the strongly-typed interface instance data declared - using the IDL "attribute" keyword. - Not all objects have explicit "name-value pair" AttributeSet - properties. - Attribute names and values may have any UTF-8 string value, however - where possible, in order to facilitate consistent use and exposure - of "attribute" properties by applications and AT clients, attribute - names and values should chosen from a publicly-specified namespace - where appropriate. - Where possible, the names and values in the name-value pairs - should be chosen from well-established attribute namespaces using - standard semantics. For example, attributes of Accessible objects - corresponding to XHTML content elements should correspond to - attribute names and values specified in the w3c XHTML specification, - at http://www.w3.org/TR/xhtml2, where such values are not already - exposed via a more strongly-typed aspect of the AT-SPI API. Metadata - names and values should be chosen from the 'Dublin Core' Metadata - namespace using Dublin Core semantics: http://dublincore.org/dcregistry/ - Similarly, relevant structural metadata should be exposed using - attribute names and values chosen from the CSS2 and WICD specification: - http://www.w3.org/TR/1998/REC-CSS2-19980512 WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). - - @return : An AttributeSet encapsulating any "attribute values" - currently defined for the object. An attribute set is a list of strings - with each string comprising an name-value pair format 'name:value'. - """ - return [] - - def getChildAtIndex(self, index): - """ - Get the accessible child of this object at index. - @param : index - an in parameter indicating which child is requested (zero-indexed). - @return : the 'nth' Accessible child of this object. - """ - return self._cache.get_application_at_index(index, self) - - def getIndexInParent(self): - """ - Get the index of this object in its parent's child list. - @return : a long integer indicating this object's index in the - parent's list. - """ - return -1 - - def getLocalizedRoleName(self): - """ - Get a string indicating the type of UI role played by this object, - translated to the current locale. - @return : a UTF-8 string indicating the type of UI role played - by this object. """ - #TODO Need to localize this somehow. Hmmmmm - return 'unknown' - - def getRelationSet(self): + The base interface which is implemented by all accessible objects. + All objects support interfaces for querying their contained + 'children' and position in the accessible-object hierarchy, + whether or not they actually have children. """ - Get a set defining this object's relationship to other accessible - objects. - @return : a RelationSet defining this object's relationships. - """ - return [] - - def getRole(self): - """ - Get the Role indicating the type of UI role played by this object. - @return : a Role indicating the type of UI role played by this - object. - """ - return ROLE_UNKNOWN - - def getRoleName(self): - """ - Get a string indicating the type of UI role played by this object. - @return : a UTF-8 string indicating the type of UI role played - by this object. - """ - return 'unknown' - - def getState(self): - """ - Get the current state of the object as a StateSet. - @return : a StateSet encapsulating the currently true states - of the object. - """ - return StateSet() - - def isEqual(self, accessible): - """ - Determine whether an Accessible refers to the same object as - another. This method should be used rather than brute-force comparison - of object references (i.e. "by-value" comparison), as two object - references may have different apparent values yet refer to the - same object. - @param : obj - an Accessible object reference to compare to - @return : a boolean indicating whether the two object references - point to the same object. - """ - return self == accessible - def get_childCount(self): - return self._cache.get_application_count() - _childCountDoc = \ - """ - childCount: the number of children contained by this object. - """ - childCount = property(fget=get_childCount, doc=_childCountDoc) + __metaclass__ = BaseProxyMeta - getChildCount = get_childCount - - def get_description(self): - return '' - _descriptionDoc = \ - """ - a string describing the object in more detail than name. - """ - description = property(fget=get_description, doc=_descriptionDoc) - - def get_name(self): - return 'main' - _nameDoc = \ - """ - a (short) string representing the object's name. - """ - name = property(fget=get_name, doc=_nameDoc) - - def get_parent(self): - return None - _parentDoc = \ - """ - An Accessible object which is this object's containing object. - """ - parent = property(fget=get_parent, doc=_parentDoc) - - @property - def interfaces(self): - return [interfaces.ATSPI_ACCESSIBLE, interfaces.ATSPI_COMPONENT] - - def queryInterface(self, interface): - """ - Gets a different accessible interface for this object - or raises a NotImplemented error if the given interface - is not supported. - """ - if interface == interfaces.ATSPI_ACCESSIBLE: - return self - elif interface == interfaces.ATSPI_COMPONENT: - return DesktopComponent() - else: - raise NotImplementedError( - "%s not supported by accessible object at path %s" - % (interface, self.path)) + def __init__(self, cache): + """ + Creates a desktop object. There should be one single desktop + object for the Registry object. + + @param cache - The application cache. + @kwarf application - The application D-Bus name + + If the application name is provided the Desktop is being used for + test and will only report the application provided as its single child. + """ + self._cache = cache + self._app_name = '/' + + def __nonzero__(self): + return True + + def __len__(self): + return self.getChildCount() + + def __getitem__(self, index): + return self.getChildAtIndex(index) + + def getApplication(self): + """ + Get the containing Application for this object. + @return the Application instance to which this object belongs. + """ + return None + + def getAttributes(self): + """ + Get a list of properties applied to this object as a whole, as + an AttributeSet consisting of name-value pairs. As such these + attributes may be considered weakly-typed properties or annotations, + as distinct from the strongly-typed interface instance data declared + using the IDL "attribute" keyword. + Not all objects have explicit "name-value pair" AttributeSet + properties. + Attribute names and values may have any UTF-8 string value, however + where possible, in order to facilitate consistent use and exposure + of "attribute" properties by applications and AT clients, attribute + names and values should chosen from a publicly-specified namespace + where appropriate. + Where possible, the names and values in the name-value pairs + should be chosen from well-established attribute namespaces using + standard semantics. For example, attributes of Accessible objects + corresponding to XHTML content elements should correspond to + attribute names and values specified in the w3c XHTML specification, + at http://www.w3.org/TR/xhtml2, where such values are not already + exposed via a more strongly-typed aspect of the AT-SPI API. Metadata + names and values should be chosen from the 'Dublin Core' Metadata + namespace using Dublin Core semantics: http://dublincore.org/dcregistry/ + Similarly, relevant structural metadata should be exposed using + attribute names and values chosen from the CSS2 and WICD specification: + http://www.w3.org/TR/1998/REC-CSS2-19980512 WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). + + @return : An AttributeSet encapsulating any "attribute values" + currently defined for the object. An attribute set is a list of strings + with each string comprising an name-value pair format 'name:value'. + """ + return [] + + def getChildAtIndex(self, index): + """ + Get the accessible child of this object at index. + @param : index + an in parameter indicating which child is requested (zero-indexed). + @return : the 'nth' Accessible child of this object. + """ + return self._cache.get_application_at_index(index, self) + + def getIndexInParent(self): + """ + Get the index of this object in its parent's child list. + @return : a long integer indicating this object's index in the + parent's list. + """ + return -1 + + def getLocalizedRoleName(self): + """ + Get a string indicating the type of UI role played by this object, + translated to the current locale. + @return : a UTF-8 string indicating the type of UI role played + by this object. + """ + #TODO Need to localize this somehow. Hmmmmm + return 'unknown' + + def getRelationSet(self): + """ + Get a set defining this object's relationship to other accessible + objects. + @return : a RelationSet defining this object's relationships. + """ + return [] + + def getRole(self): + """ + Get the Role indicating the type of UI role played by this object. + @return : a Role indicating the type of UI role played by this + object. + """ + return ROLE_UNKNOWN + + def getRoleName(self): + """ + Get a string indicating the type of UI role played by this object. + @return : a UTF-8 string indicating the type of UI role played + by this object. + """ + return 'unknown' + + def getState(self): + """ + Get the current state of the object as a StateSet. + @return : a StateSet encapsulating the currently true states + of the object. + """ + return StateSet() + + def isEqual(self, accessible): + """ + Determine whether an Accessible refers to the same object as + another. This method should be used rather than brute-force comparison + of object references (i.e. "by-value" comparison), as two object + references may have different apparent values yet refer to the + same object. + @param : obj + an Accessible object reference to compare to + @return : a boolean indicating whether the two object references + point to the same object. + """ + return self == accessible + + def get_childCount(self): + return self._cache.get_application_count() + _childCountDoc = \ + """ + childCount: the number of children contained by this object. + """ + childCount = property(fget=get_childCount, doc=_childCountDoc) + + getChildCount = get_childCount + + def get_description(self): + return '' + _descriptionDoc = \ + """ + a string describing the object in more detail than name. + """ + description = property(fget=get_description, doc=_descriptionDoc) + + def get_name(self): + return 'main' + _nameDoc = \ + """ + a (short) string representing the object's name. + """ + name = property(fget=get_name, doc=_nameDoc) + + def get_parent(self): + return None + _parentDoc = \ + """ + An Accessible object which is this object's containing object. + """ + parent = property(fget=get_parent, doc=_parentDoc) + + @property + def interfaces(self): + return [interfaces.ATSPI_ACCESSIBLE, interfaces.ATSPI_COMPONENT] + + def queryInterface(self, interface): + """ + Gets a different accessible interface for this object + or raises a NotImplemented error if the given interface + is not supported. + """ + if interface == interfaces.ATSPI_ACCESSIBLE: + return self + elif interface == interfaces.ATSPI_COMPONENT: + return DesktopComponent() + else: + raise NotImplementedError( + "%s not supported by accessible object at path %s" + % (interface, self.path)) #END---------------------------------------------------------------------------- diff --git a/pyatspi/document.py b/pyatspi/document.py index 88a9df5..8b0ccc2 100644 --- a/pyatspi/document.py +++ b/pyatspi/document.py @@ -17,57 +17,57 @@ from base import BaseProxy from factory import add_accessible_class __all__ = [ - "Document", - ] + "Document", + ] #------------------------------------------------------------------------------ class Document(BaseProxy): - """ - Primarily a 'tagging' interface which indicates the start of - document content in the Accessibility hierarchy. Accessible objects - below the node implementing Document are normally assumed to - be part of the document content. Attributes of Document are those - attributes associated with the document as a whole. Objects that - implement Document are normally expected to implement Collection - as well. - """ - - def getAttributeValue(self, *args, **kwargs): """ - Gets the value of a single attribute, if specified for the document - as a whole. - @param : attributename - a string indicating the name of a specific attribute (name-value - pair) being queried. - @return a string corresponding to the value of the specified - attribute, or an empty string if the attribute is unspecified - for the object. + Primarily a 'tagging' interface which indicates the start of + document content in the Accessibility hierarchy. Accessible objects + below the node implementing Document are normally assumed to + be part of the document content. Attributes of Document are those + attributes associated with the document as a whole. Objects that + implement Document are normally expected to implement Collection + as well. """ - func = self.get_dbus_method("getAttributeValue") - return func(*args, **kwargs) - - def getAttributes(self, *args, **kwargs): - """ - Gets all attributes specified for a document as a whole. For - attributes which change within the document content, see Accessibility::Text::getAttributes - instead. - @return an AttributeSet containing the attributes of the document, - as name-value pairs. - """ - func = self.get_dbus_method("getAttributes") - return func(*args, **kwargs) - - def getLocale(self, *args, **kwargs): - """ - Gets the locale associated with the document's content. e.g. - the locale for LOCALE_TYPE_MESSAGES. - @return a string compliant with the POSIX standard for locale - description. - """ - func = self.get_dbus_method("getLocale") - return func(*args, **kwargs) - + + def getAttributeValue(self, *args, **kwargs): + """ + Gets the value of a single attribute, if specified for the document + as a whole. + @param : attributename + a string indicating the name of a specific attribute (name-value + pair) being queried. + @return a string corresponding to the value of the specified + attribute, or an empty string if the attribute is unspecified + for the object. + """ + func = self.get_dbus_method("getAttributeValue") + return func(*args, **kwargs) + + def getAttributes(self, *args, **kwargs): + """ + Gets all attributes specified for a document as a whole. For + attributes which change within the document content, see Accessibility::Text::getAttributes + instead. + @return an AttributeSet containing the attributes of the document, + as name-value pairs. + """ + func = self.get_dbus_method("getAttributes") + return func(*args, **kwargs) + + def getLocale(self, *args, **kwargs): + """ + Gets the locale associated with the document's content. e.g. + the locale for LOCALE_TYPE_MESSAGES. + @return a string compliant with the POSIX standard for locale + description. + """ + func = self.get_dbus_method("getLocale") + return func(*args, **kwargs) + # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_DOCUMENT, Document) diff --git a/pyatspi/editabletext.py b/pyatspi/editabletext.py index eb70ed1..3ce10ee 100644 --- a/pyatspi/editabletext.py +++ b/pyatspi/editabletext.py @@ -18,116 +18,116 @@ from factory import add_accessible_class from text import * __all__ = [ - "EditableText", - ] + "EditableText", + ] #------------------------------------------------------------------------------ class EditableText(Text): - """ - Derived from interface Text, EditableText provides methods for - modifying textual content of components which support editing. - EditableText also interacts with the system clipboard via copyText, - cutText, and pasteText. - """ - - def copyText(self, *args, **kwargs): """ - Copy a range of text into the system clipboard. - @param : startPos - the character offset of the first character in the range of text - being copied. - @param : endPos - the offset of the first character past the end of the range of - text being copied. + Derived from interface Text, EditableText provides methods for + modifying textual content of components which support editing. + EditableText also interacts with the system clipboard via copyText, + cutText, and pasteText. """ - func = self.get_dbus_method("copyText") - return func(*args, **kwargs) - - def cutText(self, *args, **kwargs): - """ - Excise a range of text from a Text object, copying it into the - system clipboard. - @param : startPos - the character offset of the first character in the range of text - being cut. - @param : endPos - the offset of the first character past the end of the range of - text being cut. - @return True if the text was successfully cut, False otherwise. - """ - func = self.get_dbus_method("cutText") - return func(*args, **kwargs) - - def deleteText(self, *args, **kwargs): - """ - Excise a range of text from a Text object without copying it - into the system clipboard. - @param : startPos - the character offset of the first character in the range of text - being deleted. - @param : endPos - the offset of the first character past the end of the range of - text being deleted. - @return True if the text was successfully deleted, False otherwise. - """ - func = self.get_dbus_method("deleteText") - return func(*args, **kwargs) - - def insertText(self, *args, **kwargs): - """ - Insert new text contents into an existing text object at a given - location, while retaining the old contents. - @param : position - the character offset into the Text implementor's content at which - the new content will be inserted. - @param : text - a UTF-8 string of which length characters will be inserted into - the text object's text buffer. - @param : length - the number of characters of text to insert. If the character - count of text is less than or equal to length, the entire contents - of text will be inserted. - @return True if the text content was successfully inserted, False - otherwise. - """ - func = self.get_dbus_method("insertText") - return func(*args, **kwargs) - - def pasteText(self, *args, **kwargs): - """ - Copy the text contents of the system clipboard, if any, into - a Text object, inserting it at a particular character offset. - @param : position - the character offset before which the text will be inserted. - @return True if the text was successfully pasted into the Text - object, False otherwise. - """ - func = self.get_dbus_method("pasteText") - return func(*args, **kwargs) - - def setAttributes(self, *args, **kwargs): - """ - Apply a particular set of attributes to a range of text. - @return True if the text attributes were successfully modified, - False otherwise. - """ - func = self.get_dbus_method("setAttributes") - return func(*args, **kwargs) - - def setTextContents(self, *args, **kwargs): - """ - Replace the text contents with a new string, discarding the old - contents. - @param : newContents - a UTF-8 string with which the text object's contents will be - replaced. - @return True if the text content was successfully changed, False - otherwise. - """ - func = self.get_dbus_method("setTextContents") - return func(*args, **kwargs) - + + def copyText(self, *args, **kwargs): + """ + Copy a range of text into the system clipboard. + @param : startPos + the character offset of the first character in the range of text + being copied. + @param : endPos + the offset of the first character past the end of the range of + text being copied. + """ + func = self.get_dbus_method("copyText") + return func(*args, **kwargs) + + def cutText(self, *args, **kwargs): + """ + Excise a range of text from a Text object, copying it into the + system clipboard. + @param : startPos + the character offset of the first character in the range of text + being cut. + @param : endPos + the offset of the first character past the end of the range of + text being cut. + @return True if the text was successfully cut, False otherwise. + """ + func = self.get_dbus_method("cutText") + return func(*args, **kwargs) + + def deleteText(self, *args, **kwargs): + """ + Excise a range of text from a Text object without copying it + into the system clipboard. + @param : startPos + the character offset of the first character in the range of text + being deleted. + @param : endPos + the offset of the first character past the end of the range of + text being deleted. + @return True if the text was successfully deleted, False otherwise. + """ + func = self.get_dbus_method("deleteText") + return func(*args, **kwargs) + + def insertText(self, *args, **kwargs): + """ + Insert new text contents into an existing text object at a given + location, while retaining the old contents. + @param : position + the character offset into the Text implementor's content at which + the new content will be inserted. + @param : text + a UTF-8 string of which length characters will be inserted into + the text object's text buffer. + @param : length + the number of characters of text to insert. If the character + count of text is less than or equal to length, the entire contents + of text will be inserted. + @return True if the text content was successfully inserted, False + otherwise. + """ + func = self.get_dbus_method("insertText") + return func(*args, **kwargs) + + def pasteText(self, *args, **kwargs): + """ + Copy the text contents of the system clipboard, if any, into + a Text object, inserting it at a particular character offset. + @param : position + the character offset before which the text will be inserted. + @return True if the text was successfully pasted into the Text + object, False otherwise. + """ + func = self.get_dbus_method("pasteText") + return func(*args, **kwargs) + + def setAttributes(self, *args, **kwargs): + """ + Apply a particular set of attributes to a range of text. + @return True if the text attributes were successfully modified, + False otherwise. + """ + func = self.get_dbus_method("setAttributes") + return func(*args, **kwargs) + + def setTextContents(self, *args, **kwargs): + """ + Replace the text contents with a new string, discarding the old + contents. + @param : newContents + a UTF-8 string with which the text object's contents will be + replaced. + @return True if the text content was successfully changed, False + otherwise. + """ + func = self.get_dbus_method("setTextContents") + return func(*args, **kwargs) + # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_EDITABLE_TEXT, EditableText) diff --git a/pyatspi/event.py b/pyatspi/event.py index 4ae61ee..d5a31e7 100644 --- a/pyatspi/event.py +++ b/pyatspi/event.py @@ -17,235 +17,235 @@ from factory import create_accessible, add_accessible_class from accessible import BoundingBox __all__ = [ - "Event", - "EventType", - "event_type_to_signal_reciever", - ] + "Event", + "EventType", + "event_type_to_signal_reciever", + ] #------------------------------------------------------------------------------ _interface_to_klass = { - "org.freedesktop.atspi.Event.Object":"object", - "org.freedesktop.atspi.Event.Window":"window", - "org.freedesktop.atspi.Event.Mouse":"mouse", - "org.freedesktop.atspi.Event.Terminal":"terminal", - "org.freedesktop.atspi.Event.Document":"document", - "org.freedesktop.atspi.Event.Focus":"focus", - } + "org.freedesktop.atspi.Event.Object":"object", + "org.freedesktop.atspi.Event.Window":"window", + "org.freedesktop.atspi.Event.Mouse":"mouse", + "org.freedesktop.atspi.Event.Terminal":"terminal", + "org.freedesktop.atspi.Event.Document":"document", + "org.freedesktop.atspi.Event.Focus":"focus", + } _klass_to_interface = { - "object":"org.freedesktop.atspi.Event.Object", - "window":"org.freedesktop.atspi.Event.Window", - "mouse":"org.freedesktop.atspi.Event.Mouse", - "terminal":"org.freedesktop.atspi.Event.Terminal", - "document":"org.freedesktop.atspi.Event.Document", - "focus":"org.freedesktop.atspi.Event.Focus", - } + "object":"org.freedesktop.atspi.Event.Object", + "window":"org.freedesktop.atspi.Event.Window", + "mouse":"org.freedesktop.atspi.Event.Mouse", + "terminal":"org.freedesktop.atspi.Event.Terminal", + "document":"org.freedesktop.atspi.Event.Document", + "focus":"org.freedesktop.atspi.Event.Focus", + } #------------------------------------------------------------------------------ class _ELessList(list): - def __getitem__(self, index): - try: - return list.__getitem__(self, index) - except IndexError: - return None + def __getitem__(self, index): + try: + return list.__getitem__(self, index) + except IndexError: + return None class EventType(str): - """ - Wraps the AT-SPI event type string so its components can be accessed - individually as klass (can't use the keyword class), major, minor, and detail - (klass_major_minor_detail). - - @note: All attributes of an instance of this class should be considered - public readable as it is acting a a struct. - @ivar klass: Most general event type identifier (object, window, mouse, etc.) - @type klass: string - @ivar major: Second level event type description - @type major: string - @ivar minor: Third level event type description - @type minor: string - @ivar detail: Lowest level event type description - @type detail: string - @ivar name: Full, unparsed event name as received from AT-SPI - @type name: string - @cvar format: Names of the event string components - @type format: 4-tuple of string - """ - - _SEPARATOR = ':' - - def __init__(self, name): - """ - Parses the full AT-SPI event name into its components - (klass:major:minor:detail). If the provided event name is an integer - instead of a string, then the event is really a device event. - - @param name: Full AT-SPI event name - @type name: string - @raise AttributeError: When the given event name is not a valid string - """ - stripped = name.strip(self._SEPARATOR) - separated = stripped.split(self._SEPARATOR, 3) - self._separated = _ELessList(separated) - - self.klass = self._separated[0] - self.major = self._separated[1] - self.minor = self._separated[2] - self.detail = self._separated[3] - - self._name = ":".join(separated) - - def is_subtype(self, event_type): - """ - Determines if the passed event type is a subtype - of this event. - """ - if event_type.klass and event_type.klass != self.klass: - return False - else: - if event_type.major and event_type.major != self.major: - return False - else: - if event_type.minor and event_type.minor != self.minor: - return False - return True - - @property - def name(self): - return self._name - - @property - def value(self): - return self._name + """ + Wraps the AT-SPI event type string so its components can be accessed + individually as klass (can't use the keyword class), major, minor, and detail + (klass_major_minor_detail). + + @note: All attributes of an instance of this class should be considered + public readable as it is acting a a struct. + @ivar klass: Most general event type identifier (object, window, mouse, etc.) + @type klass: string + @ivar major: Second level event type description + @type major: string + @ivar minor: Third level event type description + @type minor: string + @ivar detail: Lowest level event type description + @type detail: string + @ivar name: Full, unparsed event name as received from AT-SPI + @type name: string + @cvar format: Names of the event string components + @type format: 4-tuple of string + """ + + _SEPARATOR = ':' + + def __init__(self, name): + """ + Parses the full AT-SPI event name into its components + (klass:major:minor:detail). If the provided event name is an integer + instead of a string, then the event is really a device event. + + @param name: Full AT-SPI event name + @type name: string + @raise AttributeError: When the given event name is not a valid string + """ + stripped = name.strip(self._SEPARATOR) + separated = stripped.split(self._SEPARATOR, 3) + self._separated = _ELessList(separated) + + self.klass = self._separated[0] + self.major = self._separated[1] + self.minor = self._separated[2] + self.detail = self._separated[3] + + self._name = ":".join(separated) + + def is_subtype(self, event_type): + """ + Determines if the passed event type is a subtype + of this event. + """ + if event_type.klass and event_type.klass != self.klass: + return False + else: + if event_type.major and event_type.major != self.major: + return False + else: + if event_type.minor and event_type.minor != self.minor: + return False + return True + + @property + def name(self): + return self._name + + @property + def value(self): + return self._name #------------------------------------------------------------------------------ def event_type_to_signal_reciever(bus, cache, event_handler, event_type): - kwargs = { - 'sender_keyword':'sender', - 'interface_keyword':'interface', - 'member_keyword':'member', - 'path_keyword':'path', - } - if event_type.major: - major = event_type.major.replace('-', '_') - if event_type.klass: - kwargs['dbus_interface'] = _klass_to_interface[event_type.klass] - if event_type.major: - kwargs['signal_name'] = major - if event_type.minor: - kwargs['arg0'] = event_type.minor - - def handler_wrapper(minor, detail1, detail2, any_data, - sender=None, interface=None, member=None, path=None): - event = Event(cache, path, sender, interface, member, (minor, detail1, detail2, any_data)) - return event_handler(event) - - return bus.add_signal_receiver(handler_wrapper, **kwargs) + kwargs = { + 'sender_keyword':'sender', + 'interface_keyword':'interface', + 'member_keyword':'member', + 'path_keyword':'path', + } + if event_type.major: + major = event_type.major.replace('-', '_') + if event_type.klass: + kwargs['dbus_interface'] = _klass_to_interface[event_type.klass] + if event_type.major: + kwargs['signal_name'] = major + if event_type.minor: + kwargs['arg0'] = event_type.minor + + def handler_wrapper(minor, detail1, detail2, any_data, + sender=None, interface=None, member=None, path=None): + event = Event(cache, path, sender, interface, member, (minor, detail1, detail2, any_data)) + return event_handler(event) + + return bus.add_signal_receiver(handler_wrapper, **kwargs) #------------------------------------------------------------------------------ class Event(object): - """ - Wraps an AT-SPI event with a more Pythonic interface managing exceptions, - the differences in any_data across versions, and the reference counting of - accessibles provided with the event. - - @note: All unmarked attributes of this class should be considered public - readable and writable as the class is acting as a record object. - - @ivar type: The type of the AT-SPI event - @type type: L{EventType} - @ivar detail1: First AT-SPI event parameter - @type detail1: integer - @ivar detail2: Second AT-SPI event parameter - @type detail2: integer - @ivar any_data: Extra AT-SPI data payload - @type any_data: object - @ivar host_application: Application owning the event source - @type host_application: Accessibility.Application - @ivar source_name: Name of the event source at the time of event dispatch - @type source_name: string - @ivar source_role: Role of the event source at the time of event dispatch - @type source_role: Accessibility.Role - @ivar source: Source of the event - @type source: Accessibility.Accessible - """ - def __init__(self, cache, source_path, source_application, interface, name, event): - """ - Extracts information from the provided event. If the event is a "normal" - event, pulls the detail1, detail2, any_data, and source values out of the - given object and stores it in this object. If the event is a device event, - key ID is stored in detail1, scan code is stored in detail2, key name, - key modifiers (e.g. ALT, CTRL, etc.), is text flag, and timestamp are - stored as a 4-tuple in any_data, and source is None (since key events are - global). - - @param event: Event from an AT-SPI callback - @type event: Accessibility.Event or Accessibility.DeviceEvent - """ - self._cache = cache - self._source_path = source_path - self._source_application = source_application - - self._source = None - self._application = None - - self._klass = _interface_to_klass[interface] - # The replace is neccessary as '-' not legal as signal name - # so translated on the server side. - self._major = name.replace('_', '-') - self._minor = event[0] - self.type = EventType(':'.join([self._klass, self._major, self._minor])) - self.detail1 = event[1] - self.detail2 = event[2] - - data = event[3] - if name == "object_bounds_changed": - self.any_data = BoundingBox(*data) - else: - self.any_data = data - - @property - def host_application(self): - if not self._application: - application_root = self._cache[self._source_application]._get_root() - return create_accessible(self._cache, - self._source_application, - application_root, - interfaces.ATSPI_APPLICATION, - connection=self._cache._connection) - return self._application - - @property - def source(self): - if not self._source: - self._source = create_accessible(self._cache, - self._source_application, - self._source_path, - interfaces.ATSPI_ACCESSIBLE, - connection=self._cache._connection) - return self._source - - @property - def source_name(self): - return source.name - - @property - def source_role(self): - return source.getRole() - - def __str__(self): - """ - Builds a human readable representation of the event including event type, - parameters, and source info. - - @return: Event description - @rtype: string - """ - return '%s(%s, %s, %s)\n\tsource: %s\n\thost_application: %s' % \ - (self.type, self.detail1, self.detail2, self.any_data, - self.source, self.host_application) + """ + Wraps an AT-SPI event with a more Pythonic interface managing exceptions, + the differences in any_data across versions, and the reference counting of + accessibles provided with the event. + + @note: All unmarked attributes of this class should be considered public + readable and writable as the class is acting as a record object. + + @ivar type: The type of the AT-SPI event + @type type: L{EventType} + @ivar detail1: First AT-SPI event parameter + @type detail1: integer + @ivar detail2: Second AT-SPI event parameter + @type detail2: integer + @ivar any_data: Extra AT-SPI data payload + @type any_data: object + @ivar host_application: Application owning the event source + @type host_application: Accessibility.Application + @ivar source_name: Name of the event source at the time of event dispatch + @type source_name: string + @ivar source_role: Role of the event source at the time of event dispatch + @type source_role: Accessibility.Role + @ivar source: Source of the event + @type source: Accessibility.Accessible + """ + def __init__(self, cache, source_path, source_application, interface, name, event): + """ + Extracts information from the provided event. If the event is a "normal" + event, pulls the detail1, detail2, any_data, and source values out of the + given object and stores it in this object. If the event is a device event, + key ID is stored in detail1, scan code is stored in detail2, key name, + key modifiers (e.g. ALT, CTRL, etc.), is text flag, and timestamp are + stored as a 4-tuple in any_data, and source is None (since key events are + global). + + @param event: Event from an AT-SPI callback + @type event: Accessibility.Event or Accessibility.DeviceEvent + """ + self._cache = cache + self._source_path = source_path + self._source_application = source_application + + self._source = None + self._application = None + + self._klass = _interface_to_klass[interface] + # The replace is neccessary as '-' not legal as signal name + # so translated on the server side. + self._major = name.replace('_', '-') + self._minor = event[0] + self.type = EventType(':'.join([self._klass, self._major, self._minor])) + self.detail1 = event[1] + self.detail2 = event[2] + + data = event[3] + if name == "object_bounds_changed": + self.any_data = BoundingBox(*data) + else: + self.any_data = data + + @property + def host_application(self): + if not self._application: + application_root = self._cache[self._source_application]._get_root() + return create_accessible(self._cache, + self._source_application, + application_root, + interfaces.ATSPI_APPLICATION, + connection=self._cache._connection) + return self._application + + @property + def source(self): + if not self._source: + self._source = create_accessible(self._cache, + self._source_application, + self._source_path, + interfaces.ATSPI_ACCESSIBLE, + connection=self._cache._connection) + return self._source + + @property + def source_name(self): + return source.name + + @property + def source_role(self): + return source.getRole() + + def __str__(self): + """ + Builds a human readable representation of the event including event type, + parameters, and source info. + + @return: Event description + @rtype: string + """ + return '%s(%s, %s, %s)\n\tsource: %s\n\thost_application: %s' % \ + (self.type, self.detail1, self.detail2, self.any_data, + self.source, self.host_application) #END---------------------------------------------------------------------------- diff --git a/pyatspi/factory.py b/pyatspi/factory.py index 71ea7ab..ffbf5f5 100644 --- a/pyatspi/factory.py +++ b/pyatspi/factory.py @@ -15,46 +15,46 @@ #------------------------------------------------------------------------------ class AccessibleFactory(object): - __accessible_interfaces = {} + __accessible_interfaces = {} - def create_accessible(self, cache, app_name, acc_path, interface, dbus_object=None, connection=None, parent=None): - class_ = self.__accessible_interfaces[interface] - return class_(cache, - app_name, - acc_path, - interface, - dbus_object=dbus_object, - connection=connection, - parent=parent) + def create_accessible(self, cache, app_name, acc_path, interface, dbus_object=None, connection=None, parent=None): + class_ = self.__accessible_interfaces[interface] + return class_(cache, + app_name, + acc_path, + interface, + dbus_object=dbus_object, + connection=connection, + parent=parent) - def add_accessible_class(self, name, cls): - self.__accessible_interfaces[name] = cls + def add_accessible_class(self, name, cls): + self.__accessible_interfaces[name] = cls _factory = AccessibleFactory() def create_accessible(cache, app_name, acc_path, interface, dbus_object=None, connection=None, parent=None): - """ - Used to create different python classes for each of the accessible interfaces. - - The decision on which class to create is based on the name of the - accessible interface. - - cache - ApplicationCache, where the cached data for the accessible can be obtained. - app_name - D-Bus bus name of the application this accessible belongs to. - acc_path - D-Bus object path of the server side accessible object. - interface - D-Bus interface of the object. Used to decide which accessible class to instanciate. - dbus_object(kwarg) - The D-Bus proxy object used by the accessible for D-Bus method calls. - connection(kwarg) - Client side D-Bus connection, provided if no D-Bus proxy is available. - """ - return _factory.create_accessible(cache, - app_name, - acc_path, - interface, - dbus_object=dbus_object, - connection=connection, - parent=parent) + """ + Used to create different python classes for each of the accessible interfaces. + + The decision on which class to create is based on the name of the + accessible interface. + + cache - ApplicationCache, where the cached data for the accessible can be obtained. + app_name - D-Bus bus name of the application this accessible belongs to. + acc_path - D-Bus object path of the server side accessible object. + interface - D-Bus interface of the object. Used to decide which accessible class to instanciate. + dbus_object(kwarg) - The D-Bus proxy object used by the accessible for D-Bus method calls. + connection(kwarg) - Client side D-Bus connection, provided if no D-Bus proxy is available. + """ + return _factory.create_accessible(cache, + app_name, + acc_path, + interface, + dbus_object=dbus_object, + connection=connection, + parent=parent) def add_accessible_class(name, cls): - _factory.add_accessible_class(name, cls) + _factory.add_accessible_class(name, cls) #END---------------------------------------------------------------------------- diff --git a/pyatspi/hyperlink.py b/pyatspi/hyperlink.py index 01afd4e..10b8b36 100644 --- a/pyatspi/hyperlink.py +++ b/pyatspi/hyperlink.py @@ -17,94 +17,94 @@ from base import BaseProxy from factory import add_accessible_class __all__ = [ - "Hyperlink", - ] + "Hyperlink", + ] #------------------------------------------------------------------------------ class Hyperlink(BaseProxy): - """ - Instances of Hyperlink are returned by Hypertext objects, and - are the means by which end users and clients interact with linked, - and in some cases embedded, content. Hyperlinks may have multiple - "anchors", where an anchor corresponds to a reference to a particular - resource with a corresponding resource identified (URI). Hyperlinks - may be queried for their URIs, or queried for the objects corresponding - to their anchors. The objects thus obtained are instances of - Accessible, and may be queried, and manipulated via the Action - interface. - """ - - def getObject(self, *args, **kwargs): """ - Gets the i'th object, (where i is an integer between 0 and Hyperlink::numAnchors - - 1, inclusive) associated with a Hyperlink. The objects returned - are usually actionable (i.e. they should implement Accessibility::Action), - and the available actions often include "open", "bookmark", "save - link as", etc. They may also implement Accessibility::StreamableContent, - although clients can normally use getURI to obtain a resource - locator via which the object's data may be accessed. - @return an Accessible object instance representing the Hyperlink's - ith anchor, or through which the content associated with the - ith anchor can be accessed. + Instances of Hyperlink are returned by Hypertext objects, and + are the means by which end users and clients interact with linked, + and in some cases embedded, content. Hyperlinks may have multiple + "anchors", where an anchor corresponds to a reference to a particular + resource with a corresponding resource identified (URI). Hyperlinks + may be queried for their URIs, or queried for the objects corresponding + to their anchors. The objects thus obtained are instances of + Accessible, and may be queried, and manipulated via the Action + interface. """ - func = self.get_dbus_method("getObject") - return func(*args, **kwargs) - - def getURI(self, *args, **kwargs): - """ - Obtain a resource locator ('URI') which can be used to access - the content to which this link "points" or is connected. - @return a string corresponding to the URI of the Hyperlink's - 'ith' anchor, if one exists, or a NIL string otherwise. - """ - func = self.get_dbus_method("getURI") - return func(*args, **kwargs) - - def isValid(self, *args, **kwargs): - """ - Check the hyperlink to see if a connection to its backing content - can be established, or if its URI is valid. - @return True if the object's content is available, or False if - the hyperlink's URI is invalid, or a connection to the resource - can not be established. - """ - func = self.get_dbus_method("isValid") - return func(*args, **kwargs) - - def get_endIndex(self): - return self._pgetter(self._dbus_interface, "endIndex") - def set_endIndex(self, value): - self._psetter(self._dbus_interface, "endIndex", value) - _endIndexDoc = \ - """ - the ending offset within the containing Hypertext content with - which this Hyperlink is associated; that is, the offset of the - first element past the range within the Hypertext associated - with this Hyperlink. - """ - endIndex = property(fget=get_endIndex, fset=set_endIndex, doc=_endIndexDoc) - - def get_nAnchors(self): - return self._pgetter(self._dbus_interface, "nAnchors") - def set_nAnchors(self, value): - self._psetter(self._dbus_interface, "nAnchors", value) - _nAnchorsDoc = \ - """ - the number of separate anchors associated with this Hyperlink - """ - nAnchors = property(fget=get_nAnchors, fset=set_nAnchors, doc=_nAnchorsDoc) - - def get_startIndex(self): - return self._pgetter(self._dbus_interface, "startIndex") - def set_startIndex(self, value): - self._psetter(self._dbus_interface, "startIndex", value) - _startIndexDoc = \ - """ - the starting offset within the containing Hypertext content with - which this Hyperlink is associated - """ - startIndex = property(fget=get_startIndex, fset=set_startIndex, doc=_startIndexDoc) + + def getObject(self, *args, **kwargs): + """ + Gets the i'th object, (where i is an integer between 0 and Hyperlink::numAnchors + - 1, inclusive) associated with a Hyperlink. The objects returned + are usually actionable (i.e. they should implement Accessibility::Action), + and the available actions often include "open", "bookmark", "save + link as", etc. They may also implement Accessibility::StreamableContent, + although clients can normally use getURI to obtain a resource + locator via which the object's data may be accessed. + @return an Accessible object instance representing the Hyperlink's + ith anchor, or through which the content associated with the + ith anchor can be accessed. + """ + func = self.get_dbus_method("getObject") + return func(*args, **kwargs) + + def getURI(self, *args, **kwargs): + """ + Obtain a resource locator ('URI') which can be used to access + the content to which this link "points" or is connected. + @return a string corresponding to the URI of the Hyperlink's + 'ith' anchor, if one exists, or a NIL string otherwise. + """ + func = self.get_dbus_method("getURI") + return func(*args, **kwargs) + + def isValid(self, *args, **kwargs): + """ + Check the hyperlink to see if a connection to its backing content + can be established, or if its URI is valid. + @return True if the object's content is available, or False if + the hyperlink's URI is invalid, or a connection to the resource + can not be established. + """ + func = self.get_dbus_method("isValid") + return func(*args, **kwargs) + + def get_endIndex(self): + return self._pgetter(self._dbus_interface, "endIndex") + def set_endIndex(self, value): + self._psetter(self._dbus_interface, "endIndex", value) + _endIndexDoc = \ + """ + the ending offset within the containing Hypertext content with + which this Hyperlink is associated; that is, the offset of the + first element past the range within the Hypertext associated + with this Hyperlink. + """ + endIndex = property(fget=get_endIndex, fset=set_endIndex, doc=_endIndexDoc) + + def get_nAnchors(self): + return self._pgetter(self._dbus_interface, "nAnchors") + def set_nAnchors(self, value): + self._psetter(self._dbus_interface, "nAnchors", value) + _nAnchorsDoc = \ + """ + the number of separate anchors associated with this Hyperlink + """ + nAnchors = property(fget=get_nAnchors, fset=set_nAnchors, doc=_nAnchorsDoc) + + def get_startIndex(self): + return self._pgetter(self._dbus_interface, "startIndex") + def set_startIndex(self, value): + self._psetter(self._dbus_interface, "startIndex", value) + _startIndexDoc = \ + """ + the starting offset within the containing Hypertext content with + which this Hyperlink is associated + """ + startIndex = property(fget=get_startIndex, fset=set_startIndex, doc=_startIndexDoc) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_HYPERLINK, Hyperlink) diff --git a/pyatspi/hypertext.py b/pyatspi/hypertext.py index e595d6a..440f227 100644 --- a/pyatspi/hypertext.py +++ b/pyatspi/hypertext.py @@ -17,52 +17,52 @@ from base import BaseProxy from factory import add_accessible_class __all__ = [ - "Hypertext", - ] + "Hypertext", + ] #------------------------------------------------------------------------------ class Hypertext(BaseProxy): - """ - An interface used for objects which implement linking between - multiple resource or content locations, or multiple 'markers' - within a single document. A Hypertext instance is associated - with one or more Hyperlinks, which are associated with particular - offsets within the Hypertext's included content. - """ - - def getLink(self, *args, **kwargs): """ - Get one of the Hyperlinks associated with this Hypertext object, - by index. - @param : linkIndex - an integer from 0 to getNLinks() - 1. - @return the Hyperlink in this Hypertext object. + An interface used for objects which implement linking between + multiple resource or content locations, or multiple 'markers' + within a single document. A Hypertext instance is associated + with one or more Hyperlinks, which are associated with particular + offsets within the Hypertext's included content. """ - func = self.get_dbus_method("getLink") - return func(*args, **kwargs) - - def getLinkIndex(self, *args, **kwargs): - """ - Get the hyperlink index, if any, associated with a particular - character offset in the Hypertext object. For Hypertext implementors - without textual content, all hyperlinks are associated with character - offset '0'. - @return the index of the Hyperlink associated with character - offset characterIndex, or -1 if no Hyperlink is associated with - that character offset. - """ - func = self.get_dbus_method("getLinkIndex") - return func(*args, **kwargs) - - def getNLinks(self, *args, **kwargs): - """ - Query the hypertext object for the number of Hyperlinks it contains. - @return the number of Hyperlinks associated with this Hypertext - object, as a long integer. - """ - func = self.get_dbus_method("getNLinks") - return func(*args, **kwargs) + + def getLink(self, *args, **kwargs): + """ + Get one of the Hyperlinks associated with this Hypertext object, + by index. + @param : linkIndex + an integer from 0 to getNLinks() - 1. + @return the Hyperlink in this Hypertext object. + """ + func = self.get_dbus_method("getLink") + return func(*args, **kwargs) + + def getLinkIndex(self, *args, **kwargs): + """ + Get the hyperlink index, if any, associated with a particular + character offset in the Hypertext object. For Hypertext implementors + without textual content, all hyperlinks are associated with character + offset '0'. + @return the index of the Hyperlink associated with character + offset characterIndex, or -1 if no Hyperlink is associated with + that character offset. + """ + func = self.get_dbus_method("getLinkIndex") + return func(*args, **kwargs) + + def getNLinks(self, *args, **kwargs): + """ + Query the hypertext object for the number of Hyperlinks it contains. + @return the number of Hyperlinks associated with this Hypertext + object, as a long integer. + """ + func = self.get_dbus_method("getNLinks") + return func(*args, **kwargs) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_HYPERTEXT, Hypertext) diff --git a/pyatspi/image.py b/pyatspi/image.py index bf9beb5..d113d4c 100644 --- a/pyatspi/image.py +++ b/pyatspi/image.py @@ -19,92 +19,92 @@ from factory import add_accessible_class from accessible import BoundingBox __all__ = [ - "Image", - ] + "Image", + ] #------------------------------------------------------------------------------ class Image(BaseProxy): - """ - An interface implemented by objects which render image data or - pictorial information to the screen. When onscreen components - include graphical information that is not purely intended to - enhance "3d effect" or visual layout, but which conveys some - semantic or informational content to the sighted user, they should - implement Image, and that semantic content should be conveyed - textually to the extent possible via the image description, as - well as the Accessible::name and Accessible::description properties. - """ - - def getImageExtents(self, coordType): """ - Obtain a bounding box which entirely contains the image contents, - as displayed on screen. The bounds returned do not account for - any viewport clipping or the fact that the image may be partially - or wholly obscured by other onscreen content. - @param : coordType - If 0, the returned bounding box position is returned relative - to the screen; if 1, the bounding box position is returned relative - to the containing window. - @return a BoundingBox enclosing the image's onscreen representation. + An interface implemented by objects which render image data or + pictorial information to the screen. When onscreen components + include graphical information that is not purely intended to + enhance "3d effect" or visual layout, but which conveys some + semantic or informational content to the sighted user, they should + implement Image, and that semantic content should be conveyed + textually to the extent possible via the image description, as + well as the Accessible::name and Accessible::description properties. """ - func = self.get_dbus_method("getImageExtents") - return BoundingBox(*func(dbus.Int16(coordType))) - - def getImagePosition(self, *args, **kwargs): - """ - Get the coordinates of the current image position on screen. - @param : x - Back-filled with the x coordinate of the onscreen image (i.e. - the minimum x coordinate) - @param : y - Back-filled with the y coordinate of the onscreen image (i.e. - the minimum y coordinate) - @param : coordType - If 0, the returned x and y coordinates are returned relative - to the screen; if 1, they are returned relative to the containing - window. - """ - func = self.get_dbus_method("getImagePosition") - return func(*args, **kwargs) - - def getImageSize(self, *args, **kwargs): - """ - Obtain the width and height of the current onscreen view of the - image. The extents returned do not account for any viewport clipping - or the fact that the image may be partially or wholly obscured - by other onscreen content. - @param : width - Back-filled with the x extents of the onscreen image (i.e. the - image width in pixels) - @param : height - Back-filled with the y extents of the onscreen image (i.e. the - image height in pixels) - """ - func = self.get_dbus_method("getImageSize") - return func(*args, **kwargs) - def get_imageDescription(self): - return self._pgetter(self._dbus_interface, "imageDescription") - def set_imageDescription(self, value): - self._psetter(self._dbus_interface, "imageDescription", value) - _imageDescriptionDoc = \ - """ - A UTF-8 string providing a textual description of what is visually - depicted in the image. - """ - imageDescription = property(fget=get_imageDescription, fset=set_imageDescription, doc=_imageDescriptionDoc) - - def get_imageLocale(self): - return self._pgetter(self._dbus_interface, "imageLocale") - def set_imageLocale(self, value): - self._psetter(self._dbus_interface, "imageLocale", value) - _imageLocaleDoc = \ - """ - A string corresponding to the POSIX LC_MESSAGES locale used by - the imageDescription. - """ - imageLocale = property(fget=get_imageLocale, fset=set_imageLocale, doc=_imageLocaleDoc) + def getImageExtents(self, coordType): + """ + Obtain a bounding box which entirely contains the image contents, + as displayed on screen. The bounds returned do not account for + any viewport clipping or the fact that the image may be partially + or wholly obscured by other onscreen content. + @param : coordType + If 0, the returned bounding box position is returned relative + to the screen; if 1, the bounding box position is returned relative + to the containing window. + @return a BoundingBox enclosing the image's onscreen representation. + """ + func = self.get_dbus_method("getImageExtents") + return BoundingBox(*func(dbus.Int16(coordType))) + + def getImagePosition(self, *args, **kwargs): + """ + Get the coordinates of the current image position on screen. + @param : x + Back-filled with the x coordinate of the onscreen image (i.e. + the minimum x coordinate) + @param : y + Back-filled with the y coordinate of the onscreen image (i.e. + the minimum y coordinate) + @param : coordType + If 0, the returned x and y coordinates are returned relative + to the screen; if 1, they are returned relative to the containing + window. + """ + func = self.get_dbus_method("getImagePosition") + return func(*args, **kwargs) + + def getImageSize(self, *args, **kwargs): + """ + Obtain the width and height of the current onscreen view of the + image. The extents returned do not account for any viewport clipping + or the fact that the image may be partially or wholly obscured + by other onscreen content. + @param : width + Back-filled with the x extents of the onscreen image (i.e. the + image width in pixels) + @param : height + Back-filled with the y extents of the onscreen image (i.e. the + image height in pixels) + """ + func = self.get_dbus_method("getImageSize") + return func(*args, **kwargs) + + def get_imageDescription(self): + return self._pgetter(self._dbus_interface, "imageDescription") + def set_imageDescription(self, value): + self._psetter(self._dbus_interface, "imageDescription", value) + _imageDescriptionDoc = \ + """ + A UTF-8 string providing a textual description of what is visually + depicted in the image. + """ + imageDescription = property(fget=get_imageDescription, fset=set_imageDescription, doc=_imageDescriptionDoc) + + def get_imageLocale(self): + return self._pgetter(self._dbus_interface, "imageLocale") + def set_imageLocale(self, value): + self._psetter(self._dbus_interface, "imageLocale", value) + _imageLocaleDoc = \ + """ + A string corresponding to the POSIX LC_MESSAGES locale used by + the imageDescription. + """ + imageLocale = property(fget=get_imageLocale, fset=set_imageLocale, doc=_imageLocaleDoc) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_IMAGE, Image) diff --git a/pyatspi/loginhelper.py b/pyatspi/loginhelper.py index 5d50820..d0aceb9 100644 --- a/pyatspi/loginhelper.py +++ b/pyatspi/loginhelper.py @@ -17,138 +17,128 @@ from base import BaseProxy, Enum from factory import add_accessible_class __all__ = [ - "LoginHelper", - ] + "LoginHelper", + ] #------------------------------------------------------------------------------ class LoginHelper(BaseProxy): - """ - An interface for use by assistive technologies by which they - can access system information and services on a 'need to know' - basis while the screen is locked, during user authentication, - or during other sensitive operations. - This interface is intended for use by assistive technologies - and related user-enabling services, and by applications and utilities - which may wish to restrict access to certain system devices and - services during security-sensitive states, e.g. when the screen - is locked or during authentication into some secure service. - Such 'applications' (for instance, screen lock dialogs and security-enabled - web browsers) use the LoginHelper client interfaces, and the - bonobo-activation query service, to query for assistive technologies - which advertise the LoginHelper service. The client then queries - these assistive technologies for their device I/O requirements, - via the getDeviceReqs call. The client may then issue the advisory - request setSafe (TRUE), which requests that the LoginHelper -implementing - service make a best-effort attempt to make itself more secure - (for instance, an onscreen keyboard might turn off word prediction, - and a screenreader may turn off keyboard echo via speech). The - return value of setSafe is an advisory indication of whether - this attempt was successful (no specific guarantees are implied). - Once the 'security sensitive' state is exited, the client should - call setSafe (FALSE). - The return values from getDeviceReqs inform the client of which - services the LoginHelper service (e. g. assistive technology) - needs in order to do its job. The client may use this information - to loosen any restrictions on access which it may currently have - in place (for instance, keyboard grabs, etc.). If it does not - do so, the likely outcome is that the end-user will experience - loss of access to the system. - """ - - def getDeviceReqs(self, *args, **kwargs): """ - getDeviceReqs: - Query a LoginHelper for the types of device I/O it requires, - in order to do its job. For instance, a LoginHelper which needs - to receive keyboard events will include Accessibility_LoginHelper_CORE_KEYBOARD - in this list. - @return : A sequence of LoginHelper_DeviceReq indicating the - device I/O required in order to facilitate end-user access to - the system. + An interface for use by assistive technologies by which they + can access system information and services on a 'need to know' + basis while the screen is locked, during user authentication, + or during other sensitive operations. + This interface is intended for use by assistive technologies + and related user-enabling services, and by applications and utilities + which may wish to restrict access to certain system devices and + services during security-sensitive states, e.g. when the screen + is locked or during authentication into some secure service. + Such 'applications' (for instance, screen lock dialogs and security-enabled + web browsers) use the LoginHelper client interfaces, and the + bonobo-activation query service, to query for assistive technologies + which advertise the LoginHelper service. The client then queries + these assistive technologies for their device I/O requirements, + via the getDeviceReqs call. The client may then issue the advisory + request setSafe (TRUE), which requests that the LoginHelper -implementing + service make a best-effort attempt to make itself more secure + (for instance, an onscreen keyboard might turn off word prediction, + and a screenreader may turn off keyboard echo via speech). The + return value of setSafe is an advisory indication of whether + this attempt was successful (no specific guarantees are implied). + Once the 'security sensitive' state is exited, the client should + call setSafe (FALSE). + The return values from getDeviceReqs inform the client of which + services the LoginHelper service (e. g. assistive technology) + needs in order to do its job. The client may use this information + to loosen any restrictions on access which it may currently have + in place (for instance, keyboard grabs, etc.). If it does not + do so, the likely outcome is that the end-user will experience + loss of access to the system. """ - func = self.get_dbus_method("getDeviceReqs") - return func(*args, **kwargs) - - def getRaiseWindows(self, *args, **kwargs): - """ - getRaiseWindows: - Get a list of window IDs that need raising on login. - @return : a sequence containing window IDS for toplevels which - need to be raised/made visible during user authentication, in - order for the LoginHelper to facilitate end-user access to the - system. - """ - func = self.get_dbus_method("getRaiseWindows") - return func(*args, **kwargs) - - def setSafe(self, *args, **kwargs): - """ - setSafe: - @param : safe_mode - TRUE if the client is requesting that 'safe mode' be initiated, - FALSE if the client is advising that 'safe mode' may be exited, - i.e. normal operation may be resumed. - Request a LoginHelper to enter "safe" mode, or inform LoginHelper - that "safe" mode may be exited. If safe_mode is TRUE, but the - return value is FALSE, the requesting client may wish to deny - services to the LoginHelper, for instance avoid raising its toplevels. - The return value is purely advisory, and no guarantees are intended - about what the implementing LoginHelper will do to improve security - when in "safe" mode. - @return : whether the LoginHelper is now "safe" or not. - """ - func = self.get_dbus_method("setSafe") - return func(*args, **kwargs) - - class DeviceReq(Enum): - _enum_lookup = { - 0:'GUI_EVENTS', - 1:'CORE_KEYBOARD', - 2:'CORE_POINTER', - 3:'EXT_INPUT', - 4:'POST_WINDOWS', - 5:'AUDIO_OUT', - 6:'AUDIO_IN', - 7:'NETWORK', - 8:'LOCALHOST', - 9:'SERIAL_OUT', - 10:'SERIAL_IN', - } - - AUDIO_IN = DeviceReq(6) - - AUDIO_OUT = DeviceReq(5) - - CORE_KEYBOARD = DeviceReq(1) - - CORE_POINTER = DeviceReq(2) - - EXT_INPUT = DeviceReq(3) - - GUI_EVENTS = DeviceReq(0) - - LOCALHOST = DeviceReq(8) - - NETWORK = DeviceReq(7) - - POST_WINDOWS = DeviceReq(4) - - SERIAL_IN = DeviceReq(10) - - SERIAL_OUT = DeviceReq(9) - - class WindowInfo(list): - def __new__(cls, winID): - list.__new__(cls, (winID)) - def __init__(self, winID): - list.__init__(self, (winID)) - - def _get_winID(self): - return self[0] - def _set_winID(self, val): - self[0] = val - winID = property(fget=_get_winID, fset=_set_winID) + + def getDeviceReqs(self, *args, **kwargs): + """ + getDeviceReqs: + Query a LoginHelper for the types of device I/O it requires, + in order to do its job. For instance, a LoginHelper which needs + to receive keyboard events will include Accessibility_LoginHelper_CORE_KEYBOARD + in this list. + @return : A sequence of LoginHelper_DeviceReq indicating the + device I/O required in order to facilitate end-user access to + the system. + """ + func = self.get_dbus_method("getDeviceReqs") + return func(*args, **kwargs) + + def getRaiseWindows(self, *args, **kwargs): + """ + getRaiseWindows: + Get a list of window IDs that need raising on login. + @return : a sequence containing window IDS for toplevels which + need to be raised/made visible during user authentication, in + order for the LoginHelper to facilitate end-user access to the + system. + """ + func = self.get_dbus_method("getRaiseWindows") + return func(*args, **kwargs) + + def setSafe(self, *args, **kwargs): + """ + setSafe: + @param : safe_mode + TRUE if the client is requesting that 'safe mode' be initiated, + FALSE if the client is advising that 'safe mode' may be exited, + i.e. normal operation may be resumed. + Request a LoginHelper to enter "safe" mode, or inform LoginHelper + that "safe" mode may be exited. If safe_mode is TRUE, but the + return value is FALSE, the requesting client may wish to deny + services to the LoginHelper, for instance avoid raising its toplevels. + The return value is purely advisory, and no guarantees are intended + about what the implementing LoginHelper will do to improve security + when in "safe" mode. + @return : whether the LoginHelper is now "safe" or not. + """ + func = self.get_dbus_method("setSafe") + return func(*args, **kwargs) + + class DeviceReq(Enum): + _enum_lookup = { + 0:'GUI_EVENTS', + 1:'CORE_KEYBOARD', + 2:'CORE_POINTER', + 3:'EXT_INPUT', + 4:'POST_WINDOWS', + 5:'AUDIO_OUT', + 6:'AUDIO_IN', + 7:'NETWORK', + 8:'LOCALHOST', + 9:'SERIAL_OUT', + 10:'SERIAL_IN', + } + + AUDIO_IN = DeviceReq(6) + AUDIO_OUT = DeviceReq(5) + CORE_KEYBOARD = DeviceReq(1) + CORE_POINTER = DeviceReq(2) + EXT_INPUT = DeviceReq(3) + GUI_EVENTS = DeviceReq(0) + LOCALHOST = DeviceReq(8) + NETWORK = DeviceReq(7) + POST_WINDOWS = DeviceReq(4) + SERIAL_IN = DeviceReq(10) + SERIAL_OUT = DeviceReq(9) + + class WindowInfo(list): + def __new__(cls, winID): + list.__new__(cls, (winID)) + def __init__(self, winID): + list.__init__(self, (winID)) + + def _get_winID(self): + return self[0] + def _set_winID(self, val): + self[0] = val + winID = property(fget=_get_winID, fset=_set_winID) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_LOGIN_HELPER, LoginHelper) diff --git a/pyatspi/registry.py b/pyatspi/registry.py index 96c3d10..d4dd284 100644 --- a/pyatspi/registry.py +++ b/pyatspi/registry.py @@ -35,12 +35,12 @@ _DBusGMainLoop(set_as_default=True) #------------------------------------------------------------------------------ class PressedEventType(_Enum): - _enum_lookup = { - 0:'KEY_PRESSED_EVENT', - 1:'KEY_RELEASED_EVENT', - 2:'BUTTON_PRESSED_EVENT', - 3:'BUTTON_RELEASED_EVENT', - } + _enum_lookup = { + 0:'KEY_PRESSED_EVENT', + 1:'KEY_RELEASED_EVENT', + 2:'BUTTON_PRESSED_EVENT', + 3:'BUTTON_RELEASED_EVENT', + } KEY_PRESSED_EVENT = PressedEventType(0) KEY_RELEASED_EVENT = PressedEventType(1) @@ -49,23 +49,23 @@ BUTTON_RELEASED_EVENT = PressedEventType(3) #------------------------------------------------------------------------------ class KeyEventType(_Enum): - _enum_lookup = { - 0:'KEY_PRESSED', - 1:'KEY_RELEASED', - } + _enum_lookup = { + 0:'KEY_PRESSED', + 1:'KEY_RELEASED', + } KEY_PRESSED = KeyEventType(0) KEY_RELEASED = KeyEventType(1) #------------------------------------------------------------------------------ class KeySynthType(_Enum): - _enum_lookup = { - 0:'KEY_PRESS', - 1:'KEY_RELEASE', - 2:'KEY_PRESSRELEASE', - 3:'KEY_SYM', - 4:'KEY_STRING', - } + _enum_lookup = { + 0:'KEY_PRESS', + 1:'KEY_RELEASE', + 2:'KEY_PRESSRELEASE', + 3:'KEY_SYM', + 4:'KEY_STRING', + } KEY_PRESS = KeySynthType(0) KEY_PRESSRELEASE = KeySynthType(2) @@ -76,16 +76,16 @@ KEY_SYM = KeySynthType(3) #------------------------------------------------------------------------------ class ModifierType(_Enum): - _enum_lookup = { - 0:'MODIFIER_SHIFT', - 1:'MODIFIER_SHIFTLOCK', - 2:'MODIFIER_CONTROL', - 3:'MODIFIER_ALT', - 4:'MODIFIER_META', - 5:'MODIFIER_META2', - 6:'MODIFIER_META3', - 7:'MODIFIER_NUMLOCK', - } + _enum_lookup = { + 0:'MODIFIER_SHIFT', + 1:'MODIFIER_SHIFTLOCK', + 2:'MODIFIER_CONTROL', + 3:'MODIFIER_ALT', + 4:'MODIFIER_META', + 5:'MODIFIER_META2', + 6:'MODIFIER_META3', + 7:'MODIFIER_NUMLOCK', + } MODIFIER_ALT = ModifierType(3) MODIFIER_CONTROL = ModifierType(2) @@ -99,400 +99,400 @@ MODIFIER_SHIFTLOCK = ModifierType(1) #------------------------------------------------------------------------------ class _Registry(object): - """ - Wraps the Accessibility.Registry to provide more Pythonic registration for - events. - - This object should be treated as a singleton, but such treatment is not - enforced. You can construct another instance of this object and give it a - reference to the Accessibility.Registry singleton. Doing so is harmless and - has no point. - - @ivar async: Should event dispatch to local listeners be decoupled from event - receiving from the registry? - @type async: boolean - @ivar reg: Reference to the real, wrapped registry object - @type reg: Accessibility.Registry - @ivar dev: Reference to the device controller - @type dev: Accessibility.DeviceEventController - @ivar queue: Queue of events awaiting local dispatch - @type queue: Queue.Queue - @ivar clients: Map of event names to client listeners - @type clients: dictionary - @ivar observers: Map of event names to AT-SPI L{_Observer} objects - @type observers: dictionary - """ - - _REGISTRY_NAME = 'org.freedesktop.atspi.Registry' - - def __init__(self): - """ - Stores a reference to the AT-SPI registry. Gets and stores a reference - to the DeviceEventController. - - @param reg: Reference to the AT-SPI registry daemon - @type reg: Accessibility.Registry - """ - self._bus = _dbus.SessionBus() - - app_name = None - if "ATSPI_TEST_APP_NAME" in _os.environ.keys(): - app_name = _os.environ["ATSPI_TEST_APP_NAME"] - if app_name: - self._app_name = app_name - self._cache = _TestApplicationCache(self, self._bus, app_name) - - self._event_listeners = {} - - # All of this special casing is for the 'faked' - # events caused by cache updates. - - self._name_type = _EventType("object:property-change:name") - self._name_listeners = {} - self._description_type = _EventType("object:property-change:description") - self._description_listeners = {} - self._parent_type = _EventType("object:property-change:parent") - self._parent_listeners = {} - self._children_changed_type = _EventType("object:children-changed") - self._children_changed_listeners = {} - - def __call__(self): - """ - @return: This instance of the registry - @rtype: L{Registry} - """ - return self - - def start(self, async=False, gil=True): - """ - Enter the main loop to start receiving and dispatching events. - - @param async: Should event dispatch be asynchronous (decoupled) from - event receiving from the AT-SPI registry? - @type async: boolean - @param gil: Add an idle callback which releases the Python GIL for a few - milliseconds to allow other threads to run? Necessary if other threads - will be used in this process. - Note - No Longer used. - @type gil: boolean - """ - self._loop = _gobject.MainLoop() - try: - self._loop.run() - except KeyboardInterrupt: - pass - - def stop(self, *args): - """Quits the main loop.""" - self._loop.quit() - self.flushEvents() - - def getDesktopCount(self): - """ - Gets the number of available desktops. - - @return: Number of desktops - @rtype: integer - """ - return 1 - - def getDesktop(self, i): - """ - Gets a reference to the i-th desktop. - - @param i: Which desktop to get - @type i: integer - @return: Desktop reference - @rtype: Accessibility.Desktop - """ - return _Desktop(self._cache) - - def _callClients(self, register, event): - for client in register.keys(): - client(event) - - def _notifyNameChange(self, event): - self._callClients(self._name_listeners, event) - - def _notifyDescriptionChange(self, event): - self._callClients(self._description_listeners, event) - - def _notifyParentChange(self, event): - self._callClients(self._parent_listeners, event) - - def _notifyChildenChange(self, event): - self._callClients(self._children_changed_listeners, event) - - def _registerFake(self, type, register, client, *names): - """ - Registers a client from a register of clients - for 'Fake' events emitted by the cache. - """ - try: - registered = register[client] - except KeyError: - registered = [] - register[client] = registered - - for name in names: - new_type = _EventType(name) - if new_type.is_subtype(type): - registered.append(new_type.name) - - def _deregisterFake(self, type, register, client, *names): - """ - Deregisters a client from a register of clients - for 'Fake' events emitted by the cache. - """ - try: - registered = register[client] - except KeyError: - return True - - for name in names: - remove_type = _EventType(name) - - for i in range(0, len(registered) - 1): - type_name = registered[i] - registered_type = _EventType(type_name) - - if remove_type.is_subtype(registered_type): - del(registered[i]) - - if registered == []: - del(register[client]) - - def registerEventListener(self, client, *names): - """ - Registers a new client callback for the given event names. Supports - registration for all subevents if only partial event name is specified. - Do not include a trailing colon. - - For example, 'object' will register for all object events, - 'object:property-change' will register for all property change events, - and 'object:property-change:accessible-parent' will register only for the - parent property change event. - - Registered clients will not be automatically removed when the client dies. - To ensure the client is properly garbage collected, call - L{deregisterEventListener}. - - @param client: Callable to be invoked when the event occurs - @type client: callable - @param names: List of full or partial event names - @type names: list of string - """ - try: - registered = self._event_listeners[client] - except KeyError: - registered = [] - self._event_listeners[client] = registered - - for name in names: - new_type = _EventType(name) - registered.append((new_type.name, - _event_type_to_signal_reciever(self._bus, self._cache, client, new_type))) - - self._registerFake(self._name_type, self._name_listeners, client, *names) - self._registerFake(self._description_type, self._description_listeners, client, *names) - self._registerFake(self._parent_type, self._parent_listeners, client, *names) - self._registerFake(self._children_changed_type, self._children_changed_listeners, client, *names) - - def deregisterEventListener(self, client, *names): - """ - Unregisters an existing client callback for the given event names. Supports - unregistration for all subevents if only partial event name is specified. - Do not include a trailing colon. - - This method must be called to ensure a client registered by - L{registerEventListener} is properly garbage collected. - - @param client: Client callback to remove - @type client: callable - @param names: List of full or partial event names - @type names: list of string - @return: Were event names specified for which the given client was not - registered? - @rtype: boolean - """ - try: - registered = self._event_listeners[client] - except KeyError: - # Presumably if were trying to deregister a client with - # no names then the return type is always true. - return True - - missing = False - - for name in names: - remove_type = _EventType(name) - - for i in range(0, len(registered) - 1): - (type_name, signal_match) = registered[i] - registered_type = _EventType(type_name) - - if remove_type.is_subtype(registered_type): - signal_match.remove() - del(registered[i]) - else: - missing = True - - if registered == []: - del(self._event_listeners[client]) - - #TODO Do these account for missing also? - self._deregisterFake(self._name_type, self._name_listeners, client, *names) - self._deregisterFake(self._description_type, self._description_listeners, client, *names) - self._deregisterFake(self._parent_type, self._parent_listeners, client, *names) - self._deregisterFake(self._children_changed_type, self._children_changed_listeners, client, *names) - - return missing - - def registerKeystrokeListener(self, - client, - key_set=[], - mask=0, - kind=(KEY_PRESSED_EVENT, KEY_RELEASED_EVENT), - synchronous=True, - preemptive=True, - global_=False): - """ - Registers a listener for key stroke events. - - @param client: Callable to be invoked when the event occurs - @type client: callable - @param key_set: Set of hardware key codes to stop monitoring. Leave empty - to indicate all keys. - @type key_set: list of integer - @param mask: When the mask is None, the codes in the key_set will be - monitored only when no modifier is held. When the mask is an - integer, keys in the key_set will be monitored only when the modifiers in - the mask are held. When the mask is an iterable over more than one - integer, keys in the key_set will be monitored when any of the modifier - combinations in the set are held. - @type mask: integer, iterable, None - @param kind: Kind of events to watch, KEY_PRESSED_EVENT or - KEY_RELEASED_EVENT. - @type kind: list - @param synchronous: Should the callback notification be synchronous, giving - the client the chance to consume the event? - @type synchronous: boolean - @param preemptive: Should the callback be allowed to preempt / consume the - event? - @type preemptive: boolean - @param global_: Should callback occur even if an application not supporting - AT-SPI is in the foreground? (requires xevie) - @type global_: boolean - """ - pass - - def deregisterKeystrokeListener(self, - client, - key_set=[], - mask=0, - kind=(KEY_PRESSED_EVENT, KEY_RELEASED_EVENT)): - """ - Deregisters a listener for key stroke events. - - @param client: Callable to be invoked when the event occurs - @type client: callable - @param key_set: Set of hardware key codes to stop monitoring. Leave empty - to indicate all keys. - @type key_set: list of integer - @param mask: When the mask is None, the codes in the key_set will be - monitored only when no modifier is held. When the mask is an - integer, keys in the key_set will be monitored only when the modifiers in - the mask are held. When the mask is an iterable over more than one - integer, keys in the key_set will be monitored when any of the modifier - combinations in the set are held. - @type mask: integer, iterable, None - @param kind: Kind of events to stop watching, KEY_PRESSED_EVENT or - KEY_RELEASED_EVENT. - @type kind: list - @raise KeyError: When the client isn't already registered for events - """ - pass - - def generateKeyboardEvent(self, keycode, keysym, kind): - """ - Generates a keyboard event. One of the keycode or the keysym parameters - should be specified and the other should be None. The kind parameter is - required and should be one of the KEY_PRESS, KEY_RELEASE, KEY_PRESSRELEASE, - KEY_SYM, or KEY_STRING. - - @param keycode: Hardware keycode or None - @type keycode: integer - @param keysym: Symbolic key string or None - @type keysym: string - @param kind: Kind of event to synthesize - @type kind: integer - """ - pass - - def generateMouseEvent(self, x, y, name): - """ - Generates a mouse event at the given absolute x and y coordinate. The kind - of event generated is specified by the name. For example, MOUSE_B1P - (button 1 press), MOUSE_REL (relative motion), MOUSE_B3D (butten 3 - double-click). - - @param x: Horizontal coordinate, usually left-hand oriented - @type x: integer - @param y: Vertical coordinate, usually left-hand oriented - @type y: integer - @param name: Name of the event to generate - @type name: string - """ - pass - - def handleDeviceEvent(self, event, ob): - """ - Dispatches L{event.DeviceEvent}s to registered clients. Clients are called - in the order they were registered for the given AT-SPI event. If any - client returns True, callbacks cease for the event for clients of this registry - instance. Clients of other registry instances and clients in other processes may - be affected depending on the values of synchronous and preemptive used when invoking - L{registerKeystrokeListener}. - - @note: Asynchronous dispatch of device events is not supported. - - @param event: AT-SPI device event - @type event: L{event.DeviceEvent} - @param ob: Observer that received the event - @type ob: L{_DeviceObserver} - - @return: Should the event be consumed (True) or allowed to pass on to other - AT-SPI observers (False)? - @rtype: boolean - """ - return True + """ + Wraps the Accessibility.Registry to provide more Pythonic registration for + events. + + This object should be treated as a singleton, but such treatment is not + enforced. You can construct another instance of this object and give it a + reference to the Accessibility.Registry singleton. Doing so is harmless and + has no point. + + @ivar async: Should event dispatch to local listeners be decoupled from event + receiving from the registry? + @type async: boolean + @ivar reg: Reference to the real, wrapped registry object + @type reg: Accessibility.Registry + @ivar dev: Reference to the device controller + @type dev: Accessibility.DeviceEventController + @ivar queue: Queue of events awaiting local dispatch + @type queue: Queue.Queue + @ivar clients: Map of event names to client listeners + @type clients: dictionary + @ivar observers: Map of event names to AT-SPI L{_Observer} objects + @type observers: dictionary + """ + + _REGISTRY_NAME = 'org.freedesktop.atspi.Registry' + + def __init__(self): + """ + Stores a reference to the AT-SPI registry. Gets and stores a reference + to the DeviceEventController. + + @param reg: Reference to the AT-SPI registry daemon + @type reg: Accessibility.Registry + """ + self._bus = _dbus.SessionBus() + + app_name = None + if "ATSPI_TEST_APP_NAME" in _os.environ.keys(): + app_name = _os.environ["ATSPI_TEST_APP_NAME"] + if app_name: + self._app_name = app_name + self._cache = _TestApplicationCache(self, self._bus, app_name) + + self._event_listeners = {} + + # All of this special casing is for the 'faked' + # events caused by cache updates. + + self._name_type = _EventType("object:property-change:name") + self._name_listeners = {} + self._description_type = _EventType("object:property-change:description") + self._description_listeners = {} + self._parent_type = _EventType("object:property-change:parent") + self._parent_listeners = {} + self._children_changed_type = _EventType("object:children-changed") + self._children_changed_listeners = {} + + def __call__(self): + """ + @return: This instance of the registry + @rtype: L{Registry} + """ + return self + + def start(self, async=False, gil=True): + """ + Enter the main loop to start receiving and dispatching events. + + @param async: Should event dispatch be asynchronous (decoupled) from + event receiving from the AT-SPI registry? + @type async: boolean + @param gil: Add an idle callback which releases the Python GIL for a few + milliseconds to allow other threads to run? Necessary if other threads + will be used in this process. + Note - No Longer used. + @type gil: boolean + """ + self._loop = _gobject.MainLoop() + try: + self._loop.run() + except KeyboardInterrupt: + pass + + def stop(self, *args): + """Quits the main loop.""" + self._loop.quit() + self.flushEvents() + + def getDesktopCount(self): + """ + Gets the number of available desktops. + + @return: Number of desktops + @rtype: integer + """ + return 1 + + def getDesktop(self, i): + """ + Gets a reference to the i-th desktop. + + @param i: Which desktop to get + @type i: integer + @return: Desktop reference + @rtype: Accessibility.Desktop + """ + return _Desktop(self._cache) + + def _callClients(self, register, event): + for client in register.keys(): + client(event) + + def _notifyNameChange(self, event): + self._callClients(self._name_listeners, event) + + def _notifyDescriptionChange(self, event): + self._callClients(self._description_listeners, event) + + def _notifyParentChange(self, event): + self._callClients(self._parent_listeners, event) + + def _notifyChildenChange(self, event): + self._callClients(self._children_changed_listeners, event) + + def _registerFake(self, type, register, client, *names): + """ + Registers a client from a register of clients + for 'Fake' events emitted by the cache. + """ + try: + registered = register[client] + except KeyError: + registered = [] + register[client] = registered + + for name in names: + new_type = _EventType(name) + if new_type.is_subtype(type): + registered.append(new_type.name) + + def _deregisterFake(self, type, register, client, *names): + """ + Deregisters a client from a register of clients + for 'Fake' events emitted by the cache. + """ + try: + registered = register[client] + except KeyError: + return True + + for name in names: + remove_type = _EventType(name) + + for i in range(0, len(registered) - 1): + type_name = registered[i] + registered_type = _EventType(type_name) + + if remove_type.is_subtype(registered_type): + del(registered[i]) + + if registered == []: + del(register[client]) + + def registerEventListener(self, client, *names): + """ + Registers a new client callback for the given event names. Supports + registration for all subevents if only partial event name is specified. + Do not include a trailing colon. + + For example, 'object' will register for all object events, + 'object:property-change' will register for all property change events, + and 'object:property-change:accessible-parent' will register only for the + parent property change event. + + Registered clients will not be automatically removed when the client dies. + To ensure the client is properly garbage collected, call + L{deregisterEventListener}. + + @param client: Callable to be invoked when the event occurs + @type client: callable + @param names: List of full or partial event names + @type names: list of string + """ + try: + registered = self._event_listeners[client] + except KeyError: + registered = [] + self._event_listeners[client] = registered + + for name in names: + new_type = _EventType(name) + registered.append((new_type.name, + _event_type_to_signal_reciever(self._bus, self._cache, client, new_type))) + + self._registerFake(self._name_type, self._name_listeners, client, *names) + self._registerFake(self._description_type, self._description_listeners, client, *names) + self._registerFake(self._parent_type, self._parent_listeners, client, *names) + self._registerFake(self._children_changed_type, self._children_changed_listeners, client, *names) + + def deregisterEventListener(self, client, *names): + """ + Unregisters an existing client callback for the given event names. Supports + unregistration for all subevents if only partial event name is specified. + Do not include a trailing colon. + + This method must be called to ensure a client registered by + L{registerEventListener} is properly garbage collected. + + @param client: Client callback to remove + @type client: callable + @param names: List of full or partial event names + @type names: list of string + @return: Were event names specified for which the given client was not + registered? + @rtype: boolean + """ + try: + registered = self._event_listeners[client] + except KeyError: + # Presumably if were trying to deregister a client with + # no names then the return type is always true. + return True + + missing = False + + for name in names: + remove_type = _EventType(name) + + for i in range(0, len(registered) - 1): + (type_name, signal_match) = registered[i] + registered_type = _EventType(type_name) + + if remove_type.is_subtype(registered_type): + signal_match.remove() + del(registered[i]) + else: + missing = True + + if registered == []: + del(self._event_listeners[client]) + + #TODO Do these account for missing also? + self._deregisterFake(self._name_type, self._name_listeners, client, *names) + self._deregisterFake(self._description_type, self._description_listeners, client, *names) + self._deregisterFake(self._parent_type, self._parent_listeners, client, *names) + self._deregisterFake(self._children_changed_type, self._children_changed_listeners, client, *names) + + return missing + + def registerKeystrokeListener(self, + client, + key_set=[], + mask=0, + kind=(KEY_PRESSED_EVENT, KEY_RELEASED_EVENT), + synchronous=True, + preemptive=True, + global_=False): + """ + Registers a listener for key stroke events. + + @param client: Callable to be invoked when the event occurs + @type client: callable + @param key_set: Set of hardware key codes to stop monitoring. Leave empty + to indicate all keys. + @type key_set: list of integer + @param mask: When the mask is None, the codes in the key_set will be + monitored only when no modifier is held. When the mask is an + integer, keys in the key_set will be monitored only when the modifiers in + the mask are held. When the mask is an iterable over more than one + integer, keys in the key_set will be monitored when any of the modifier + combinations in the set are held. + @type mask: integer, iterable, None + @param kind: Kind of events to watch, KEY_PRESSED_EVENT or + KEY_RELEASED_EVENT. + @type kind: list + @param synchronous: Should the callback notification be synchronous, giving + the client the chance to consume the event? + @type synchronous: boolean + @param preemptive: Should the callback be allowed to preempt / consume the + event? + @type preemptive: boolean + @param global_: Should callback occur even if an application not supporting + AT-SPI is in the foreground? (requires xevie) + @type global_: boolean + """ + pass + + def deregisterKeystrokeListener(self, + client, + key_set=[], + mask=0, + kind=(KEY_PRESSED_EVENT, KEY_RELEASED_EVENT)): + """ + Deregisters a listener for key stroke events. + + @param client: Callable to be invoked when the event occurs + @type client: callable + @param key_set: Set of hardware key codes to stop monitoring. Leave empty + to indicate all keys. + @type key_set: list of integer + @param mask: When the mask is None, the codes in the key_set will be + monitored only when no modifier is held. When the mask is an + integer, keys in the key_set will be monitored only when the modifiers in + the mask are held. When the mask is an iterable over more than one + integer, keys in the key_set will be monitored when any of the modifier + combinations in the set are held. + @type mask: integer, iterable, None + @param kind: Kind of events to stop watching, KEY_PRESSED_EVENT or + KEY_RELEASED_EVENT. + @type kind: list + @raise KeyError: When the client isn't already registered for events + """ + pass + + def generateKeyboardEvent(self, keycode, keysym, kind): + """ + Generates a keyboard event. One of the keycode or the keysym parameters + should be specified and the other should be None. The kind parameter is + required and should be one of the KEY_PRESS, KEY_RELEASE, KEY_PRESSRELEASE, + KEY_SYM, or KEY_STRING. + + @param keycode: Hardware keycode or None + @type keycode: integer + @param keysym: Symbolic key string or None + @type keysym: string + @param kind: Kind of event to synthesize + @type kind: integer + """ + pass + + def generateMouseEvent(self, x, y, name): + """ + Generates a mouse event at the given absolute x and y coordinate. The kind + of event generated is specified by the name. For example, MOUSE_B1P + (button 1 press), MOUSE_REL (relative motion), MOUSE_B3D (butten 3 + double-click). + + @param x: Horizontal coordinate, usually left-hand oriented + @type x: integer + @param y: Vertical coordinate, usually left-hand oriented + @type y: integer + @param name: Name of the event to generate + @type name: string + """ + pass + + def handleDeviceEvent(self, event, ob): + """ + Dispatches L{event.DeviceEvent}s to registered clients. Clients are called + in the order they were registered for the given AT-SPI event. If any + client returns True, callbacks cease for the event for clients of this registry + instance. Clients of other registry instances and clients in other processes may + be affected depending on the values of synchronous and preemptive used when invoking + L{registerKeystrokeListener}. + + @note: Asynchronous dispatch of device events is not supported. + + @param event: AT-SPI device event + @type event: L{event.DeviceEvent} + @param ob: Observer that received the event + @type ob: L{_DeviceObserver} + + @return: Should the event be consumed (True) or allowed to pass on to other + AT-SPI observers (False)? + @rtype: boolean + """ + return True - def handleEvent(self, event): - """ - Handles an AT-SPI event by either queuing it for later dispatch when the - L{Registry.async} flag is set, or dispatching it immediately. - - @param event: AT-SPI event - @type event: L{event.Event} - """ - pass - - def flushEvents(self): - """ - Flushes the event queue by destroying it and recreating it. - """ - pass - - def pumpQueuedEvents(self, num=-1): - """ - Provides asynch processing of events in the queue by executeing them with - _dispatchEvent() (as is done immediately when synch processing). - This method would normally be called from a main loop or idle function. - - @param num: Number of events to pump. If number is negative it pumps - the entire queue. Default is -1. - @type num: integer - @return: True if queue is not empty after events were pumped. - @rtype: boolean - """ - return False + def handleEvent(self, event): + """ + Handles an AT-SPI event by either queuing it for later dispatch when the + L{Registry.async} flag is set, or dispatching it immediately. + + @param event: AT-SPI event + @type event: L{event.Event} + """ + pass + + def flushEvents(self): + """ + Flushes the event queue by destroying it and recreating it. + """ + pass + + def pumpQueuedEvents(self, num=-1): + """ + Provides asynch processing of events in the queue by executeing them with + _dispatchEvent() (as is done immediately when synch processing). + This method would normally be called from a main loop or idle function. + + @param num: Number of events to pump. If number is negative it pumps + the entire queue. Default is -1. + @type num: integer + @return: True if queue is not empty after events were pumped. + @rtype: boolean + """ + return False diff --git a/pyatspi/relation.py b/pyatspi/relation.py index de91e25..c963966 100644 --- a/pyatspi/relation.py +++ b/pyatspi/relation.py @@ -26,66 +26,48 @@ from factory import create_accessible #------------------------------------------------------------------------------ class RelationType(_Enum): - _enum_lookup = { - 0:'RELATION_NULL', - 1:'RELATION_LABEL_FOR', - 2:'RELATION_LABELLED_BY', - 3:'RELATION_CONTROLLER_FOR', - 4:'RELATION_CONTROLLED_BY', - 5:'RELATION_MEMBER_OF', - 6:'RELATION_TOOLTIP_FOR', - 7:'RELATION_NODE_CHILD_OF', - 8:'RELATION_EXTENDED', - 9:'RELATION_FLOWS_TO', - 10:'RELATION_FLOWS_FROM', - 11:'RELATION_SUBWINDOW_OF', - 12:'RELATION_EMBEDS', - 13:'RELATION_EMBEDDED_BY', - 14:'RELATION_POPUP_FOR', - 15:'RELATION_PARENT_WINDOW_OF', - 16:'RELATION_DESCRIPTION_FOR', - 17:'RELATION_DESCRIBED_BY', - 18:'RELATION_LAST_DEFINED', - } + _enum_lookup = { + 0:'RELATION_NULL', + 1:'RELATION_LABEL_FOR', + 2:'RELATION_LABELLED_BY', + 3:'RELATION_CONTROLLER_FOR', + 4:'RELATION_CONTROLLED_BY', + 5:'RELATION_MEMBER_OF', + 6:'RELATION_TOOLTIP_FOR', + 7:'RELATION_NODE_CHILD_OF', + 8:'RELATION_EXTENDED', + 9:'RELATION_FLOWS_TO', + 10:'RELATION_FLOWS_FROM', + 11:'RELATION_SUBWINDOW_OF', + 12:'RELATION_EMBEDS', + 13:'RELATION_EMBEDDED_BY', + 14:'RELATION_POPUP_FOR', + 15:'RELATION_PARENT_WINDOW_OF', + 16:'RELATION_DESCRIPTION_FOR', + 17:'RELATION_DESCRIBED_BY', + 18:'RELATION_LAST_DEFINED', + } #------------------------------------------------------------------------------ RELATION_CONTROLLED_BY = RelationType(4) - RELATION_CONTROLLER_FOR = RelationType(3) - RELATION_DESCRIBED_BY = RelationType(17) - RELATION_DESCRIPTION_FOR = RelationType(16) - RELATION_EMBEDDED_BY = RelationType(13) - RELATION_EMBEDS = RelationType(12) - RELATION_EXTENDED = RelationType(8) - RELATION_FLOWS_FROM = RelationType(10) - RELATION_FLOWS_TO = RelationType(9) - RELATION_LABELLED_BY = RelationType(2) - RELATION_LABEL_FOR = RelationType(1) - RELATION_LAST_DEFINED = RelationType(18) - RELATION_MEMBER_OF = RelationType(5) - RELATION_NODE_CHILD_OF = RelationType(7) - RELATION_NULL = RelationType(0) - RELATION_PARENT_WINDOW_OF = RelationType(15) - RELATION_POPUP_FOR = RelationType(14) - RELATION_SUBWINDOW_OF = RelationType(11) - RELATION_TOOLTIP_FOR = RelationType(6) #------------------------------------------------------------------------------ @@ -100,59 +82,59 @@ RELATION_VALUE_TO_NAME = dict(((value, name[9:].lower().replace('_', ' ')) #------------------------------------------------------------------------------ def _marshal_relation_set(cache, app_name, relation_set): - """ - The D-Bus protocol has a relation set passed as an array of - relation types and object arrays. + """ + The D-Bus protocol has a relation set passed as an array of + relation types and object arrays. - This function marshals the D-Bus message into a list of relation - objects. - """ - return [Relation(cache, app_name, *relation) for relation in relation_set] + This function marshals the D-Bus message into a list of relation + objects. + """ + return [Relation(cache, app_name, *relation) for relation in relation_set] #------------------------------------------------------------------------------ class Relation(object): - """ - An interface via which objects' non-hierarchical relationships - to one another are indicated. An instance of Relations represents - a "one-to-many" correspondance. - """ - - def __init__(self, cache, app_name, type, objects): - self._type = type - self._objects = objects - - self._cache = cache - self._app_name = app_name - - def getNTargets(self): - """ - @return the number of objects to which this relationship applies. """ - return len(self._objects) - - def getRelationType(self): + An interface via which objects' non-hierarchical relationships + to one another are indicated. An instance of Relations represents + a "one-to-many" correspondance. """ - @return the RelationType of this Relation. - """ - return self._type - - def getRelationTypeName(self): - """ - @return an unlocalized string representing the relation type. - """ - return RELATION_VALUE_TO_NAME[self._type] - - def getTarget(self, index): - """ - @return an Object which is the 'nth'target of this Relation, - e.g. the Object at index i in the list of Objects having the - specified relationship to this Accessible. - """ - return create_accessible(self._cache, - self._app_name, - self._objects[index], - interfaces.ATSPI_ACCESSIBLE, - connection=self._cache._connection) + + def __init__(self, cache, app_name, type, objects): + self._type = type + self._objects = objects + + self._cache = cache + self._app_name = app_name + + def getNTargets(self): + """ + @return the number of objects to which this relationship applies. + """ + return len(self._objects) + + def getRelationType(self): + """ + @return the RelationType of this Relation. + """ + return self._type + + def getRelationTypeName(self): + """ + @return an unlocalized string representing the relation type. + """ + return RELATION_VALUE_TO_NAME[self._type] + + def getTarget(self, index): + """ + @return an Object which is the 'nth'target of this Relation, + e.g. the Object at index i in the list of Objects having the + specified relationship to this Accessible. + """ + return create_accessible(self._cache, + self._app_name, + self._objects[index], + interfaces.ATSPI_ACCESSIBLE, + connection=self._cache._connection) #END---------------------------------------------------------------------------- diff --git a/pyatspi/role.py b/pyatspi/role.py index a2cf9ce..b4fe24f 100644 --- a/pyatspi/role.py +++ b/pyatspi/role.py @@ -17,99 +17,99 @@ from base import Enum as _Enum #------------------------------------------------------------------------------ class Role(_Enum): - _enum_lookup = { - 0:'ROLE_INVALID', - 1:'ROLE_ACCELERATOR_LABEL', - 2:'ROLE_ALERT', - 3:'ROLE_ANIMATION', - 4:'ROLE_ARROW', - 5:'ROLE_CALENDAR', - 6:'ROLE_CANVAS', - 7:'ROLE_CHECK_BOX', - 8:'ROLE_CHECK_MENU_ITEM', - 9:'ROLE_COLOR_CHOOSER', - 10:'ROLE_COLUMN_HEADER', - 11:'ROLE_COMBO_BOX', - 12:'ROLE_DATE_EDITOR', - 13:'ROLE_DESKTOP_ICON', - 14:'ROLE_DESKTOP_FRAME', - 15:'ROLE_DIAL', - 16:'ROLE_DIALOG', - 17:'ROLE_DIRECTORY_PANE', - 18:'ROLE_DRAWING_AREA', - 19:'ROLE_FILE_CHOOSER', - 20:'ROLE_FILLER', - 21:'ROLE_FOCUS_TRAVERSABLE', - 22:'ROLE_FONT_CHOOSER', - 23:'ROLE_FRAME', - 24:'ROLE_GLASS_PANE', - 25:'ROLE_HTML_CONTAINER', - 26:'ROLE_ICON', - 27:'ROLE_IMAGE', - 28:'ROLE_INTERNAL_FRAME', - 29:'ROLE_LABEL', - 30:'ROLE_LAYERED_PANE', - 31:'ROLE_LIST', - 32:'ROLE_LIST_ITEM', - 33:'ROLE_MENU', - 34:'ROLE_MENU_BAR', - 35:'ROLE_MENU_ITEM', - 36:'ROLE_OPTION_PANE', - 37:'ROLE_PAGE_TAB', - 38:'ROLE_PAGE_TAB_LIST', - 39:'ROLE_PANEL', - 40:'ROLE_PASSWORD_TEXT', - 41:'ROLE_POPUP_MENU', - 42:'ROLE_PROGRESS_BAR', - 43:'ROLE_PUSH_BUTTON', - 44:'ROLE_RADIO_BUTTON', - 45:'ROLE_RADIO_MENU_ITEM', - 46:'ROLE_ROOT_PANE', - 47:'ROLE_ROW_HEADER', - 48:'ROLE_SCROLL_BAR', - 49:'ROLE_SCROLL_PANE', - 50:'ROLE_SEPARATOR', - 51:'ROLE_SLIDER', - 52:'ROLE_SPIN_BUTTON', - 53:'ROLE_SPLIT_PANE', - 54:'ROLE_STATUS_BAR', - 55:'ROLE_TABLE', - 56:'ROLE_TABLE_CELL', - 57:'ROLE_TABLE_COLUMN_HEADER', - 58:'ROLE_TABLE_ROW_HEADER', - 59:'ROLE_TEAROFF_MENU_ITEM', - 60:'ROLE_TERMINAL', - 61:'ROLE_TEXT', - 62:'ROLE_TOGGLE_BUTTON', - 63:'ROLE_TOOL_BAR', - 64:'ROLE_TOOL_TIP', - 65:'ROLE_TREE', - 66:'ROLE_TREE_TABLE', - 67:'ROLE_UNKNOWN', - 68:'ROLE_VIEWPORT', - 69:'ROLE_WINDOW', - 70:'ROLE_EXTENDED', - 71:'ROLE_HEADER', - 72:'ROLE_FOOTER', - 73:'ROLE_PARAGRAPH', - 74:'ROLE_RULER', - 75:'ROLE_APPLICATION', - 76:'ROLE_AUTOCOMPLETE', - 77:'ROLE_EDITBAR', - 78:'ROLE_EMBEDDED', - 79:'ROLE_ENTRY', - 80:'ROLE_CHART', - 81:'ROLE_CAPTION', - 82:'ROLE_DOCUMENT_FRAME', - 83:'ROLE_HEADING', - 84:'ROLE_PAGE', - 85:'ROLE_SECTION', - 86:'ROLE_REDUNDANT_OBJECT', - 87:'ROLE_FORM', - 88:'ROLE_LINK', - 89:'ROLE_INPUT_METHOD_WINDOW', - 90:'ROLE_LAST_DEFINED', - } + _enum_lookup = { + 0:'ROLE_INVALID', + 1:'ROLE_ACCELERATOR_LABEL', + 2:'ROLE_ALERT', + 3:'ROLE_ANIMATION', + 4:'ROLE_ARROW', + 5:'ROLE_CALENDAR', + 6:'ROLE_CANVAS', + 7:'ROLE_CHECK_BOX', + 8:'ROLE_CHECK_MENU_ITEM', + 9:'ROLE_COLOR_CHOOSER', + 10:'ROLE_COLUMN_HEADER', + 11:'ROLE_COMBO_BOX', + 12:'ROLE_DATE_EDITOR', + 13:'ROLE_DESKTOP_ICON', + 14:'ROLE_DESKTOP_FRAME', + 15:'ROLE_DIAL', + 16:'ROLE_DIALOG', + 17:'ROLE_DIRECTORY_PANE', + 18:'ROLE_DRAWING_AREA', + 19:'ROLE_FILE_CHOOSER', + 20:'ROLE_FILLER', + 21:'ROLE_FOCUS_TRAVERSABLE', + 22:'ROLE_FONT_CHOOSER', + 23:'ROLE_FRAME', + 24:'ROLE_GLASS_PANE', + 25:'ROLE_HTML_CONTAINER', + 26:'ROLE_ICON', + 27:'ROLE_IMAGE', + 28:'ROLE_INTERNAL_FRAME', + 29:'ROLE_LABEL', + 30:'ROLE_LAYERED_PANE', + 31:'ROLE_LIST', + 32:'ROLE_LIST_ITEM', + 33:'ROLE_MENU', + 34:'ROLE_MENU_BAR', + 35:'ROLE_MENU_ITEM', + 36:'ROLE_OPTION_PANE', + 37:'ROLE_PAGE_TAB', + 38:'ROLE_PAGE_TAB_LIST', + 39:'ROLE_PANEL', + 40:'ROLE_PASSWORD_TEXT', + 41:'ROLE_POPUP_MENU', + 42:'ROLE_PROGRESS_BAR', + 43:'ROLE_PUSH_BUTTON', + 44:'ROLE_RADIO_BUTTON', + 45:'ROLE_RADIO_MENU_ITEM', + 46:'ROLE_ROOT_PANE', + 47:'ROLE_ROW_HEADER', + 48:'ROLE_SCROLL_BAR', + 49:'ROLE_SCROLL_PANE', + 50:'ROLE_SEPARATOR', + 51:'ROLE_SLIDER', + 52:'ROLE_SPIN_BUTTON', + 53:'ROLE_SPLIT_PANE', + 54:'ROLE_STATUS_BAR', + 55:'ROLE_TABLE', + 56:'ROLE_TABLE_CELL', + 57:'ROLE_TABLE_COLUMN_HEADER', + 58:'ROLE_TABLE_ROW_HEADER', + 59:'ROLE_TEAROFF_MENU_ITEM', + 60:'ROLE_TERMINAL', + 61:'ROLE_TEXT', + 62:'ROLE_TOGGLE_BUTTON', + 63:'ROLE_TOOL_BAR', + 64:'ROLE_TOOL_TIP', + 65:'ROLE_TREE', + 66:'ROLE_TREE_TABLE', + 67:'ROLE_UNKNOWN', + 68:'ROLE_VIEWPORT', + 69:'ROLE_WINDOW', + 70:'ROLE_EXTENDED', + 71:'ROLE_HEADER', + 72:'ROLE_FOOTER', + 73:'ROLE_PARAGRAPH', + 74:'ROLE_RULER', + 75:'ROLE_APPLICATION', + 76:'ROLE_AUTOCOMPLETE', + 77:'ROLE_EDITBAR', + 78:'ROLE_EMBEDDED', + 79:'ROLE_ENTRY', + 80:'ROLE_CHART', + 81:'ROLE_CAPTION', + 82:'ROLE_DOCUMENT_FRAME', + 83:'ROLE_HEADING', + 84:'ROLE_PAGE', + 85:'ROLE_SECTION', + 86:'ROLE_REDUNDANT_OBJECT', + 87:'ROLE_FORM', + 88:'ROLE_LINK', + 89:'ROLE_INPUT_METHOD_WINDOW', + 90:'ROLE_LAST_DEFINED', + } ROLE_ACCELERATOR_LABEL = Role(1) ROLE_ALERT = Role(2) diff --git a/pyatspi/selection.py b/pyatspi/selection.py index 3811061..b68c33c 100644 --- a/pyatspi/selection.py +++ b/pyatspi/selection.py @@ -17,117 +17,117 @@ from base import BaseProxy from factory import add_accessible_class __all__ = [ - "Selection", - ] + "Selection", + ] #------------------------------------------------------------------------------ class Selection(BaseProxy): - """ - An interface which indicates that an object exposes a 'selection' - model, allowing the selection of one or more of its children. - Read-only Selection instances are possible, in which case the - interface is used to programmatically determine the selected-ness - of its children. A selected child has State::STATE_SELECTED, - and a child which may hypothetically be selected (though possibly - not programmatically selectable) has State::STATE_SELECTABLE. - """ - - def clearSelection(self, *args, **kwargs): """ - Attempt to clear all selections (i.e. deselect all children) - of a Selection. Not all Selection implementations allow the removal - of all selections. - @return True if the selections were successfully cleared, False - otherwise. + An interface which indicates that an object exposes a 'selection' + model, allowing the selection of one or more of its children. + Read-only Selection instances are possible, in which case the + interface is used to programmatically determine the selected-ness + of its children. A selected child has State::STATE_SELECTED, + and a child which may hypothetically be selected (though possibly + not programmatically selectable) has State::STATE_SELECTABLE. """ - func = self.get_dbus_method("clearSelection") - return func(*args, **kwargs) - - def deselectChild(self, *args, **kwargs): - """ - Remove a child from the selected children list of a Selection, - if the child is currently selected. - @param : childIndex - a long integer (the zero offset index into the Accessible object's - list of children) indicating which child of the Selection is - to be selected. - @return True if the child was successfully selected, False otherwise. - """ - func = self.get_dbus_method("deselectChild") - return func(*args, **kwargs) - - def deselectSelectedChild(self, *args, **kwargs): - """ - Remove a child to the selected children list of a Selection. - @param : selectedChildIndex - a long integer indicating which of the selected children of the - Selection is to be deselected. The index is a zero-offset index - into the 'selected child list', not a zero-offset index into - the list of all children of the Selection. - @return True if the child was successfully deselected, False - otherwise. - """ - func = self.get_dbus_method("deselectSelectedChild") - return func(*args, **kwargs) - - def getSelectedChild(self, *args, **kwargs): - """ - Get the i-th selected Accessible child of a Selection. - @param : selectedChildIndex - a long integer indicating which of the selected children of an - object is being requested. - @return a pointer to a selected Accessible child object, specified - by selectedChildIndex. - """ - func = self.get_dbus_method("getSelectedChild") - return func(*args, **kwargs) - - def isChildSelected(self, *args, **kwargs): - """ - Determine whether a particular child of an Selection implementor - is currently selected. Note that childIndex is the zero-offset - index into the standard Accessible container's list of children. - @param : childIndex - an index into the Selection's list of children. - @return True if the specified child is currently selected, False - otherwise. - """ - func = self.get_dbus_method("isChildSelected") - return func(*args, **kwargs) - - def selectAll(self, *args, **kwargs): - """ - Attempt to select all of the children of a Selection implementor. - Not all Selection implementors support this operation (for instance, - implementations which support only "single selection" do not - support this operation). - @return True if successful, False otherwise. - """ - func = self.get_dbus_method("selectAll") - return func(*args, **kwargs) - - def selectChild(self, *args, **kwargs): - """ - Add a child to the selected children list of a Selection. - @param : childIndex - a long integer indicating which child of the Selection is to - be selected. - @return True if the child was successfully selected, False otherwise. - """ - func = self.get_dbus_method("selectChild") - return func(*args, **kwargs) - - def get_nSelectedChildren(self): - return self._pgetter(self._dbus_interface, "nSelectedChildren") - def set_nSelectedChildren(self, value): - self._psetter(self._dbus_interface, "nSelectedChildren", value) - _nSelectedChildrenDoc = \ - """ - The number of children of a Selection implementor which are currently - selected. - """ - nSelectedChildren = property(fget=get_nSelectedChildren, fset=set_nSelectedChildren, doc=_nSelectedChildrenDoc) + + def clearSelection(self, *args, **kwargs): + """ + Attempt to clear all selections (i.e. deselect all children) + of a Selection. Not all Selection implementations allow the removal + of all selections. + @return True if the selections were successfully cleared, False + otherwise. + """ + func = self.get_dbus_method("clearSelection") + return func(*args, **kwargs) + + def deselectChild(self, *args, **kwargs): + """ + Remove a child from the selected children list of a Selection, + if the child is currently selected. + @param : childIndex + a long integer (the zero offset index into the Accessible object's + list of children) indicating which child of the Selection is + to be selected. + @return True if the child was successfully selected, False otherwise. + """ + func = self.get_dbus_method("deselectChild") + return func(*args, **kwargs) + + def deselectSelectedChild(self, *args, **kwargs): + """ + Remove a child to the selected children list of a Selection. + @param : selectedChildIndex + a long integer indicating which of the selected children of the + Selection is to be deselected. The index is a zero-offset index + into the 'selected child list', not a zero-offset index into + the list of all children of the Selection. + @return True if the child was successfully deselected, False + otherwise. + """ + func = self.get_dbus_method("deselectSelectedChild") + return func(*args, **kwargs) + + def getSelectedChild(self, *args, **kwargs): + """ + Get the i-th selected Accessible child of a Selection. + @param : selectedChildIndex + a long integer indicating which of the selected children of an + object is being requested. + @return a pointer to a selected Accessible child object, specified + by selectedChildIndex. + """ + func = self.get_dbus_method("getSelectedChild") + return func(*args, **kwargs) + + def isChildSelected(self, *args, **kwargs): + """ + Determine whether a particular child of an Selection implementor + is currently selected. Note that childIndex is the zero-offset + index into the standard Accessible container's list of children. + @param : childIndex + an index into the Selection's list of children. + @return True if the specified child is currently selected, False + otherwise. + """ + func = self.get_dbus_method("isChildSelected") + return func(*args, **kwargs) + + def selectAll(self, *args, **kwargs): + """ + Attempt to select all of the children of a Selection implementor. + Not all Selection implementors support this operation (for instance, + implementations which support only "single selection" do not + support this operation). + @return True if successful, False otherwise. + """ + func = self.get_dbus_method("selectAll") + return func(*args, **kwargs) + + def selectChild(self, *args, **kwargs): + """ + Add a child to the selected children list of a Selection. + @param : childIndex + a long integer indicating which child of the Selection is to + be selected. + @return True if the child was successfully selected, False otherwise. + """ + func = self.get_dbus_method("selectChild") + return func(*args, **kwargs) + + def get_nSelectedChildren(self): + return self._pgetter(self._dbus_interface, "nSelectedChildren") + def set_nSelectedChildren(self, value): + self._psetter(self._dbus_interface, "nSelectedChildren", value) + _nSelectedChildrenDoc = \ + """ + The number of children of a Selection implementor which are currently + selected. + """ + nSelectedChildren = property(fget=get_nSelectedChildren, fset=set_nSelectedChildren, doc=_nSelectedChildrenDoc) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_SELECTION, Selection) diff --git a/pyatspi/selector.py b/pyatspi/selector.py index 21fb989..1de3ead 100644 --- a/pyatspi/selector.py +++ b/pyatspi/selector.py @@ -17,154 +17,150 @@ from base import BaseProxy, Enum from factory import add_accessible_class __all__ = [ - "Selector", - "Command", - "CommandListener", - ] + "Selector", + "Command", + "CommandListener", + ] #------------------------------------------------------------------------------ class Command(list): - def __new__(cls, name, id): - list.__new__(cls, (name, id)) - def __init__(self, name, id): - list.__init__(self, (name, id)) - - def _get_name(self): - return self[0] - def _set_name(self, val): - self[0] = val - name = property(fget=_get_name, fset=_set_name) - def _get_id(self): - return self[1] - def _set_id(self, val): - self[1] = val - id = property(fget=_get_id, fset=_set_id) + def __new__(cls, name, id): + list.__new__(cls, (name, id)) + def __init__(self, name, id): + list.__init__(self, (name, id)) + + def _get_name(self): + return self[0] + def _set_name(self, val): + self[0] = val + name = property(fget=_get_name, fset=_set_name) + def _get_id(self): + return self[1] + def _set_id(self, val): + self[1] = val + id = property(fget=_get_id, fset=_set_id) #------------------------------------------------------------------------------ class CommandListener(BaseProxy): - """ - An interface which should be implemented by assistive technologies - or other clients of the Selector interface, over which notifications - to the list of available commands is made. The notifyCommands() - method of the client is then called by the Selector instance. - """ - def notifyCommands(self, *args, **kwargs): - """ - Notify the CommandListener instance of changes to the currently - available commands, by sending the current CommandList. - @param : commands - The newly-available list of Command objects which may be invoked - by the listener. """ - func = self.get_dbus_method("notifyCommands") - return func(*args, **kwargs) + An interface which should be implemented by assistive technologies + or other clients of the Selector interface, over which notifications + to the list of available commands is made. The notifyCommands() + method of the client is then called by the Selector instance. + """ + def notifyCommands(self, *args, **kwargs): + """ + Notify the CommandListener instance of changes to the currently + available commands, by sending the current CommandList. + @param : commands + The newly-available list of Command objects which may be invoked + by the listener. + """ + func = self.get_dbus_method("notifyCommands") + return func(*args, **kwargs) #------------------------------------------------------------------------------ class Selector(BaseProxy): - """ - This interface is intended for use by assistive technologies - and related user-agents. Via this interface, an assistive technology - or user agent may expose a series of choices or selections in - textual form, which can be activated on demand by a client of - the Selector interface. - Examples of the use of this interface include voice-command and - remote-control applications, in which the user interaction is - wholly or partly delegated by the implementor to an external - agent. - """ - - def activateCommand(self, *args, **kwargs): - """ - Request that the Selector invoke the specified Command. - @param : cmd - the Command to activate/invoke. - @return a CommandResult indicating whether the request was honored, - and the reason for failure if the Command could not be activated - or invoked. - """ - func = self.get_dbus_method("activateCommand") - return func(*args, **kwargs) - - def deregisterChangeListener(self, *args, **kwargs): - """ - Tell the Selector instance to cease notifying the specified CommandListener - of changes to the command list. - @param : listener - the CommandListener to remove from the notification list. - """ - func = self.get_dbus_method("deregisterChangeListener") - return func(*args, **kwargs) - - def getCommands(self, *args, **kwargs): - """ - Query the Selector for the current CommandList. - @return the currently available CommandList - """ - func = self.get_dbus_method("getCommands") - return func(*args, **kwargs) - - def refreshCommands(self, *args, **kwargs): - """ - Ask the Selector to re-calculate its CommandList. - @return TRUE if the CommandList changed. - """ - func = self.get_dbus_method("refreshCommands") - return func(*args, **kwargs) - - def registerChangeListener(self, *args, **kwargs): - """ - Register a :CommandListener instance for notification of changes - to the command set. - @param : listener - the CommandListener to be notified of changes. - """ - func = self.get_dbus_method("registerChangeListener") - return func(*args, **kwargs) - - def replaceCommands(self, *args, **kwargs): """ - @return TRUE if the replacement request was successful, FALSE - if the request could not be honored. + This interface is intended for use by assistive technologies + and related user-agents. Via this interface, an assistive technology + or user agent may expose a series of choices or selections in + textual form, which can be activated on demand by a client of + the Selector interface. + Examples of the use of this interface include voice-command and + remote-control applications, in which the user interaction is + wholly or partly delegated by the implementor to an external + agent. """ - func = self.get_dbus_method("replaceCommands") - return func(*args, **kwargs) - - def get_supportsReplace(self): - return self._pgetter(self._dbus_interface, "supportsReplace") - def set_supportsReplace(self, value): - self._psetter(self._dbus_interface, "supportsReplace", value) - _supportsReplaceDoc = \ - """ - This attribute is TRUE if this Selector allows its CommandList - to be specified by the client - """ - supportsReplace = property(fget=get_supportsReplace, fset=set_supportsReplace, doc=_supportsReplaceDoc) - class CommandResult(Enum): - """ - A code returned by a call to activateCommand, indicating the - result of the activation request. - """ - _enum_lookup = { - 0:'COMMAND_RESULT_INVALID', - 1:'COMMAND_RESULT_SUCCESS', - 2:'COMMAND_RESULT_FAILED', - 3:'COMMAND_RESULT_OBSOLETE', - 4:'COMMAND_RESULT_LAST_DEFINED', - } - - COMMAND_RESULT_FAILED = CommandResult(2) - - COMMAND_RESULT_INVALID = CommandResult(0) - - COMMAND_RESULT_LAST_DEFINED = CommandResult(4) - - COMMAND_RESULT_OBSOLETE = CommandResult(3) - - COMMAND_RESULT_SUCCESS = CommandResult(1) + def activateCommand(self, *args, **kwargs): + """ + Request that the Selector invoke the specified Command. + @param : cmd + the Command to activate/invoke. + @return a CommandResult indicating whether the request was honored, + and the reason for failure if the Command could not be activated + or invoked. + """ + func = self.get_dbus_method("activateCommand") + return func(*args, **kwargs) + + def deregisterChangeListener(self, *args, **kwargs): + """ + Tell the Selector instance to cease notifying the specified CommandListener + of changes to the command list. + @param : listener + the CommandListener to remove from the notification list. + """ + func = self.get_dbus_method("deregisterChangeListener") + return func(*args, **kwargs) + + def getCommands(self, *args, **kwargs): + """ + Query the Selector for the current CommandList. + @return the currently available CommandList + """ + func = self.get_dbus_method("getCommands") + return func(*args, **kwargs) + + def refreshCommands(self, *args, **kwargs): + """ + Ask the Selector to re-calculate its CommandList. + @return TRUE if the CommandList changed. + """ + func = self.get_dbus_method("refreshCommands") + return func(*args, **kwargs) + + def registerChangeListener(self, *args, **kwargs): + """ + Register a :CommandListener instance for notification of changes + to the command set. + @param : listener + the CommandListener to be notified of changes. + """ + func = self.get_dbus_method("registerChangeListener") + return func(*args, **kwargs) + + def replaceCommands(self, *args, **kwargs): + """ + @return TRUE if the replacement request was successful, FALSE + if the request could not be honored. + """ + func = self.get_dbus_method("replaceCommands") + return func(*args, **kwargs) + + def get_supportsReplace(self): + return self._pgetter(self._dbus_interface, "supportsReplace") + def set_supportsReplace(self, value): + self._psetter(self._dbus_interface, "supportsReplace", value) + _supportsReplaceDoc = \ + """ + This attribute is TRUE if this Selector allows its CommandList + to be specified by the client + """ + supportsReplace = property(fget=get_supportsReplace, fset=set_supportsReplace, doc=_supportsReplaceDoc) + + class CommandResult(Enum): + """ + A code returned by a call to activateCommand, indicating the + result of the activation request. + """ + _enum_lookup = { + 0:'COMMAND_RESULT_INVALID', + 1:'COMMAND_RESULT_SUCCESS', + 2:'COMMAND_RESULT_FAILED', + 3:'COMMAND_RESULT_OBSOLETE', + 4:'COMMAND_RESULT_LAST_DEFINED', + } + + COMMAND_RESULT_FAILED = CommandResult(2) + COMMAND_RESULT_INVALID = CommandResult(0) + COMMAND_RESULT_LAST_DEFINED = CommandResult(4) + COMMAND_RESULT_OBSOLETE = CommandResult(3) + COMMAND_RESULT_SUCCESS = CommandResult(1) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_SELECTOR, Selector) diff --git a/pyatspi/state.py b/pyatspi/state.py index 6e698d4..fdfb284 100644 --- a/pyatspi/state.py +++ b/pyatspi/state.py @@ -24,50 +24,50 @@ from base import Enum as _Enum #------------------------------------------------------------------------------ class StateType(_Enum): - _enum_lookup = { - 0:'STATE_INVALID', - 1:'STATE_ACTIVE', - 2:'STATE_ARMED', - 3:'STATE_BUSY', - 4:'STATE_CHECKED', - 5:'STATE_COLLAPSED', - 6:'STATE_DEFUNCT', - 7:'STATE_EDITABLE', - 8:'STATE_ENABLED', - 9:'STATE_EXPANDABLE', - 10:'STATE_EXPANDED', - 11:'STATE_FOCUSABLE', - 12:'STATE_FOCUSED', - 13:'STATE_HAS_TOOLTIP', - 14:'STATE_HORIZONTAL', - 15:'STATE_ICONIFIED', - 16:'STATE_MODAL', - 17:'STATE_MULTI_LINE', - 18:'STATE_MULTISELECTABLE', - 19:'STATE_OPAQUE', - 20:'STATE_PRESSED', - 21:'STATE_RESIZABLE', - 22:'STATE_SELECTABLE', - 23:'STATE_SELECTED', - 24:'STATE_SENSITIVE', - 25:'STATE_SHOWING', - 26:'STATE_SINGLE_LINE', - 27:'STATE_STALE', - 28:'STATE_TRANSIENT', - 29:'STATE_VERTICAL', - 30:'STATE_VISIBLE', - 31:'STATE_MANAGES_DESCENDANTS', - 32:'STATE_INDETERMINATE', - 33:'STATE_REQUIRED', - 34:'STATE_TRUNCATED', - 35:'STATE_ANIMATED', - 36:'STATE_INVALID_ENTRY', - 37:'STATE_SUPPORTS_AUTOCOMPLETION', - 38:'STATE_SELECTABLE_TEXT', - 39:'STATE_IS_DEFAULT', - 40:'STATE_VISITED', - 41:'STATE_LAST_DEFINED', - } + _enum_lookup = { + 0:'STATE_INVALID', + 1:'STATE_ACTIVE', + 2:'STATE_ARMED', + 3:'STATE_BUSY', + 4:'STATE_CHECKED', + 5:'STATE_COLLAPSED', + 6:'STATE_DEFUNCT', + 7:'STATE_EDITABLE', + 8:'STATE_ENABLED', + 9:'STATE_EXPANDABLE', + 10:'STATE_EXPANDED', + 11:'STATE_FOCUSABLE', + 12:'STATE_FOCUSED', + 13:'STATE_HAS_TOOLTIP', + 14:'STATE_HORIZONTAL', + 15:'STATE_ICONIFIED', + 16:'STATE_MODAL', + 17:'STATE_MULTI_LINE', + 18:'STATE_MULTISELECTABLE', + 19:'STATE_OPAQUE', + 20:'STATE_PRESSED', + 21:'STATE_RESIZABLE', + 22:'STATE_SELECTABLE', + 23:'STATE_SELECTED', + 24:'STATE_SENSITIVE', + 25:'STATE_SHOWING', + 26:'STATE_SINGLE_LINE', + 27:'STATE_STALE', + 28:'STATE_TRANSIENT', + 29:'STATE_VERTICAL', + 30:'STATE_VISIBLE', + 31:'STATE_MANAGES_DESCENDANTS', + 32:'STATE_INDETERMINATE', + 33:'STATE_REQUIRED', + 34:'STATE_TRUNCATED', + 35:'STATE_ANIMATED', + 36:'STATE_INVALID_ENTRY', + 37:'STATE_SUPPORTS_AUTOCOMPLETION', + 38:'STATE_SELECTABLE_TEXT', + 39:'STATE_IS_DEFAULT', + 40:'STATE_VISITED', + 41:'STATE_LAST_DEFINED', + } #------------------------------------------------------------------------------ @@ -118,139 +118,139 @@ STATE_VISITED = StateType(40) # Build a dictionary mapping state values to names based on the prefix of the enum constants. -STATE_VALUE_TO_NAME = dict(((value, name[6:].lower().replace('_', ' ')) - for name, value - in globals().items() +STATE_VALUE_TO_NAME = dict(((value, name[6:].lower().replace('_', ' ')) + for name, value + in globals().items() if name.startswith('STATE_'))) #------------------------------------------------------------------------------ def _marshal_state_set(bitfield): - """ - The D-Bus protocol has a stateset object passed - as a 64bit bitfield. The Bits are passed as two 32bit - integers. - - This function marshals the D-Bus message into a - StateSet object that corresponds to these states. - """ - (lower, upper) = bitfield - - states = [] - - pos = 0 - while (lower): - if (1L)&lower: - states.append(StateType(pos)) - pos+=1 - lower >>= 1 - - pos = 32 - while (upper): - if (1L)&upper: - states.append(StateType(pos)) - pos+=1 - upper >>= 1 - - return StateSet(*states) + """ + The D-Bus protocol has a stateset object passed + as a 64bit bitfield. The Bits are passed as two 32bit + integers. + + This function marshals the D-Bus message into a + StateSet object that corresponds to these states. + """ + (lower, upper) = bitfield + + states = [] + + pos = 0 + while (lower): + if (1L)&lower: + states.append(StateType(pos)) + pos+=1 + lower >>= 1 + + pos = 32 + while (upper): + if (1L)&upper: + states.append(StateType(pos)) + pos+=1 + upper >>= 1 + + return StateSet(*states) #------------------------------------------------------------------------------ class StateSet(object): - """ - The StateSet object implements a wrapper around a - bitmap of Accessible states. - - The StateSet object is the instantaneous state of - the Accessible object and is not updated with its - container Accessible. This behaviour is different - to the CORBA version of AT-SPI - """ - def __init__(self, *states): - """ - Initializes the state set with the given states. - - @param states: States to add immediately - @type states: list - """ - self.states = set() - map(self.add, states) - - def contains(self, state): - """ - Checks if this StateSet contains the given state. - - @param state: State to check - @type state: Accessibility.StateType - @return: True if the set contains the given state - @rtype: boolean - """ - return state in self.states - - def add(self, *states): - """ - Adds states to this set. - - @param states: State(s) to add - @type states: Accessibility.StateType - """ - for state in states: - self.states.add(state) - - def remove(self, state): - """ - Removes states from this set. - - @param states: State(s) to remove - @type states: Accessibility.StateType - """ - self.states.remove(state) - - def equals(self, state_set): - """ - Checks if this StateSet contains exactly the same members as the given - StateSet. - - @param state_set: Another set - @type state_set: Accessibility.StateSet - @return: Are the sets equivalent in terms of their contents? - @rtype: boolean - """ - return set(state_set.getStates()) == self.states - - def compare(self, state_set): - """ - Finds the symmetric difference between this state set andthe one provided, - and returns it as a new StateSet. - - @note: This does not use L{_StateSetImpl.compare} which cannot be - implemented at this time - @param state_set: Set to compare against - @type state_set: Accessibility.StateSet - @return: Proxy for the new set - @rtype: L{StateSet} - """ - a = set(self.getStates()) - b = set(state_set.getStates()) - diff = a.symmetric_difference(b) - return StateSet(*diff) - - def isEmpty(self): - """ - Checks if this StateSet is empty. - - @return: Is it empty? - @rtype: boolean - """ - return len(self.states) == 0 - - def getStates(self): - """ - Gets the sequence of all states in this set. - - @return: List of states - @rtype: list - """ - return list(self.states) + """ + The StateSet object implements a wrapper around a + bitmap of Accessible states. + + The StateSet object is the instantaneous state of + the Accessible object and is not updated with its + container Accessible. This behaviour is different + to the CORBA version of AT-SPI + """ + def __init__(self, *states): + """ + Initializes the state set with the given states. + + @param states: States to add immediately + @type states: list + """ + self.states = set() + map(self.add, states) + + def contains(self, state): + """ + Checks if this StateSet contains the given state. + + @param state: State to check + @type state: Accessibility.StateType + @return: True if the set contains the given state + @rtype: boolean + """ + return state in self.states + + def add(self, *states): + """ + Adds states to this set. + + @param states: State(s) to add + @type states: Accessibility.StateType + """ + for state in states: + self.states.add(state) + + def remove(self, state): + """ + Removes states from this set. + + @param states: State(s) to remove + @type states: Accessibility.StateType + """ + self.states.remove(state) + + def equals(self, state_set): + """ + Checks if this StateSet contains exactly the same members as the given + StateSet. + + @param state_set: Another set + @type state_set: Accessibility.StateSet + @return: Are the sets equivalent in terms of their contents? + @rtype: boolean + """ + return set(state_set.getStates()) == self.states + + def compare(self, state_set): + """ + Finds the symmetric difference between this state set andthe one provided, + and returns it as a new StateSet. + + @note: This does not use L{_StateSetImpl.compare} which cannot be + implemented at this time + @param state_set: Set to compare against + @type state_set: Accessibility.StateSet + @return: Proxy for the new set + @rtype: L{StateSet} + """ + a = set(self.getStates()) + b = set(state_set.getStates()) + diff = a.symmetric_difference(b) + return StateSet(*diff) + + def isEmpty(self): + """ + Checks if this StateSet is empty. + + @return: Is it empty? + @rtype: boolean + """ + return len(self.states) == 0 + + def getStates(self): + """ + Gets the sequence of all states in this set. + + @return: List of states + @rtype: list + """ + return list(self.states) #END---------------------------------------------------------------------------- diff --git a/pyatspi/streamablecontent.py b/pyatspi/streamablecontent.py index e69f9f4..dc2273f 100644 --- a/pyatspi/streamablecontent.py +++ b/pyatspi/streamablecontent.py @@ -1,6 +1,6 @@ #Copyright (C) 2008 Codethink Ltd -#This library is free software; you can redistribute it and/or + #modify it under the terms of the GNU Lesser General Public #License version 2 as published by the Free Software Foundation. @@ -17,141 +17,130 @@ from base import BaseProxy, Enum from factory import add_accessible_class __all__ = [ - "ContentStream", - "StreamableContent", - ] + "ContentStream", + "StreamableContent", + ] #------------------------------------------------------------------------------ class ContentStream(BaseProxy): - """ - An interface by which the requested data from a StreamableContent - object may be read by the client. - """ - - def close(self, *args, **kwargs): - """ - close the stream and release associated resources. A client should - not perform further operations on a StreamableContent::Stream - object after closing it. - """ - func = self.get_dbus_method("close") - return func(*args, **kwargs) - - def read(self, *args, **kwargs): - """ - Request/read a specified amount of data from a Stream. - @return the number of bytes actually read into the client buffer. - """ - func = self.get_dbus_method("read") - return func(*args, **kwargs) - - def seek(self, *args, **kwargs): - """ - Seek to a specified position in the Stream. - @param : offset - an offset specifying the requested position in the stream, relative - to the SeekType specified in whence. - @param : whence - a SeekType specifying the reference point from which the seek - offset is calculated. Some forms of seek are not supported by - certain implementations of Stream, in which case a NotSupported - exception will be raised. - @return the actual resulting offset, if no exception was raised. - """ - func = self.get_dbus_method("seek") - return func(*args, **kwargs) - - class IOError(Exception): - pass - - class NoPermission(Exception): - pass - - class NotSupported(Exception): - pass - - class SeekType(Enum): """ - Specifies the meaning of a seek 'offset'. Not all SeekTypes are - supported by all StreamableContent data sources, for instance - some streams may not support seeking from the beginning or other - types of 'backwards' seeks. + An interface by which the requested data from a StreamableContent + object may be read by the client. """ - _enum_lookup = { - 0:'SEEK_SET', - 1:'SEEK_CURRENT', - 2:'SEEK_END', - } - - SEEK_CURRENT = SeekType(1) - - SEEK_END = SeekType(2) - - SEEK_SET = SeekType(0) + + def close(self, *args, **kwargs): + """ + close the stream and release associated resources. A client should + not perform further operations on a StreamableContent::Stream + object after closing it. + """ + func = self.get_dbus_method("close") + return func(*args, **kwargs) + + def read(self, *args, **kwargs): + """ + Request/read a specified amount of data from a Stream. + @return the number of bytes actually read into the client buffer. + """ + func = self.get_dbus_method("read") + return func(*args, **kwargs) + + def seek(self, *args, **kwargs): + """ + Seek to a specified position in the Stream. + @param : offset + an offset specifying the requested position in the stream, relative + to the SeekType specified in whence. + @param : whence + a SeekType specifying the reference point from which the seek + offset is calculated. Some forms of seek are not supported by + certain implementations of Stream, in which case a NotSupported + exception will be raised. + @return the actual resulting offset, if no exception was raised. + """ + func = self.get_dbus_method("seek") + return func(*args, **kwargs) + + class IOError(Exception): + pass + + class NoPermission(Exception): + pass + + class NotSupported(Exception): + pass + + class SeekType(Enum): + """ + Specifies the meaning of a seek 'offset'. Not all SeekTypes are + supported by all StreamableContent data sources, for instance + some streams may not support seeking from the beginning or other + types of 'backwards' seeks. + """ + _enum_lookup = { + 0:'SEEK_SET', + 1:'SEEK_CURRENT', + 2:'SEEK_END', + } + + SEEK_CURRENT = SeekType(1) + SEEK_END = SeekType(2) + SEEK_SET = SeekType(0) #------------------------------------------------------------------------------ class StreamableContent(BaseProxy): - """ - An interface whereby an object allows its backing content to - be streamed to clients. Negotiation of content type is allowed. - Clients may examine the backing data and transform, convert, - or parse the content in order to present it in an alternate form - to end-users. - """ - - def getContent(self, *args, **kwargs): - """ - DEPRECATED, use getStream instead. getContent: Retrieve this - object's content, in a format appropriate to a requested mimetype. - long Bonobo::Stream:seek (in long offset, in SeekType - whence) - raises (NoPermission, IOError) - void Bonobo::Stream:read (in long count, out iobuf buffer) - raises (NoPermission, IOError) - - @return a Bonobo::Stream whose mimetype matches contentType, - if available, or NIL. - """ - func = self.get_dbus_method("getContent") - return func(*args, **kwargs) - - def getContentTypes(self, *args, **kwargs): - """ - getContentTypes: - @return the list of available mimetypes for this object's content. - """ - func = self.get_dbus_method("getContentTypes") - return func(*args, **kwargs) - - def getStream(self, *args, **kwargs): - """ - Retrieve this object's content, in a format appropriate to a - requested mimetype, as a ContentStream instance. - @param : contentType - a string specifying the desired mimetype for the content stream. - @return a Stream whose mimetype matches contentType, if available, - or NIL. """ - func = self.get_dbus_method("getStream") - return func(*args, **kwargs) - - def getURI(self, *args, **kwargs): + An interface whereby an object allows its backing content to + be streamed to clients. Negotiation of content type is allowed. + Clients may examine the backing data and transform, convert, + or parse the content in order to present it in an alternate form + to end-users. """ - Get a URI pointing to the content of the specified type, if such - a URI can be obtained. Not all streamable content providers have - URI representations. - @param : contentType - a string specifying the desired mimetype for the content stream. - If NULL, then a URI for the default content type will be returned, - if available. - @return a string which constitutes a URI for a stream of the - specified content type, or NULL if no such URI can be obtained. - """ - func = self.get_dbus_method("getURI") - return func(*args, **kwargs) - + + def getContent(self, *args, **kwargs): + """ + DEPRECATED, use getStream instead. + """ + func = self.get_dbus_method("getContent") + return func(*args, **kwargs) + + def getContentTypes(self, *args, **kwargs): + """ + getContentTypes: + @return the list of available mimetypes for this object's content. + """ + func = self.get_dbus_method("getContentTypes") + return func(*args, **kwargs) + + def getStream(self, *args, **kwargs): + """ + Retrieve this object's content, in a format appropriate to a + requested mimetype, as a ContentStream instance. + @param : contentType + a string specifying the desired mimetype for the content stream. + @return a Stream whose mimetype matches contentType, if available, + or NIL. + """ + func = self.get_dbus_method("getStream") + return func(*args, **kwargs) + + def getURI(self, *args, **kwargs): + """ + Get a URI pointing to the content of the specified type, if such + a URI can be obtained. Not all streamable content providers have + URI representations. + @param : contentType + a string specifying the desired mimetype for the content stream. + If NULL, then a URI for the default content type will be returned, + if available. + @return a string which constitutes a URI for a stream of the + specified content type, or NULL if no such URI can be obtained. + """ + func = self.get_dbus_method("getURI") + return func(*args, **kwargs) + # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_STREAMABLE_CONTENT, StreamableContent) diff --git a/pyatspi/table.py b/pyatspi/table.py index 26cee38..cf86d8b 100644 --- a/pyatspi/table.py +++ b/pyatspi/table.py @@ -17,361 +17,361 @@ from base import BaseProxy from factory import add_accessible_class __all__ = [ - "Table", - ] + "Table", + ] #------------------------------------------------------------------------------ class Table(BaseProxy): - """ - An interface used by containers whose contained data is arranged - in a "tabular" (i.e. row-column) fashion. Tables may resemble - a two-dimensional grid, as in a spreadsheet, or may feature objects - which span multiple rows and/or columns, but whose bounds are - aligned on a row/column matrix. Thus, the Table interface may - be used to represent "spreadsheets" as well as "frames". - Objects within tables are children of the Table instance, and - they may be referenced either via a child index or via a row/column - pair. Their role may be ROLE_TABLE_CELL, but table 'cells' may - have other roles as well. These 'cells' may implement other interfaces, - such as Text, Action, Image, and Component, and should do so - as appropriate to their onscreen representation and/or behavior. - """ - - def addColumnSelection(self, *args, **kwargs): """ - Select the specified column, adding it to the current column - selection, if the table's selection model permits it. - @param : column - @return True if the specified column was successfully selected, - False if not. + An interface used by containers whose contained data is arranged + in a "tabular" (i.e. row-column) fashion. Tables may resemble + a two-dimensional grid, as in a spreadsheet, or may feature objects + which span multiple rows and/or columns, but whose bounds are + aligned on a row/column matrix. Thus, the Table interface may + be used to represent "spreadsheets" as well as "frames". + Objects within tables are children of the Table instance, and + they may be referenced either via a child index or via a row/column + pair. Their role may be ROLE_TABLE_CELL, but table 'cells' may + have other roles as well. These 'cells' may implement other interfaces, + such as Text, Action, Image, and Component, and should do so + as appropriate to their onscreen representation and/or behavior. """ - func = self.get_dbus_method("addColumnSelection") - return func(*args, **kwargs) - - def addRowSelection(self, *args, **kwargs): - """ - Select the specified row, adding it to the current row selection, - if the table's selection model permits it. - @param : row - @return True if the specified row was successfully selected, - False if not. - """ - func = self.get_dbus_method("addRowSelection") - return func(*args, **kwargs) - - def getAccessibleAt(self, *args, **kwargs): - """ - Get the table cell at the specified row and column indices. - @param : row - the specified table row, zero-indexed. - @param : column - the specified table column, zero-indexed. - @return an Accessible object representing the specified table - cell. - """ - func = self.get_dbus_method("getAccessibleAt") - return func(*args, **kwargs) - - def getColumnAtIndex(self, *args, **kwargs): - """ - Get the table column index occupied by the child at a particular - 1-D child index. - @param : index - the specified child index, zero-indexed. - @return a long integer indicating the first column spanned by - the child of a table, at the specified 1-D (zero-offset) index. - """ - func = self.get_dbus_method("getColumnAtIndex") - return func(*args, **kwargs) - - def getColumnDescription(self, *args, **kwargs): - """ - Get a text description of a particular table column. This differs - from AccessibleTable_getColumnHeader, which returns an Accessible. - @param : column - the specified table column, zero-indexed. - @return a UTF-8 string describing the specified table column, - if available. - """ - func = self.get_dbus_method("getColumnDescription") - return func(*args, **kwargs) - - def getColumnExtentAt(self, *args, **kwargs): - """ - Get the number of columns spanned by the table cell at the specific - row and column. (some tables can have cells which span multiple - rows and/or columns). - @param : row - the specified table row, zero-indexed. - @param : column - the specified table column, zero-indexed. - @return a long integer indicating the number of columns spanned - by the specified cell. - """ - func = self.get_dbus_method("getColumnExtentAt") - return func(*args, **kwargs) - - def getColumnHeader(self, *args, **kwargs): - """ - Get the header associated with a table column, if available, - as an instance of Accessible. This differs from getColumnDescription, - which returns a string. - @param : column - the specified table column, zero-indexed. - @return an Accessible representatin of the specified table column, - if available. - """ - func = self.get_dbus_method("getColumnHeader") - return func(*args, **kwargs) - - def getIndexAt(self, *args, **kwargs): - """ - Get the 1-D child index corresponding to the specified 2-D row - and column indices. - @param : row - the specified table row, zero-indexed. - @param : column - the specified table column, zero-indexed. - @return a long integer which serves as the index of a specified - cell in the table, in a form usable by Accessible::getChildAtIndex. - """ - func = self.get_dbus_method("getIndexAt") - return func(*args, **kwargs) - - def getRowAtIndex(self, *args, **kwargs): - """ - Get the table row index occupied by the child at a particular - 1-D child index. - @param : index - the specified child index, zero-indexed. - @return a long integer indicating the first row spanned by the - child of a table, at the specified 1-D (zero-offset) index. - """ - func = self.get_dbus_method("getRowAtIndex") - return func(*args, **kwargs) - - def getRowColumnExtentsAtIndex(self, *args, **kwargs): - """ - Given a child index, determine the row and column indices and - extents, and whether the cell is currently selected. If the child - at index is not a cell (for instance, if it is a summary, caption, - etc.), False is returned. - @param : index - the index of the Table child whose row/column extents are requested. - @param : row - back-filled with the first table row associated with the cell - with child index index. - @param : col - back-filled with the first table column associated with the cell - with child index index. - @param : row_extents - back-filled with the number of table rows across which child - i extends. - @param : col_extents - back-filled with the number of table columns across which child - i extends. - @param : is_selected - a boolean which is back-filled with True if the child at index - i corresponds to a selected table cell, False otherwise. - Example: If the Table child at index '6' extends across columns - 5 and 6 of row 2 of a Table instance, and is currently selected, - then retval=table::getRowColumnExtentsAtIndex(6,row,col, - row_extents, - col_extents, - is_selected); - will return True, and after the call row, col, row_extents, - col_extents, and is_selected will contain 2, 5, 1, 2, and True, - respectively. - @return True if the index is associated with a valid table cell, - False if the index does not correspond to a cell. If False is - returned, the values of the out parameters are undefined. - """ - func = self.get_dbus_method("getRowColumnExtentsAtIndex") - return func(*args, **kwargs) - - def getRowDescription(self, *args, **kwargs): - """ - Get a text description of a particular table row. This differs - from AccessibleTable_getRowHeader, which returns an Accessible. - @param : row - the specified table row, zero-indexed. - @return a UTF-8 string describing the specified table row, if - available. - """ - func = self.get_dbus_method("getRowDescription") - return func(*args, **kwargs) - - def getRowExtentAt(self, *args, **kwargs): - """ - Get the number of rows spanned by the table cell at the specific - row and column. (some tables can have cells which span multiple - rows and/or columns). - @param : row - the specified table row, zero-indexed. - @param : column - the specified table column, zero-indexed. - @return a long integer indicating the number of rows spanned - by the specified cell. - """ - func = self.get_dbus_method("getRowExtentAt") - return func(*args, **kwargs) - - def getRowHeader(self, *args, **kwargs): - """ - Get the header associated with a table row, if available. This - differs from getRowDescription, which returns a string. - @param : row - the specified table row, zero-indexed. - @return an Accessible representatin of the specified table row, - if available. - """ - func = self.get_dbus_method("getRowHeader") - return func(*args, **kwargs) - - def getSelectedColumns(self, *args, **kwargs): - """ - Obtain the indices of all columns which are currently selected. - @return a sequence of integers comprising the indices of columns - currently selected. - """ - func = self.get_dbus_method("getSelectedColumns") - return func(*args, **kwargs) - - def getSelectedRows(self, *args, **kwargs): - """ - Obtain the indices of all rows which are currently selected. - @return a sequence of integers comprising the indices of rows - currently selected. - """ - func = self.get_dbus_method("getSelectedRows") - return func(*args, **kwargs) - - def isColumnSelected(self, *args, **kwargs): - """ - Determine whether a table column is selected. - @param : column - the column being queried. - @return True if the specified column is currently selected, False - if not. - """ - func = self.get_dbus_method("isColumnSelected") - return func(*args, **kwargs) - - def isRowSelected(self, *args, **kwargs): - """ - Determine whether a table row is selected. - @param : row - the row being queried. - @return True if the specified row is currently selected, False - if not. - """ - func = self.get_dbus_method("isRowSelected") - return func(*args, **kwargs) - - def isSelected(self, *args, **kwargs): - """ - Determine whether the cell at a specific row and column is selected. - @param : row - a row occupied by the cell whose state is being queried. - @param : column - a column occupied by the cell whose state is being queried. - @return True if the specified cell is currently selected, False - if not. - """ - func = self.get_dbus_method("isSelected") - return func(*args, **kwargs) - - def removeColumnSelection(self, *args, **kwargs): - """ - Remove the specified column from current column selection, if - the table's selection model permits it. - @param : column - @return True if the specified column was successfully de-selected, - False if not. - """ - func = self.get_dbus_method("removeColumnSelection") - return func(*args, **kwargs) - - def removeRowSelection(self, *args, **kwargs): - """ - Remove the specified row from current row selection, if the table's - selection model permits it. - @param : row - @return True if the specified row was successfully de-selected, - False if not. - """ - func = self.get_dbus_method("removeRowSelection") - return func(*args, **kwargs) - - def get_caption(self): - return self._pgetter(self._dbus_interface, "caption") - def set_caption(self, value): - self._psetter(self._dbus_interface, "caption", value) - _captionDoc = \ - """ - An Accessible which represents of a caption for a Table. - """ - caption = property(fget=get_caption, fset=set_caption, doc=_captionDoc) - - def get_nColumns(self): - return self._pgetter(self._dbus_interface, "nColumns") - def set_nColumns(self, value): - self._psetter(self._dbus_interface, "nColumns", value) - _nColumnsDoc = \ - """ - The total number of columns in this table (including empty columns), - exclusive of columns which are programmatically hidden. Columns - which are scrolled out of view or clipped by the current viewport - are included. - """ - nColumns = property(fget=get_nColumns, fset=set_nColumns, doc=_nColumnsDoc) - - def get_nRows(self): - return self._pgetter(self._dbus_interface, "nRows") - def set_nRows(self, value): - self._psetter(self._dbus_interface, "nRows", value) - _nRowsDoc = \ - """ - The total number of rows in this table (including empty rows), - exclusive of any rows which are programmatically hidden. Rows - which are merely scrolled out of view are included. - """ - nRows = property(fget=get_nRows, fset=set_nRows, doc=_nRowsDoc) - - def get_nSelectedColumns(self): - return self._pgetter(self._dbus_interface, "nSelectedColumns") - def set_nSelectedColumns(self, value): - self._psetter(self._dbus_interface, "nSelectedColumns", value) - _nSelectedColumnsDoc = \ - """ - The number of columns currently selected. A selected column is - one in which all included cells are selected. - """ - nSelectedColumns = property(fget=get_nSelectedColumns, fset=set_nSelectedColumns, doc=_nSelectedColumnsDoc) - - def get_nSelectedRows(self): - return self._pgetter(self._dbus_interface, "nSelectedRows") - def set_nSelectedRows(self, value): - self._psetter(self._dbus_interface, "nSelectedRows", value) - _nSelectedRowsDoc = \ - """ - The number of rows currently selected. A selected row is one - in which all included cells are selected. - """ - nSelectedRows = property(fget=get_nSelectedRows, fset=set_nSelectedRows, doc=_nSelectedRowsDoc) - - def get_summary(self): - return self._pgetter(self._dbus_interface, "summary") - def set_summary(self, value): - self._psetter(self._dbus_interface, "summary", value) - _summaryDoc = \ - """ - An accessible object which summarizes the contents of a Table. - This object is frequently itself a Table instance, albeit a simplified - one. - """ - summary = property(fget=get_summary, fset=set_summary, doc=_summaryDoc) + + def addColumnSelection(self, *args, **kwargs): + """ + Select the specified column, adding it to the current column + selection, if the table's selection model permits it. + @param : column + @return True if the specified column was successfully selected, + False if not. + """ + func = self.get_dbus_method("addColumnSelection") + return func(*args, **kwargs) + + def addRowSelection(self, *args, **kwargs): + """ + Select the specified row, adding it to the current row selection, + if the table's selection model permits it. + @param : row + @return True if the specified row was successfully selected, + False if not. + """ + func = self.get_dbus_method("addRowSelection") + return func(*args, **kwargs) + + def getAccessibleAt(self, *args, **kwargs): + """ + Get the table cell at the specified row and column indices. + @param : row + the specified table row, zero-indexed. + @param : column + the specified table column, zero-indexed. + @return an Accessible object representing the specified table + cell. + """ + func = self.get_dbus_method("getAccessibleAt") + return func(*args, **kwargs) + + def getColumnAtIndex(self, *args, **kwargs): + """ + Get the table column index occupied by the child at a particular + 1-D child index. + @param : index + the specified child index, zero-indexed. + @return a long integer indicating the first column spanned by + the child of a table, at the specified 1-D (zero-offset) index. + """ + func = self.get_dbus_method("getColumnAtIndex") + return func(*args, **kwargs) + + def getColumnDescription(self, *args, **kwargs): + """ + Get a text description of a particular table column. This differs + from AccessibleTable_getColumnHeader, which returns an Accessible. + @param : column + the specified table column, zero-indexed. + @return a UTF-8 string describing the specified table column, + if available. + """ + func = self.get_dbus_method("getColumnDescription") + return func(*args, **kwargs) + + def getColumnExtentAt(self, *args, **kwargs): + """ + Get the number of columns spanned by the table cell at the specific + row and column. (some tables can have cells which span multiple + rows and/or columns). + @param : row + the specified table row, zero-indexed. + @param : column + the specified table column, zero-indexed. + @return a long integer indicating the number of columns spanned + by the specified cell. + """ + func = self.get_dbus_method("getColumnExtentAt") + return func(*args, **kwargs) + + def getColumnHeader(self, *args, **kwargs): + """ + Get the header associated with a table column, if available, + as an instance of Accessible. This differs from getColumnDescription, + which returns a string. + @param : column + the specified table column, zero-indexed. + @return an Accessible representatin of the specified table column, + if available. + """ + func = self.get_dbus_method("getColumnHeader") + return func(*args, **kwargs) + + def getIndexAt(self, *args, **kwargs): + """ + Get the 1-D child index corresponding to the specified 2-D row + and column indices. + @param : row + the specified table row, zero-indexed. + @param : column + the specified table column, zero-indexed. + @return a long integer which serves as the index of a specified + cell in the table, in a form usable by Accessible::getChildAtIndex. + """ + func = self.get_dbus_method("getIndexAt") + return func(*args, **kwargs) + + def getRowAtIndex(self, *args, **kwargs): + """ + Get the table row index occupied by the child at a particular + 1-D child index. + @param : index + the specified child index, zero-indexed. + @return a long integer indicating the first row spanned by the + child of a table, at the specified 1-D (zero-offset) index. + """ + func = self.get_dbus_method("getRowAtIndex") + return func(*args, **kwargs) + + def getRowColumnExtentsAtIndex(self, *args, **kwargs): + """ + Given a child index, determine the row and column indices and + extents, and whether the cell is currently selected. If the child + at index is not a cell (for instance, if it is a summary, caption, + etc.), False is returned. + @param : index + the index of the Table child whose row/column extents are requested. + @param : row + back-filled with the first table row associated with the cell + with child index index. + @param : col + back-filled with the first table column associated with the cell + with child index index. + @param : row_extents + back-filled with the number of table rows across which child + i extends. + @param : col_extents + back-filled with the number of table columns across which child + i extends. + @param : is_selected + a boolean which is back-filled with True if the child at index + i corresponds to a selected table cell, False otherwise. + Example: If the Table child at index '6' extends across columns + 5 and 6 of row 2 of a Table instance, and is currently selected, + then retval=table::getRowColumnExtentsAtIndex(6,row,col, + row_extents, + col_extents, + is_selected); + will return True, and after the call row, col, row_extents, + col_extents, and is_selected will contain 2, 5, 1, 2, and True, + respectively. + @return True if the index is associated with a valid table cell, + False if the index does not correspond to a cell. If False is + returned, the values of the out parameters are undefined. + """ + func = self.get_dbus_method("getRowColumnExtentsAtIndex") + return func(*args, **kwargs) + + def getRowDescription(self, *args, **kwargs): + """ + Get a text description of a particular table row. This differs + from AccessibleTable_getRowHeader, which returns an Accessible. + @param : row + the specified table row, zero-indexed. + @return a UTF-8 string describing the specified table row, if + available. + """ + func = self.get_dbus_method("getRowDescription") + return func(*args, **kwargs) + + def getRowExtentAt(self, *args, **kwargs): + """ + Get the number of rows spanned by the table cell at the specific + row and column. (some tables can have cells which span multiple + rows and/or columns). + @param : row + the specified table row, zero-indexed. + @param : column + the specified table column, zero-indexed. + @return a long integer indicating the number of rows spanned + by the specified cell. + """ + func = self.get_dbus_method("getRowExtentAt") + return func(*args, **kwargs) + + def getRowHeader(self, *args, **kwargs): + """ + Get the header associated with a table row, if available. This + differs from getRowDescription, which returns a string. + @param : row + the specified table row, zero-indexed. + @return an Accessible representatin of the specified table row, + if available. + """ + func = self.get_dbus_method("getRowHeader") + return func(*args, **kwargs) + + def getSelectedColumns(self, *args, **kwargs): + """ + Obtain the indices of all columns which are currently selected. + @return a sequence of integers comprising the indices of columns + currently selected. + """ + func = self.get_dbus_method("getSelectedColumns") + return func(*args, **kwargs) + + def getSelectedRows(self, *args, **kwargs): + """ + Obtain the indices of all rows which are currently selected. + @return a sequence of integers comprising the indices of rows + currently selected. + """ + func = self.get_dbus_method("getSelectedRows") + return func(*args, **kwargs) + + def isColumnSelected(self, *args, **kwargs): + """ + Determine whether a table column is selected. + @param : column + the column being queried. + @return True if the specified column is currently selected, False + if not. + """ + func = self.get_dbus_method("isColumnSelected") + return func(*args, **kwargs) + + def isRowSelected(self, *args, **kwargs): + """ + Determine whether a table row is selected. + @param : row + the row being queried. + @return True if the specified row is currently selected, False + if not. + """ + func = self.get_dbus_method("isRowSelected") + return func(*args, **kwargs) + + def isSelected(self, *args, **kwargs): + """ + Determine whether the cell at a specific row and column is selected. + @param : row + a row occupied by the cell whose state is being queried. + @param : column + a column occupied by the cell whose state is being queried. + @return True if the specified cell is currently selected, False + if not. + """ + func = self.get_dbus_method("isSelected") + return func(*args, **kwargs) + + def removeColumnSelection(self, *args, **kwargs): + """ + Remove the specified column from current column selection, if + the table's selection model permits it. + @param : column + @return True if the specified column was successfully de-selected, + False if not. + """ + func = self.get_dbus_method("removeColumnSelection") + return func(*args, **kwargs) + + def removeRowSelection(self, *args, **kwargs): + """ + Remove the specified row from current row selection, if the table's + selection model permits it. + @param : row + @return True if the specified row was successfully de-selected, + False if not. + """ + func = self.get_dbus_method("removeRowSelection") + return func(*args, **kwargs) + + def get_caption(self): + return self._pgetter(self._dbus_interface, "caption") + def set_caption(self, value): + self._psetter(self._dbus_interface, "caption", value) + _captionDoc = \ + """ + An Accessible which represents of a caption for a Table. + """ + caption = property(fget=get_caption, fset=set_caption, doc=_captionDoc) + + def get_nColumns(self): + return self._pgetter(self._dbus_interface, "nColumns") + def set_nColumns(self, value): + self._psetter(self._dbus_interface, "nColumns", value) + _nColumnsDoc = \ + """ + The total number of columns in this table (including empty columns), + exclusive of columns which are programmatically hidden. Columns + which are scrolled out of view or clipped by the current viewport + are included. + """ + nColumns = property(fget=get_nColumns, fset=set_nColumns, doc=_nColumnsDoc) + + def get_nRows(self): + return self._pgetter(self._dbus_interface, "nRows") + def set_nRows(self, value): + self._psetter(self._dbus_interface, "nRows", value) + _nRowsDoc = \ + """ + The total number of rows in this table (including empty rows), + exclusive of any rows which are programmatically hidden. Rows + which are merely scrolled out of view are included. + """ + nRows = property(fget=get_nRows, fset=set_nRows, doc=_nRowsDoc) + + def get_nSelectedColumns(self): + return self._pgetter(self._dbus_interface, "nSelectedColumns") + def set_nSelectedColumns(self, value): + self._psetter(self._dbus_interface, "nSelectedColumns", value) + _nSelectedColumnsDoc = \ + """ + The number of columns currently selected. A selected column is + one in which all included cells are selected. + """ + nSelectedColumns = property(fget=get_nSelectedColumns, fset=set_nSelectedColumns, doc=_nSelectedColumnsDoc) + + def get_nSelectedRows(self): + return self._pgetter(self._dbus_interface, "nSelectedRows") + def set_nSelectedRows(self, value): + self._psetter(self._dbus_interface, "nSelectedRows", value) + _nSelectedRowsDoc = \ + """ + The number of rows currently selected. A selected row is one + in which all included cells are selected. + """ + nSelectedRows = property(fget=get_nSelectedRows, fset=set_nSelectedRows, doc=_nSelectedRowsDoc) + + def get_summary(self): + return self._pgetter(self._dbus_interface, "summary") + def set_summary(self, value): + self._psetter(self._dbus_interface, "summary", value) + _summaryDoc = \ + """ + An accessible object which summarizes the contents of a Table. + This object is frequently itself a Table instance, albeit a simplified + one. + """ + summary = property(fget=get_summary, fset=set_summary, doc=_summaryDoc) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_TABLE, Table) diff --git a/pyatspi/test.py b/pyatspi/test.py index f82f0c3..a33cba8 100644 --- a/pyatspi/test.py +++ b/pyatspi/test.py @@ -18,39 +18,39 @@ from factory import create_accessible import interfaces __all__ = [ - "TestApplicationCache", - ] + "TestApplicationCache", + ] #------------------------------------------------------------------------------ class TestApplicationCache(object): - """ - Test application cache. Accesses single AccessibleCache. - """ - - def __init__(self, registry, connection, bus_name): - self._connection = connection - self._bus_name = bus_name - self._accessible_cache = AccessibleCache(registry, connection, bus_name) - - def __getitem__(self, key): - return self._accessible_cache - - def __contains__(self, key): - if key == self._bus_name: - return True - else: - return False - - def get_application_at_index(self, index, parent): - return create_accessible(self, - self._bus_name, - self._accessible_cache.root, - interfaces.ATSPI_ACCESSIBLE, - connection=self._connection, - parent=parent) - - def get_application_count(self): - return 1 + """ + Test application cache. Accesses single AccessibleCache. + """ + + def __init__(self, registry, connection, bus_name): + self._connection = connection + self._bus_name = bus_name + self._accessible_cache = AccessibleCache(registry, connection, bus_name) + + def __getitem__(self, key): + return self._accessible_cache + + def __contains__(self, key): + if key == self._bus_name: + return True + else: + return False + + def get_application_at_index(self, index, parent): + return create_accessible(self, + self._bus_name, + self._accessible_cache.root, + interfaces.ATSPI_ACCESSIBLE, + connection=self._connection, + parent=parent) + + def get_application_count(self): + return 1 #END---------------------------------------------------------------------------- diff --git a/pyatspi/text.py b/pyatspi/text.py index 41ddcd1..f2373ee 100644 --- a/pyatspi/text.py +++ b/pyatspi/text.py @@ -19,34 +19,34 @@ from base import BaseProxy, Enum from factory import add_accessible_class __all__ = [ - "Text", - "TEXT_BOUNDARY_TYPE", - "TEXT_BOUNDARY_CHAR", - "TEXT_BOUNDARY_WORD_START", - "TEXT_BOUNDARY_WORD_END", - "TEXT_BOUNDARY_SENTENCE_START", - "TEXT_BOUNDARY_SENTENCE_END", - "TEXT_BOUNDARY_LINE_START", - "TEXT_BOUNDARY_LINE_END", - "TEXT_CLIP_TYPE", - "TEXT_CLIP_NONE", - "TEXT_CLIP_MIN", - "TEXT_CLIP_MAX", - "TEXT_CLIP_BOTH", - ] + "Text", + "TEXT_BOUNDARY_TYPE", + "TEXT_BOUNDARY_CHAR", + "TEXT_BOUNDARY_WORD_START", + "TEXT_BOUNDARY_WORD_END", + "TEXT_BOUNDARY_SENTENCE_START", + "TEXT_BOUNDARY_SENTENCE_END", + "TEXT_BOUNDARY_LINE_START", + "TEXT_BOUNDARY_LINE_END", + "TEXT_CLIP_TYPE", + "TEXT_CLIP_NONE", + "TEXT_CLIP_MIN", + "TEXT_CLIP_MAX", + "TEXT_CLIP_BOTH", + ] #------------------------------------------------------------------------------ class TEXT_BOUNDARY_TYPE(Enum): - _enum_lookup = { - 0:'TEXT_BOUNDARY_CHAR', - 1:'TEXT_BOUNDARY_WORD_START', - 2:'TEXT_BOUNDARY_WORD_END', - 3:'TEXT_BOUNDARY_SENTENCE_START', - 4:'TEXT_BOUNDARY_SENTENCE_END', - 5:'TEXT_BOUNDARY_LINE_START', - 6:'TEXT_BOUNDARY_LINE_END', - } + _enum_lookup = { + 0:'TEXT_BOUNDARY_CHAR', + 1:'TEXT_BOUNDARY_WORD_START', + 2:'TEXT_BOUNDARY_WORD_END', + 3:'TEXT_BOUNDARY_SENTENCE_START', + 4:'TEXT_BOUNDARY_SENTENCE_END', + 5:'TEXT_BOUNDARY_LINE_START', + 6:'TEXT_BOUNDARY_LINE_END', + } TEXT_BOUNDARY_CHAR = TEXT_BOUNDARY_TYPE(0) TEXT_BOUNDARY_LINE_END = TEXT_BOUNDARY_TYPE(6) @@ -59,12 +59,12 @@ TEXT_BOUNDARY_WORD_START = TEXT_BOUNDARY_TYPE(1) #------------------------------------------------------------------------------ class TEXT_CLIP_TYPE(Enum): - _enum_lookup = { - 0:'TEXT_CLIP_NONE', - 1:'TEXT_CLIP_MIN', - 2:'TEXT_CLIP_MAX', - 3:'TEXT_CLIP_BOTH', - } + _enum_lookup = { + 0:'TEXT_CLIP_NONE', + 1:'TEXT_CLIP_MIN', + 2:'TEXT_CLIP_MAX', + 3:'TEXT_CLIP_BOTH', + } TEXT_CLIP_BOTH = TEXT_CLIP_TYPE(3) TEXT_CLIP_MAX = TEXT_CLIP_TYPE(2) @@ -74,496 +74,495 @@ TEXT_CLIP_NONE = TEXT_CLIP_TYPE(0) #------------------------------------------------------------------------------ class Text(BaseProxy): - """ - The text interface should be implemented by objects which place - textual information onscreen as character strings or glyphs. - The text interface allows access to textual content, including - display attributes and semantic hints associated with runs of - text, and access to bounding box information for glyphs and substrings. - It also allows portions of textual content to be selected, if - the object's StateSet includes STATE_SELECTABLE_TEXT. - In some cases a Text object may have, as its content, an empty - string. In particular this can occur in the case of Hypertext - objects which do not display explicitly textual information onscreen, - as Hypertext is derived from the Text interface. - Typographic and semantic attributes of onscreen textual content, - for instance typeface, weight, language, and such qualities as - 'emphasis' or 'blockquote', are represented as text attributes. - Contiguous sequences of characters over which these attributes - are unchanged are referred to as "attribute runs", and are available - via Text::getAttributeRun. Where possible, implementing clients - will report textual attributes which are the same over the entire - text object, for instance those inherited from a default or document-scope - style, via getDefaultAttributes instead of reporting them explicitly - for each character. Therefore, for any span of text, the attributes - in effect are the union of the set returned by Text::getDefaultAttributes, - and the set returned at a particular character offset via Text::getAttributeRun. - """ - - - def addSelection(self, *args, **kwargs): """ - The result of calling addSelection on objects which already have - one selection present, and which do not include STATE_MULTISELECTABLE, - is undefined, other than the return value. - @return True of the selection was successfully added, False otherwise. - Selection may fail if the object does not support selection of - text (see STATE_SELECTABLE_TEXT), if the object does not support - multiple selections and a selection is already defined, or for - other reasons (for instance if the user does not have permission - to copy the text into the relevant selection buffer). + The text interface should be implemented by objects which place + textual information onscreen as character strings or glyphs. + The text interface allows access to textual content, including + display attributes and semantic hints associated with runs of + text, and access to bounding box information for glyphs and substrings. + It also allows portions of textual content to be selected, if + the object's StateSet includes STATE_SELECTABLE_TEXT. + In some cases a Text object may have, as its content, an empty + string. In particular this can occur in the case of Hypertext + objects which do not display explicitly textual information onscreen, + as Hypertext is derived from the Text interface. + Typographic and semantic attributes of onscreen textual content, + for instance typeface, weight, language, and such qualities as + 'emphasis' or 'blockquote', are represented as text attributes. + Contiguous sequences of characters over which these attributes + are unchanged are referred to as "attribute runs", and are available + via Text::getAttributeRun. Where possible, implementing clients + will report textual attributes which are the same over the entire + text object, for instance those inherited from a default or document-scope + style, via getDefaultAttributes instead of reporting them explicitly + for each character. Therefore, for any span of text, the attributes + in effect are the union of the set returned by Text::getDefaultAttributes, + and the set returned at a particular character offset via Text::getAttributeRun. """ - func = self.get_dbus_method("addSelection") - return func(*args, **kwargs) - - def getAttributeRun(self, *args, **kwargs): - """ - Query a particular text object for the text attributes defined - at a given offset, obtaining the start and end of the "attribute - run" over which these attributes are currently invariant. Text - attributes are those presentational, typographic, or semantic - attributes or qualitites which apply to a range of text specifyable - by starting and ending offsets. Attributes relevant to localization - should be provided in accordance with the w3c "Internationalization - and Localization Markup Requirements", http://www.w3.org/TR/2005/WD-itsreq-20051122/ - Other text attributes should choose their names and value semantics - in accordance with relevant standards such as CSS level 2 (http://www.w3.org/TR/1998/REC-CSS2-19980512), - XHTML 1.0 (http://www.w3.org/TR/2002/REC-xhtml1-20020801), and - WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). Those attributes - from the aforementioned specifications and recommendations which - do not concern typographic, presentational, or semantic aspects - of text should be exposed via the more general Accessible::getAttributes() - API (if at all). - For example, CSS attributes which should be exposed on text (either - as default attributes, or as explicitly-set attributes when non-default - values are specified in the content view) include the Font attributes - (i.e. "css2:font-weight", "css2:font-style"), the "css2:color" - and "css2:background-color" attributes, and "css2:text-decoration" - attribute. - If includeDefaults is TRUE, then this AttributeSet should include - the default attributes as well as those which are explicitly - assigned to the attribute run in question. startOffset and endOffset - will be back-filled to indicate the start and end of the attribute - run which contains 'offset' - an attribute run is a contiguous - section of text whose attributes are homogeneous. - @param : offset - the offset of the character whose attributes will be reported. - @param : startOffset - backfilled with the starting offset of the character range over - which all text attributes match those of offset, i.e. the start - of the homogeneous attribute run including offset. - @param : endOffset - backfilled with the offset of the first character past the character - range over which all text attributes match those of offset, i.e. - the character immediately after the homogeneous attribute run - including offset. - @param : includeDefaults - if False, the call should only return those attributes which - are explicitly set on the current attribute run, omitting any - attributes which are inherited from the default values. See also - Text::getDefaultAttributes. - @return the AttributeSet defined at offset, optionally including - the 'default' attributes. - """ - func = self.get_dbus_method("getAttributeRun") - return func(*args, **kwargs) - - def getAttributeValue(self, *args, **kwargs): - """ - Get the string value of a named attribute at a given offset, - if defined. - @param : offset - the offset of the character for which the attribute run is to - be obtained. - @param : attributeName - the name of the attribute for which the value is to be returned, - if defined. - @param : startOffset - back-filled with the offset of the first character in the attribute - run containing the character at offset. - @param : endOffset - back-filled with the offset of the first character past the end - of the attribute run containing the character at offset. - @param : defined - back-filled with True if the attributeName has a defined value - at offset, False otherwise. - @return the value of attribute (name-value pair) corresponding - to "name", if defined. - """ - func = self.get_dbus_method("getAttributeValue") - return func(*args, **kwargs) - - def getAttributes(self, offset): - """ - getAttributes is deprecated in favor of getAttributeRun. - @return the attributes at offset, as a semicolon-delimited set - of colon-delimited name-value pairs. - """ - func = self.get_dbus_method("getAttributes") - return func(dbus.Int32(offset)) - - def getBoundedRanges(self, *args, **kwargs): - """ - Return the text content within a bounding box, as a list of Range - structures. Depending on the TEXT_CLIP_TYPE parameters, glyphs - which are clipped by the bounding box (i.e. which lie partially - inside and partially outside it) may or may not be included in - the ranges returned. - @param : x - the minimum x ( i.e. leftmost) coordinate of the bounding box. - @param : y - the minimum y coordinate of the bounding box. - @param : width - the horizontal size of the bounding box. The rightmost bound - of the bounding box is (x + width); - @param : height - the vertical size of the bounding box. The maximum y value of - the bounding box is (y + height); - @param : coordType - If 0, the above coordinates are interpreted as pixels relative - to corner of the screen; if 1, the coordinates are interpreted - as pixels relative to the corner of the containing toplevel window. - @param : xClipType - determines whether text which intersects the bounding box in - the x direction is included. - @param : yClipType - determines whether text which intersects the bounding box in - the y direction is included. - """ - func = self.get_dbus_method("getBoundedRanges") - return func(*args, **kwargs) - - def getCharacterAtOffset(self, *args, **kwargs): - """ - @return an unsigned long integer whose value corresponds to the - UCS-4 representation of the character at the specified text offset, - or 0 if offset is out of range. - """ - func = self.get_dbus_method("getCharacterAtOffset") - return func(*args, **kwargs) - - def getCharacterExtents(self, *args, **kwargs): - """ - Obtain a the bounding box, as x, y, width, and height, of the - character or glyph at a particular character offset in this object's - text content. The coordinate system in which the results are - reported is specified by coordType. If an onscreen glyph corresponds - to multiple character offsets, for instance if the glyph is a - ligature, the bounding box reported will include the entire glyph - and therefore may apply to more than one character offset. - @param : offset - the character offset of the character or glyph being queried. - @param : x - the minimum horizontal coordinate of the bounding box of the - glyph representing the character at offset. - @param : y - the minimum vertical coordinate of the bounding box of the glyph - representing the character at offset. - @param : width - the horizontal extent of the bounding box of the glyph representing - the character at offset. - @param : height - the vertical extent of the bounding box of the glyph representing - the character at offset. - @param : coordType - If 0, the results will be reported in screen coordinates, i.e. - in pixels relative to the upper-left corner of the screen, with - the x axis pointing right and the y axis pointing down. If 1, - the results will be reported relative to the containing toplevel - window, with the x axis pointing right and the y axis pointing - down. - """ - func = self.get_dbus_method("getCharacterExtents") - return func(*args, **kwargs) - - def getDefaultAttributeSet(self, *args, **kwargs): - """ - Return an AttributeSet containing the text attributes which apply - to all text in the object by virtue of the default settings of - the document, view, or user agent; e.g. those attributes which - are implied rather than explicitly applied to the text object. - For instance, an object whose entire text content has been explicitly - marked as 'bold' will report the 'bold' attribute via getAttributeRun(), - whereas an object whose text weight is inspecified may report - the default or implied text weight in the default AttributeSet. - """ - func = self.get_dbus_method("getDefaultAttributeSet") - return func(*args, **kwargs) - - def getDefaultAttributes(self, *args, **kwargs): - """ - Deprecated in favor of getDefaultAttributeSet. - @return the attributes which apply to the entire text content, - but which were not explicitly specified by the content creator. - """ - func = self.get_dbus_method("getDefaultAttributes") - return func(*args, **kwargs) - - def getNSelections(self, *args, **kwargs): - """ - Obtain the number of separate, contiguous selections in the current - Text object. Text objects which do not implement selection of - discontiguous text regions will always return '0' or '1'. Note - that "contiguous" is defined by continuity of the offsets, i.e. - a text 'selection' is defined by a start/end offset pair. In - the case of bidirectional text, this means that a continguous - selection may appear visually discontiguous, and vice-versa. - @return the number of contiguous selections in the current Text - object. - """ - func = self.get_dbus_method("getNSelections") - return func(*args, **kwargs) - - def getOffsetAtPoint(self, *args, **kwargs): - """ - Get the offset of the character at a given onscreen coordinate. - The coordinate system used to interpret x and y is determined - by parameter coordType. - @param : x - @param : y - @param : coordType - if 0, the input coordinates are interpreted relative to the entire - screen, if 1, they are relative to the toplevel window containing - this Text object. - @return the text offset (as an offset into the character array) - of the glyph whose onscreen bounds contain the point x,y, or - -1 if the point is outside the bounds of any glyph. - """ - func = self.get_dbus_method("getOffsetAtPoint") - return func(*args, **kwargs) - - def getRangeExtents(self, *args, **kwargs): - """ - Obtain the bounding box which entirely contains a given text - range. Negative values may be returned for the bounding box parameters - in the event that all or part of the text range is offscreen - or not mapped to the screen. - @param : startOffset - the offset of the first character in the specified range. - @param : endOffset - the offset of the character immediately after the last character - in the specified range. - @param : x - an integer parameter which is back-filled with the minimum horizontal - coordinate of the resulting bounding box. - @param : y - an integer parameter which is back-filled with the minimum vertical - coordinate of the resulting bounding box. - @param : width - an integer parameter which is back-filled with the horizontal - extent of the bounding box. - @param : height - an integer parameter which is back-filled with the vertical extent - of the bounding box. - @param : coordType - If 0, the above coordinates are reported in pixels relative to - corner of the screen; if 1, the coordinates are reported relative - to the corner of the containing toplevel window. - """ - func = self.get_dbus_method("getRangeExtents") - return func(*args, **kwargs) - - def getSelection(self, *args, **kwargs): - """ - The result of calling getSelection with an out-of-range selectionNum - (i.e. for a selection which does not exist) is not strictly defined, - but should set endOffset equal to startOffset. - """ - func = self.get_dbus_method("getSelection") - return func(*args, **kwargs) - - def getText(self, startOffset, endOffset): - """ - Obtain all or part of the onscreen textual content of a Text - object. If endOffset is specified as "-1", then this method will - return the entire onscreen textual contents of the Text object. - @return the textual content of the current Text object beginning - startOffset (inclusive) up to but not including the character - at endOffset. - """ - func = self.get_dbus_method("getText") - if not endOffset: - endOffset = -1 - return func(dbus.Int32(startOffset), dbus.Int32(endOffset)) - - def getTextAfterOffset(self, *args, **kwargs): - """ - Obtain a subset of the text content of an object which entirely - follows offset, delimited by character, word, line, or sentence - boundaries as specified by type. The starting and ending offsets - of the resulting substring are returned in startOffset and endOffset. - By definition, if such a substring exists, startOffset must be - greater than offset. - @param : offset - the offset from which the substring search begins, and which - must lie before the returned substring. - @param : type - the text-boundary delimiter which determines whether the returned - text constitures a character, word, line, or sentence (and possibly - attendant whitespace), and whether the start or ending of such - a substring forms the boundary condition. - @param : startOffset - back-filled with the starting offset of the resulting substring, - if one exists. - @param : endOffset - back-filled with the offset of the character immediately following - the resulting substring, if one exists. - @return a string which is a substring of the text content of - the object, delimited by the specified boundary condition. - """ - func = self.get_dbus_method("getTextAfterOffset") - return func(*args, **kwargs) - - def getTextAtOffset(self, *args, **kwargs): - """ - Obtain a subset of the text content of an object which includes - the specified offset, delimited by character, word, line, or - sentence boundaries as specified by type. The starting and ending - offsets of the resulting substring are returned in startOffset - and endOffset. - @param : offset - the offset from which the substring search begins, and which - must lie within the returned substring. - @param : type - the text-boundary delimiter which determines whether the returned - text constitures a character, word, line, or sentence (and possibly - attendant whitespace), and whether the start or ending of such - a substring forms the boundary condition. - @param : startOffset - back-filled with the starting offset of the resulting substring, - if one exists. - @param : endOffset - back-filled with the offset of the character immediately following - the resulting substring, if one exists. - @return a string which is a substring of the text content of - the object, delimited by the specified boundary condition. - """ - func = self.get_dbus_method("getTextAtOffset") - return func(*args, **kwargs) - - def getTextBeforeOffset(self, *args, **kwargs): - """ - Obtain a subset of the text content of an object which entirely - precedes offset, delimited by character, word, line, or sentence - boundaries as specified by type. The starting and ending offsets - of the resulting substring are returned in startOffset and endOffset. - By definition, if such a substring exists, endOffset is less - than or equal to offset. - @param : offset - the offset from which the substring search begins. - @param : type - the text-boundary delimiter which determines whether the returned - text constitures a character, word, line, or sentence (and possibly - attendant whitespace), and whether the start or ending of such - a substring forms the boundary condition. - @param : startOffset - back-filled with the starting offset of the resulting substring, - if one exists. - @param : endOffset - back-filled with the offset of the character immediately following - the resulting substring, if one exists. - @return a string which is a substring of the text content of - the object, delimited by the specified boundary condition. - """ - func = self.get_dbus_method("getTextBeforeOffset") - return func(*args, **kwargs) - - def removeSelection(self, *args, **kwargs): - """ - Deselect the text contained in the specified selectionNum, if - such a selection exists, otherwise do nothing. Removal of a non-existant - selectionNum has no effect. - @return True if the selection was successfully removed, False - otherwise. - """ - func = self.get_dbus_method("removeSelection") - return func(*args, **kwargs) - - def setCaretOffset(self, *args, **kwargs): - """ - Programmatically move the text caret (visible or virtual, as - above) to a given position. - @param : offset - a long int indicating the desired character offset. Not all implementations - of Text will honor setCaretOffset requests, so the return value - below should be checked by the client. - @return TRUE if the request was carried out, or FALSE if the - caret could not be moved to the requested position. - """ - func = self.get_dbus_method("setCaretOffset") - return func(*args, **kwargs) - - def setSelection(self, *args, **kwargs): - """ - Modify an existing selection's start or ending offset. - Calling setSelection for a selectionNum that is not already defined - has no effect. The result of calling setSelection with a selectionNum - greater than 0 for objects that do not include STATE_MULTISELECTABLE - is undefined. - @param : selectionNum - indicates which of a set of non-contiguous selections to modify. - @param : startOffset - the new starting offset for the selection - @param : endOffset - the new ending offset for the selection - @return True if the selection corresponding to selectionNum is - successfully modified, False otherwise. - """ - func = self.get_dbus_method("setSelection") - return func(*args, **kwargs) - - def get_caretOffset(self): - return self._pgetter(self._dbus_interface, "caretOffset") - def set_caretOffset(self, value): - self._psetter(self._dbus_interface, "caretOffset", value) - _caretOffsetDoc = \ - """ - The current offset of the text caret in the Text object. This - caret may be virtual, e.g. non-visual and notional-only, but - if an onscreen representation of the caret position is visible, - it will correspond to this offset. The caret offset is given - as a character offset, as opposed to a byte offset into a text - buffer or a column offset. - """ - caretOffset = property(fget=get_caretOffset, fset=set_caretOffset, doc=_caretOffsetDoc) - - def get_characterCount(self): - return self._pgetter(self._dbus_interface, "characterCount") - def set_characterCount(self, value): - self._psetter(self._dbus_interface, "characterCount", value) - _characterCountDoc = \ - """ - The total current number of characters in the Text object, including - whitespace and non-spacing characters. - """ - characterCount = property(fget=get_characterCount, fset=set_characterCount, doc=_characterCountDoc) - - class Range(list): - def __new__(cls, startOffset, endOffset, content, data): - list.__new__(cls, (startOffset, endOffset, content, data)) - def __init__(self, startOffset, endOffset, content, data): - list.__init__(self, (startOffset, endOffset, content, data)) - - def _get_startOffset(self): - return self[0] - def _set_startOffset(self, val): - self[0] = val - startOffset = property(fget=_get_startOffset, fset=_set_startOffset) - def _get_endOffset(self): - return self[1] - def _set_endOffset(self, val): - self[1] = val - endOffset = property(fget=_get_endOffset, fset=_set_endOffset) - def _get_content(self): - return self[2] - def _set_content(self, val): - self[2] = val - content = property(fget=_get_content, fset=_set_content) - def _get_data(self): - return self[3] - def _set_data(self, val): - self[3] = val - data = property(fget=_get_data, fset=_set_data) + + def addSelection(self, *args, **kwargs): + """ + The result of calling addSelection on objects which already have + one selection present, and which do not include STATE_MULTISELECTABLE, + is undefined, other than the return value. + @return True of the selection was successfully added, False otherwise. + Selection may fail if the object does not support selection of + text (see STATE_SELECTABLE_TEXT), if the object does not support + multiple selections and a selection is already defined, or for + other reasons (for instance if the user does not have permission + to copy the text into the relevant selection buffer). + """ + func = self.get_dbus_method("addSelection") + return func(*args, **kwargs) + + def getAttributeRun(self, *args, **kwargs): + """ + Query a particular text object for the text attributes defined + at a given offset, obtaining the start and end of the "attribute + run" over which these attributes are currently invariant. Text + attributes are those presentational, typographic, or semantic + attributes or qualitites which apply to a range of text specifyable + by starting and ending offsets. Attributes relevant to localization + should be provided in accordance with the w3c "Internationalization + and Localization Markup Requirements", http://www.w3.org/TR/2005/WD-itsreq-20051122/ + Other text attributes should choose their names and value semantics + in accordance with relevant standards such as CSS level 2 (http://www.w3.org/TR/1998/REC-CSS2-19980512), + XHTML 1.0 (http://www.w3.org/TR/2002/REC-xhtml1-20020801), and + WICD (http://www.w3.org/TR/2005/WD-WICD-20051121/). Those attributes + from the aforementioned specifications and recommendations which + do not concern typographic, presentational, or semantic aspects + of text should be exposed via the more general Accessible::getAttributes() + API (if at all). + For example, CSS attributes which should be exposed on text (either + as default attributes, or as explicitly-set attributes when non-default + values are specified in the content view) include the Font attributes + (i.e. "css2:font-weight", "css2:font-style"), the "css2:color" + and "css2:background-color" attributes, and "css2:text-decoration" + attribute. + If includeDefaults is TRUE, then this AttributeSet should include + the default attributes as well as those which are explicitly + assigned to the attribute run in question. startOffset and endOffset + will be back-filled to indicate the start and end of the attribute + run which contains 'offset' - an attribute run is a contiguous + section of text whose attributes are homogeneous. + @param : offset + the offset of the character whose attributes will be reported. + @param : startOffset + backfilled with the starting offset of the character range over + which all text attributes match those of offset, i.e. the start + of the homogeneous attribute run including offset. + @param : endOffset + backfilled with the offset of the first character past the character + range over which all text attributes match those of offset, i.e. + the character immediately after the homogeneous attribute run + including offset. + @param : includeDefaults + if False, the call should only return those attributes which + are explicitly set on the current attribute run, omitting any + attributes which are inherited from the default values. See also + Text::getDefaultAttributes. + @return the AttributeSet defined at offset, optionally including + the 'default' attributes. + """ + func = self.get_dbus_method("getAttributeRun") + return func(*args, **kwargs) + + def getAttributeValue(self, *args, **kwargs): + """ + Get the string value of a named attribute at a given offset, + if defined. + @param : offset + the offset of the character for which the attribute run is to + be obtained. + @param : attributeName + the name of the attribute for which the value is to be returned, + if defined. + @param : startOffset + back-filled with the offset of the first character in the attribute + run containing the character at offset. + @param : endOffset + back-filled with the offset of the first character past the end + of the attribute run containing the character at offset. + @param : defined + back-filled with True if the attributeName has a defined value + at offset, False otherwise. + @return the value of attribute (name-value pair) corresponding + to "name", if defined. + """ + func = self.get_dbus_method("getAttributeValue") + return func(*args, **kwargs) + + def getAttributes(self, offset): + """ + getAttributes is deprecated in favor of getAttributeRun. + @return the attributes at offset, as a semicolon-delimited set + of colon-delimited name-value pairs. + """ + func = self.get_dbus_method("getAttributes") + return func(dbus.Int32(offset)) + + def getBoundedRanges(self, *args, **kwargs): + """ + Return the text content within a bounding box, as a list of Range + structures. Depending on the TEXT_CLIP_TYPE parameters, glyphs + which are clipped by the bounding box (i.e. which lie partially + inside and partially outside it) may or may not be included in + the ranges returned. + @param : x + the minimum x ( i.e. leftmost) coordinate of the bounding box. + @param : y + the minimum y coordinate of the bounding box. + @param : width + the horizontal size of the bounding box. The rightmost bound + of the bounding box is (x + width); + @param : height + the vertical size of the bounding box. The maximum y value of + the bounding box is (y + height); + @param : coordType + If 0, the above coordinates are interpreted as pixels relative + to corner of the screen; if 1, the coordinates are interpreted + as pixels relative to the corner of the containing toplevel window. + @param : xClipType + determines whether text which intersects the bounding box in + the x direction is included. + @param : yClipType + determines whether text which intersects the bounding box in + the y direction is included. + """ + func = self.get_dbus_method("getBoundedRanges") + return func(*args, **kwargs) + + def getCharacterAtOffset(self, *args, **kwargs): + """ + @return an unsigned long integer whose value corresponds to the + UCS-4 representation of the character at the specified text offset, + or 0 if offset is out of range. + """ + func = self.get_dbus_method("getCharacterAtOffset") + return func(*args, **kwargs) + + def getCharacterExtents(self, *args, **kwargs): + """ + Obtain a the bounding box, as x, y, width, and height, of the + character or glyph at a particular character offset in this object's + text content. The coordinate system in which the results are + reported is specified by coordType. If an onscreen glyph corresponds + to multiple character offsets, for instance if the glyph is a + ligature, the bounding box reported will include the entire glyph + and therefore may apply to more than one character offset. + @param : offset + the character offset of the character or glyph being queried. + @param : x + the minimum horizontal coordinate of the bounding box of the + glyph representing the character at offset. + @param : y + the minimum vertical coordinate of the bounding box of the glyph + representing the character at offset. + @param : width + the horizontal extent of the bounding box of the glyph representing + the character at offset. + @param : height + the vertical extent of the bounding box of the glyph representing + the character at offset. + @param : coordType + If 0, the results will be reported in screen coordinates, i.e. + in pixels relative to the upper-left corner of the screen, with + the x axis pointing right and the y axis pointing down. If 1, + the results will be reported relative to the containing toplevel + window, with the x axis pointing right and the y axis pointing + down. + """ + func = self.get_dbus_method("getCharacterExtents") + return func(*args, **kwargs) + + def getDefaultAttributeSet(self, *args, **kwargs): + """ + Return an AttributeSet containing the text attributes which apply + to all text in the object by virtue of the default settings of + the document, view, or user agent; e.g. those attributes which + are implied rather than explicitly applied to the text object. + For instance, an object whose entire text content has been explicitly + marked as 'bold' will report the 'bold' attribute via getAttributeRun(), + whereas an object whose text weight is inspecified may report + the default or implied text weight in the default AttributeSet. + """ + func = self.get_dbus_method("getDefaultAttributeSet") + return func(*args, **kwargs) + + def getDefaultAttributes(self, *args, **kwargs): + """ + Deprecated in favor of getDefaultAttributeSet. + @return the attributes which apply to the entire text content, + but which were not explicitly specified by the content creator. + """ + func = self.get_dbus_method("getDefaultAttributes") + return func(*args, **kwargs) + + def getNSelections(self, *args, **kwargs): + """ + Obtain the number of separate, contiguous selections in the current + Text object. Text objects which do not implement selection of + discontiguous text regions will always return '0' or '1'. Note + that "contiguous" is defined by continuity of the offsets, i.e. + a text 'selection' is defined by a start/end offset pair. In + the case of bidirectional text, this means that a continguous + selection may appear visually discontiguous, and vice-versa. + @return the number of contiguous selections in the current Text + object. + """ + func = self.get_dbus_method("getNSelections") + return func(*args, **kwargs) + + def getOffsetAtPoint(self, *args, **kwargs): + """ + Get the offset of the character at a given onscreen coordinate. + The coordinate system used to interpret x and y is determined + by parameter coordType. + @param : x + @param : y + @param : coordType + if 0, the input coordinates are interpreted relative to the entire + screen, if 1, they are relative to the toplevel window containing + this Text object. + @return the text offset (as an offset into the character array) + of the glyph whose onscreen bounds contain the point x,y, or + -1 if the point is outside the bounds of any glyph. + """ + func = self.get_dbus_method("getOffsetAtPoint") + return func(*args, **kwargs) + + def getRangeExtents(self, *args, **kwargs): + """ + Obtain the bounding box which entirely contains a given text + range. Negative values may be returned for the bounding box parameters + in the event that all or part of the text range is offscreen + or not mapped to the screen. + @param : startOffset + the offset of the first character in the specified range. + @param : endOffset + the offset of the character immediately after the last character + in the specified range. + @param : x + an integer parameter which is back-filled with the minimum horizontal + coordinate of the resulting bounding box. + @param : y + an integer parameter which is back-filled with the minimum vertical + coordinate of the resulting bounding box. + @param : width + an integer parameter which is back-filled with the horizontal + extent of the bounding box. + @param : height + an integer parameter which is back-filled with the vertical extent + of the bounding box. + @param : coordType + If 0, the above coordinates are reported in pixels relative to + corner of the screen; if 1, the coordinates are reported relative + to the corner of the containing toplevel window. + """ + func = self.get_dbus_method("getRangeExtents") + return func(*args, **kwargs) + + def getSelection(self, *args, **kwargs): + """ + The result of calling getSelection with an out-of-range selectionNum + (i.e. for a selection which does not exist) is not strictly defined, + but should set endOffset equal to startOffset. + """ + func = self.get_dbus_method("getSelection") + return func(*args, **kwargs) + + def getText(self, startOffset, endOffset): + """ + Obtain all or part of the onscreen textual content of a Text + object. If endOffset is specified as "-1", then this method will + return the entire onscreen textual contents of the Text object. + @return the textual content of the current Text object beginning + startOffset (inclusive) up to but not including the character + at endOffset. + """ + func = self.get_dbus_method("getText") + if not endOffset: + endOffset = -1 + return func(dbus.Int32(startOffset), dbus.Int32(endOffset)) + + def getTextAfterOffset(self, *args, **kwargs): + """ + Obtain a subset of the text content of an object which entirely + follows offset, delimited by character, word, line, or sentence + boundaries as specified by type. The starting and ending offsets + of the resulting substring are returned in startOffset and endOffset. + By definition, if such a substring exists, startOffset must be + greater than offset. + @param : offset + the offset from which the substring search begins, and which + must lie before the returned substring. + @param : type + the text-boundary delimiter which determines whether the returned + text constitures a character, word, line, or sentence (and possibly + attendant whitespace), and whether the start or ending of such + a substring forms the boundary condition. + @param : startOffset + back-filled with the starting offset of the resulting substring, + if one exists. + @param : endOffset + back-filled with the offset of the character immediately following + the resulting substring, if one exists. + @return a string which is a substring of the text content of + the object, delimited by the specified boundary condition. + """ + func = self.get_dbus_method("getTextAfterOffset") + return func(*args, **kwargs) + + def getTextAtOffset(self, *args, **kwargs): + """ + Obtain a subset of the text content of an object which includes + the specified offset, delimited by character, word, line, or + sentence boundaries as specified by type. The starting and ending + offsets of the resulting substring are returned in startOffset + and endOffset. + @param : offset + the offset from which the substring search begins, and which + must lie within the returned substring. + @param : type + the text-boundary delimiter which determines whether the returned + text constitures a character, word, line, or sentence (and possibly + attendant whitespace), and whether the start or ending of such + a substring forms the boundary condition. + @param : startOffset + back-filled with the starting offset of the resulting substring, + if one exists. + @param : endOffset + back-filled with the offset of the character immediately following + the resulting substring, if one exists. + @return a string which is a substring of the text content of + the object, delimited by the specified boundary condition. + """ + func = self.get_dbus_method("getTextAtOffset") + return func(*args, **kwargs) + + def getTextBeforeOffset(self, *args, **kwargs): + """ + Obtain a subset of the text content of an object which entirely + precedes offset, delimited by character, word, line, or sentence + boundaries as specified by type. The starting and ending offsets + of the resulting substring are returned in startOffset and endOffset. + By definition, if such a substring exists, endOffset is less + than or equal to offset. + @param : offset + the offset from which the substring search begins. + @param : type + the text-boundary delimiter which determines whether the returned + text constitures a character, word, line, or sentence (and possibly + attendant whitespace), and whether the start or ending of such + a substring forms the boundary condition. + @param : startOffset + back-filled with the starting offset of the resulting substring, + if one exists. + @param : endOffset + back-filled with the offset of the character immediately following + the resulting substring, if one exists. + @return a string which is a substring of the text content of + the object, delimited by the specified boundary condition. + """ + func = self.get_dbus_method("getTextBeforeOffset") + return func(*args, **kwargs) + + def removeSelection(self, *args, **kwargs): + """ + Deselect the text contained in the specified selectionNum, if + such a selection exists, otherwise do nothing. Removal of a non-existant + selectionNum has no effect. + @return True if the selection was successfully removed, False + otherwise. + """ + func = self.get_dbus_method("removeSelection") + return func(*args, **kwargs) + + def setCaretOffset(self, *args, **kwargs): + """ + Programmatically move the text caret (visible or virtual, as + above) to a given position. + @param : offset + a long int indicating the desired character offset. Not all implementations + of Text will honor setCaretOffset requests, so the return value + below should be checked by the client. + @return TRUE if the request was carried out, or FALSE if the + caret could not be moved to the requested position. + """ + func = self.get_dbus_method("setCaretOffset") + return func(*args, **kwargs) + + def setSelection(self, *args, **kwargs): + """ + Modify an existing selection's start or ending offset. + Calling setSelection for a selectionNum that is not already defined + has no effect. The result of calling setSelection with a selectionNum + greater than 0 for objects that do not include STATE_MULTISELECTABLE + is undefined. + @param : selectionNum + indicates which of a set of non-contiguous selections to modify. + @param : startOffset + the new starting offset for the selection + @param : endOffset + the new ending offset for the selection + @return True if the selection corresponding to selectionNum is + successfully modified, False otherwise. + """ + func = self.get_dbus_method("setSelection") + return func(*args, **kwargs) + + def get_caretOffset(self): + return self._pgetter(self._dbus_interface, "caretOffset") + def set_caretOffset(self, value): + self._psetter(self._dbus_interface, "caretOffset", value) + _caretOffsetDoc = \ + """ + The current offset of the text caret in the Text object. This + caret may be virtual, e.g. non-visual and notional-only, but + if an onscreen representation of the caret position is visible, + it will correspond to this offset. The caret offset is given + as a character offset, as opposed to a byte offset into a text + buffer or a column offset. + """ + caretOffset = property(fget=get_caretOffset, fset=set_caretOffset, doc=_caretOffsetDoc) + + def get_characterCount(self): + return self._pgetter(self._dbus_interface, "characterCount") + def set_characterCount(self, value): + self._psetter(self._dbus_interface, "characterCount", value) + _characterCountDoc = \ + """ + The total current number of characters in the Text object, including + whitespace and non-spacing characters. + """ + characterCount = property(fget=get_characterCount, fset=set_characterCount, doc=_characterCountDoc) + + class Range(list): + def __new__(cls, startOffset, endOffset, content, data): + list.__new__(cls, (startOffset, endOffset, content, data)) + def __init__(self, startOffset, endOffset, content, data): + list.__init__(self, (startOffset, endOffset, content, data)) + + def _get_startOffset(self): + return self[0] + def _set_startOffset(self, val): + self[0] = val + startOffset = property(fget=_get_startOffset, fset=_set_startOffset) + def _get_endOffset(self): + return self[1] + def _set_endOffset(self, val): + self[1] = val + endOffset = property(fget=_get_endOffset, fset=_set_endOffset) + def _get_content(self): + return self[2] + def _set_content(self, val): + self[2] = val + content = property(fget=_get_content, fset=_set_content) + def _get_data(self): + return self[3] + def _set_data(self, val): + self[3] = val + data = property(fget=_get_data, fset=_set_data) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_TEXT, Text) diff --git a/pyatspi/utils.py b/pyatspi/utils.py index 8d3b7cc..fb7cfba 100644 --- a/pyatspi/utils.py +++ b/pyatspi/utils.py @@ -24,308 +24,308 @@ import state import registry __all__ = [ - "setCacheLevel", - "getCacheLevel", - "clearCache", - "printCache", - "getInterfaceIID", - "getInterfaceName", - "listInterfaces", - "stringToConst", - "stateToString", - "stateToString", - "allModifiers", - "findDescendant", - "findAllDescendants", - "findAncestor", - "getPath", - ] + "setCacheLevel", + "getCacheLevel", + "clearCache", + "printCache", + "getInterfaceIID", + "getInterfaceName", + "listInterfaces", + "stringToConst", + "stateToString", + "stateToString", + "allModifiers", + "findDescendant", + "findAllDescendants", + "findAncestor", + "getPath", + ] def setCacheLevel(level): - pass + pass def getCacheLevel(): - return None + return None def clearCache(): - pass + pass def printCache(): - print "Print cache function is deprecated"; + print "Print cache function is deprecated"; def getInterfaceIID(obj): - """ - Gets the ID of an interface class or object in string format for use in - queryInterface. - - @param obj: Class representing an AT-SPI interface or instance - @type obj: object - @return: IID for the interface - @rtype: string - @raise AttributeError: When the parameter does not provide typecode info - - WARNING!! DEPRECATED!! - - In current D-Bus version of pyatspi this simply returns a null string. - """ - return "" + """ + Gets the ID of an interface class or object in string format for use in + queryInterface. + + @param obj: Class representing an AT-SPI interface or instance + @type obj: object + @return: IID for the interface + @rtype: string + @raise AttributeError: When the parameter does not provide typecode info + + WARNING!! DEPRECATED!! + + In current D-Bus version of pyatspi this simply returns a null string. + """ + return "" def getInterfaceName(obj): - """ - Gets the human readable name of an interface class or object in string - format. - - @param obj: Class representing an AT-SPI interface or instance - @type obj: class - @return: Name of the interface - @rtype: string - @raise AttributeError: When the parameter does not provide typecode info - """ - return obj._dbus_interface.lstrip("org.freedesktop.atspi.") + """ + Gets the human readable name of an interface class or object in string + format. + + @param obj: Class representing an AT-SPI interface or instance + @type obj: class + @return: Name of the interface + @rtype: string + @raise AttributeError: When the parameter does not provide typecode info + """ + return obj._dbus_interface.lstrip("org.freedesktop.atspi.") def listInterfaces(obj): - """ - Gets a list of the names of all interfaces supported by this object. The - names are the short-hand interface names like "Accessible" and "Component", - not the full interface identifiers. - - @param obj: Arbitrary object to query for all accessibility related - interfaces. Must provide a queryInterface method. - @type obj: object - @return: Set of supported interface names - @rtype: set - @raise AttributeError: If the object provide does not implement - queryInterface - """ - return [itf.lstrip("org.freedesktop.atspi.") for itf in obj.interfaces] + """ + Gets a list of the names of all interfaces supported by this object. The + names are the short-hand interface names like "Accessible" and "Component", + not the full interface identifiers. + + @param obj: Arbitrary object to query for all accessibility related + interfaces. Must provide a queryInterface method. + @type obj: object + @return: Set of supported interface names + @rtype: set + @raise AttributeError: If the object provide does not implement + queryInterface + """ + return [itf.lstrip("org.freedesktop.atspi.") for itf in obj.interfaces] def stringToConst(prefix, suffix): - """ - Maps a string name to an AT-SPI constant. The rules for the mapping are as - follows: - - The prefix is captalized and has an _ appended to it. - - All spaces in the suffix are mapped to the _ character. - - All alpha characters in the suffix are mapped to their uppercase. - - The resulting name is used with getattr to look up a constant with that name - in the L{constants} module. If such a constant does not exist, the string - suffix is returned instead. - - This method allows strings to be used to refer to roles, relations, etc. - without direct access to the constants. It also supports the future expansion - of roles, relations, etc. by allowing arbitrary strings which may or may not - map to the current standard set of roles, relations, etc., but may still - match some non-standard role, relation, etc. being reported by an - application. - - @param prefix: Prefix of the constant name such as role, relation, state, - text, modifier, key - @type prefix: string - @param suffix: Name of the role, relation, etc. to use to lookup the constant - @type suffix: string - @return: The matching constant value - @rtype: object - """ - name = prefix.upper()+'_'+suffix.upper().replace(' ', '_') - return getattr(constants, name, suffix) + """ + Maps a string name to an AT-SPI constant. The rules for the mapping are as + follows: + - The prefix is captalized and has an _ appended to it. + - All spaces in the suffix are mapped to the _ character. + - All alpha characters in the suffix are mapped to their uppercase. + + The resulting name is used with getattr to look up a constant with that name + in the L{constants} module. If such a constant does not exist, the string + suffix is returned instead. + + This method allows strings to be used to refer to roles, relations, etc. + without direct access to the constants. It also supports the future expansion + of roles, relations, etc. by allowing arbitrary strings which may or may not + map to the current standard set of roles, relations, etc., but may still + match some non-standard role, relation, etc. being reported by an + application. + + @param prefix: Prefix of the constant name such as role, relation, state, + text, modifier, key + @type prefix: string + @param suffix: Name of the role, relation, etc. to use to lookup the constant + @type suffix: string + @return: The matching constant value + @rtype: object + """ + name = prefix.upper()+'_'+suffix.upper().replace(' ', '_') + return getattr(constants, name, suffix) def stateToString(value): - """ - Converts a state value to a string based on the name of the state constant in - the L{constants} module that has the given value. - - @param value: An AT-SPI state - @type value: Accessibility.StateType - @return: Human readable, untranslated name of the state - @rtype: string - """ - return state.STATE_VALUE_TO_NAME.get(value) + """ + Converts a state value to a string based on the name of the state constant in + the L{constants} module that has the given value. + + @param value: An AT-SPI state + @type value: Accessibility.StateType + @return: Human readable, untranslated name of the state + @rtype: string + """ + return state.STATE_VALUE_TO_NAME.get(value) def relationToString(value): - """ - Converts a relation value to a string based on the name of the state constant - in the L{constants} module that has the given value. - - @param value: An AT-SPI relation - @type value: Accessibility.RelationType - @return: Human readable, untranslated name of the relation - @rtype: string - """ - return relation.RELATION_VALUE_TO_NAME.get(value) + """ + Converts a relation value to a string based on the name of the state constant + in the L{constants} module that has the given value. + + @param value: An AT-SPI relation + @type value: Accessibility.RelationType + @return: Human readable, untranslated name of the relation + @rtype: string + """ + return relation.RELATION_VALUE_TO_NAME.get(value) def allModifiers(): - """ - Generates all possible keyboard modifiers for use with - L{registry.Registry.registerKeystrokeListener}. - """ - mask = 0 - while mask <= (1 << registry.MODIFIER_NUMLOCK): - yield mask - mask += 1 + """ + Generates all possible keyboard modifiers for use with + L{registry.Registry.registerKeystrokeListener}. + """ + mask = 0 + while mask <= (1 << registry.MODIFIER_NUMLOCK): + yield mask + mask += 1 def findDescendant(acc, pred, breadth_first=False): - """ - Searches for a descendant node satisfying the given predicate starting at - this node. The search is performed in depth-first order by default or - in breadth first order if breadth_first is True. For example, - - my_win = findDescendant(lambda x: x.name == 'My Window') - - will search all descendants of x until one is located with the name 'My - Window' or all nodes are exausted. Calls L{_findDescendantDepth} or - L{_findDescendantBreadth} to start the recursive search. - - @param acc: Root accessible of the search - @type acc: Accessibility.Accessible - @param pred: Search predicate returning True if accessible matches the - search criteria or False otherwise - @type pred: callable - @param breadth_first: Search breadth first (True) or depth first (False)? - @type breadth_first: boolean - @return: Accessible matching the criteria or None if not found - @rtype: Accessibility.Accessible or None - """ - if breadth_first: - return _findDescendantBreadth(acc, pred) - - for child in acc: - try: - ret = _findDescendantDepth(acc, pred) - except Exception: - ret = None - if ret is not None: return ret + """ + Searches for a descendant node satisfying the given predicate starting at + this node. The search is performed in depth-first order by default or + in breadth first order if breadth_first is True. For example, + + my_win = findDescendant(lambda x: x.name == 'My Window') + + will search all descendants of x until one is located with the name 'My + Window' or all nodes are exausted. Calls L{_findDescendantDepth} or + L{_findDescendantBreadth} to start the recursive search. + + @param acc: Root accessible of the search + @type acc: Accessibility.Accessible + @param pred: Search predicate returning True if accessible matches the + search criteria or False otherwise + @type pred: callable + @param breadth_first: Search breadth first (True) or depth first (False)? + @type breadth_first: boolean + @return: Accessible matching the criteria or None if not found + @rtype: Accessibility.Accessible or None + """ + if breadth_first: + return _findDescendantBreadth(acc, pred) + + for child in acc: + try: + ret = _findDescendantDepth(acc, pred) + except Exception: + ret = None + if ret is not None: return ret def _findDescendantBreadth(acc, pred): - """ - Internal function for locating one descendant. Called by L{findDescendant} to - start the search. - - @param acc: Root accessible of the search - @type acc: Accessibility.Accessible - @param pred: Search predicate returning True if accessible matches the - search criteria or False otherwise - @type pred: callable - @return: Matching node or None to keep searching - @rtype: Accessibility.Accessible or None - """ - for child in acc: - try: - if pred(child): return child - except Exception: - pass - for child in acc: - try: - ret = _findDescendantBreadth(child, pred) - except Exception: - ret = None - if ret is not None: return ret + """ + Internal function for locating one descendant. Called by L{findDescendant} to + start the search. + + @param acc: Root accessible of the search + @type acc: Accessibility.Accessible + @param pred: Search predicate returning True if accessible matches the + search criteria or False otherwise + @type pred: callable + @return: Matching node or None to keep searching + @rtype: Accessibility.Accessible or None + """ + for child in acc: + try: + if pred(child): return child + except Exception: + pass + for child in acc: + try: + ret = _findDescendantBreadth(child, pred) + except Exception: + ret = None + if ret is not None: return ret def _findDescendantDepth(acc, pred): - """ - Internal function for locating one descendant. Called by L{findDescendant} to - start the search. - - @param acc: Root accessible of the search - @type acc: Accessibility.Accessible - @param pred: Search predicate returning True if accessible matches the - search criteria or False otherwise - @type pred: callable - @return: Matching node or None to keep searching - @rtype: Accessibility.Accessible or None - """ - try: - if pred(acc): return acc - except Exception: - pass - for child in acc: - try: - ret = _findDescendantDepth(child, pred) - except Exception: - ret = None - if ret is not None: return ret - + """ + Internal function for locating one descendant. Called by L{findDescendant} to + start the search. + + @param acc: Root accessible of the search + @type acc: Accessibility.Accessible + @param pred: Search predicate returning True if accessible matches the + search criteria or False otherwise + @type pred: callable + @return: Matching node or None to keep searching + @rtype: Accessibility.Accessible or None + """ + try: + if pred(acc): return acc + except Exception: + pass + for child in acc: + try: + ret = _findDescendantDepth(child, pred) + except Exception: + ret = None + if ret is not None: return ret + def findAllDescendants(acc, pred): - """ - Searches for all descendant nodes satisfying the given predicate starting at - this node. Does an in-order traversal. For example, - - pred = lambda x: x.getRole() == pyatspi.ROLE_PUSH_BUTTON - buttons = pyatspi.findAllDescendants(node, pred) - - will locate all push button descendants of node. - - @param acc: Root accessible of the search - @type acc: Accessibility.Accessible - @param pred: Search predicate returning True if accessible matches the - search criteria or False otherwise - @type pred: callable - @return: All nodes matching the search criteria - @rtype: list - """ - matches = [] - _findAllDescendants(acc, pred, matches) - return matches + """ + Searches for all descendant nodes satisfying the given predicate starting at + this node. Does an in-order traversal. For example, + + pred = lambda x: x.getRole() == pyatspi.ROLE_PUSH_BUTTON + buttons = pyatspi.findAllDescendants(node, pred) + + will locate all push button descendants of node. + + @param acc: Root accessible of the search + @type acc: Accessibility.Accessible + @param pred: Search predicate returning True if accessible matches the + search criteria or False otherwise + @type pred: callable + @return: All nodes matching the search criteria + @rtype: list + """ + matches = [] + _findAllDescendants(acc, pred, matches) + return matches def _findAllDescendants(acc, pred, matches): - """ - Internal method for collecting all descendants. Reuses the same matches - list so a new one does not need to be built on each recursive step. - """ - for child in acc: - try: - if pred(child): matches.append(child) - except Exception: - pass - _findAllDescendants(child, pred, matches) - + """ + Internal method for collecting all descendants. Reuses the same matches + list so a new one does not need to be built on each recursive step. + """ + for child in acc: + try: + if pred(child): matches.append(child) + except Exception: + pass + _findAllDescendants(child, pred, matches) + def findAncestor(acc, pred): - """ - Searches for an ancestor satisfying the given predicate. Note that the - AT-SPI hierarchy is not always doubly linked. Node A may consider node B its - child, but B is not guaranteed to have node A as its parent (i.e. its parent - may be set to None). This means some searches may never make it all the way - up the hierarchy to the desktop level. - - @param acc: Starting accessible object - @type acc: Accessibility.Accessible - @param pred: Search predicate returning True if accessible matches the - search criteria or False otherwise - @type pred: callable - @return: Node matching the criteria or None if not found - @rtype: Accessibility.Accessible - """ - if acc is None: - # guard against bad start condition - return None - while 1: - if acc.parent is None: - # stop if there is no parent and we haven't returned yet - return None - try: - if pred(acc.parent): return acc.parent - except Exception: - pass - # move to the parent - acc = acc.parent + """ + Searches for an ancestor satisfying the given predicate. Note that the + AT-SPI hierarchy is not always doubly linked. Node A may consider node B its + child, but B is not guaranteed to have node A as its parent (i.e. its parent + may be set to None). This means some searches may never make it all the way + up the hierarchy to the desktop level. + + @param acc: Starting accessible object + @type acc: Accessibility.Accessible + @param pred: Search predicate returning True if accessible matches the + search criteria or False otherwise + @type pred: callable + @return: Node matching the criteria or None if not found + @rtype: Accessibility.Accessible + """ + if acc is None: + # guard against bad start condition + return None + while 1: + if acc.parent is None: + # stop if there is no parent and we haven't returned yet + return None + try: + if pred(acc.parent): return acc.parent + except Exception: + pass + # move to the parent + acc = acc.parent def getPath(acc): - """ - Gets the path from the application ancestor to the given accessible in - terms of its child index at each level. - - @param acc: Target accessible - @type acc: Accessibility.Accessible - @return: Path to the target - @rtype: list of integer - @raise LookupError: When the application accessible cannot be reached - """ - path = [] - while 1: - if acc.parent is None: - path.reverse() - return path - try: - path.append(acc.getIndexInParent()) - except Exception: - raise LookupError - acc = acc.parent + """ + Gets the path from the application ancestor to the given accessible in + terms of its child index at each level. + + @param acc: Target accessible + @type acc: Accessibility.Accessible + @return: Path to the target + @rtype: list of integer + @raise LookupError: When the application accessible cannot be reached + """ + path = [] + while 1: + if acc.parent is None: + path.reverse() + return path + try: + path.append(acc.getIndexInParent()) + except Exception: + raise LookupError + acc = acc.parent diff --git a/pyatspi/value.py b/pyatspi/value.py index 6f931df..8f75cef 100644 --- a/pyatspi/value.py +++ b/pyatspi/value.py @@ -17,60 +17,60 @@ from base import BaseProxy from factory import add_accessible_class __all__ = [ - "Value", - ] + "Value", + ] #------------------------------------------------------------------------------ class Value(BaseProxy): - """ - An interface supporting controls which allow a one-dimensional, - scalar quantity to be modified or which reflect a scalar quantity. - (If STATE_EDITABLE is not present, the valuator is treated as - "read only". - """ - - def get_currentValue(self): - return self._pgetter(self._dbus_interface, "currentValue") - def set_currentValue(self, value): - self._psetter(self._dbus_interface, "currentValue", value) - _currentValueDoc = \ - """ - The current value of the valuator. - """ - currentValue = property(fget=get_currentValue, fset=set_currentValue, doc=_currentValueDoc) - - def get_maximumValue(self): - return self._pgetter(self._dbus_interface, "maximumValue") - def set_maximumValue(self, value): - self._psetter(self._dbus_interface, "maximumValue", value) - _maximumValueDoc = \ - """ - The maximum value allowed by this valuator. - """ - maximumValue = property(fget=get_maximumValue, fset=set_maximumValue, doc=_maximumValueDoc) - - def get_minimumIncrement(self): - return self._pgetter(self._dbus_interface, "minimumIncrement") - def set_minimumIncrement(self, value): - self._psetter(self._dbus_interface, "minimumIncrement", value) - _minimumIncrementDoc = \ - """ - The smallest incremental change which this valuator allows. If - 0, the incremental changes to the valuator are limited only by - the precision of a double precision value on the platform. """ - minimumIncrement = property(fget=get_minimumIncrement, fset=set_minimumIncrement, doc=_minimumIncrementDoc) - - def get_minimumValue(self): - return self._pgetter(self._dbus_interface, "minimumValue") - def set_minimumValue(self, value): - self._psetter(self._dbus_interface, "minimumValue", value) - _minimumValueDoc = \ + An interface supporting controls which allow a one-dimensional, + scalar quantity to be modified or which reflect a scalar quantity. + (If STATE_EDITABLE is not present, the valuator is treated as + "read only". """ - The minimum value allowed by this valuator. - """ - minimumValue = property(fget=get_minimumValue, fset=set_minimumValue, doc=_minimumValueDoc) + + def get_currentValue(self): + return self._pgetter(self._dbus_interface, "currentValue") + def set_currentValue(self, value): + self._psetter(self._dbus_interface, "currentValue", value) + _currentValueDoc = \ + """ + The current value of the valuator. + """ + currentValue = property(fget=get_currentValue, fset=set_currentValue, doc=_currentValueDoc) + + def get_maximumValue(self): + return self._pgetter(self._dbus_interface, "maximumValue") + def set_maximumValue(self, value): + self._psetter(self._dbus_interface, "maximumValue", value) + _maximumValueDoc = \ + """ + The maximum value allowed by this valuator. + """ + maximumValue = property(fget=get_maximumValue, fset=set_maximumValue, doc=_maximumValueDoc) + + def get_minimumIncrement(self): + return self._pgetter(self._dbus_interface, "minimumIncrement") + def set_minimumIncrement(self, value): + self._psetter(self._dbus_interface, "minimumIncrement", value) + _minimumIncrementDoc = \ + """ + The smallest incremental change which this valuator allows. If + 0, the incremental changes to the valuator are limited only by + the precision of a double precision value on the platform. + """ + minimumIncrement = property(fget=get_minimumIncrement, fset=set_minimumIncrement, doc=_minimumIncrementDoc) + + def get_minimumValue(self): + return self._pgetter(self._dbus_interface, "minimumValue") + def set_minimumValue(self, value): + self._psetter(self._dbus_interface, "minimumValue", value) + _minimumValueDoc = \ + """ + The minimum value allowed by this valuator. + """ + minimumValue = property(fget=get_minimumValue, fset=set_minimumValue, doc=_minimumValueDoc) # ATTENTION - Register the Application class with the accessible factory. add_accessible_class(interfaces.ATSPI_VALUE, Value) -- 2.7.4