LibreOffice Developer's Guide: Chapter 17 - Accessibility

From The Document Foundation Wiki
Jump to navigation Jump to search

There are certain circumstances where LibreOffice applications can not be used with the usual input and output devices, such as a mouse, keyboard, monitor and printer. This may be because the user is sitting in a car and can only occasionally look at the screen and has no keyboard at all. Maybe the user is disabled and can not see or hear or use traditional keyboards. Alternative input and output devices are called assistive technology, or AT. Examples of AT are Braille terminals, which are used mainly for display of single text lines where each character is represented by raised or lowered dots and can be read by touching them with the fingertips, screen magnifiers, which magnify the screen contents and optionally change color, and screen readers, which use speech synthesis to read displayed text or descriptions of objects out loud in a human language.

To make LibreOffice applications accessible to the disabled or to people in mobile environments, alternative input and output devices have to be supported. In order to support a wide variety of ATs, the approach taken by Java and Gnome has been adopted: an API tailored to the specific needs of AT and modeled closely after its Java counterpart is used as an interface between the available data of the elements visible on screen and the AT, which transforms that data and presents an alternative view of the screen contents.

Overview

As previously stated, the UNO Accessibility API, or UAA, is closely modeled after the Java Accessibility API, and to some extent the Gnome Accessibility API. This section describes some differences with common UNO styles and standards.

The purpose of the accessibility API is to represent what is currently visible on screen. To be kept up-to-date, users of the accessibility API are informed of any relevant changes of the screen content by events. This focus on visual appearance is another point in which the accessibility API differs from other parts of UNO, which are strictly model centered. The accessibility API provides a tree structure or, to be more specific, a forest of accessibility objects that, as a whole, represent the on-screen data.

The transition point from the UNO API to the accessibility API is windows, which both support the <idl>com.sun.star.awt.XWindow</idl> and <idl>com.sun.star.accessibility.XAccessible</idl> interfaces. A list of all top-level windows, from which you can get the roots of the associated accessibility trees, can be retrieved from the toolkit through the <idl>com.sun.star.awt.XExtendedToolkit</idl> interface.

The <idl>com.sun.star.accessibility.XAccessible</idl> interface can be queried for the actual accessibility object with its only function <idlm>com.sun.star.accessibility.XAccessible:getAccessibleContext</idlm>(). With this technique, the implementations of the accessibility interfaces can be kept apart from that of the other UNO interfaces. The <idlm>com.sun.star.accessibility.XAccessible:getAccessibleContext</idlm>() function returns a reference to an object that implements the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface. This interface is the center of the accessibility API. On the one hand it provides the functionality to traverse the accessibility tree and on the other hand gives access to basic information that represents the object that is being made accessible. These two aspects are described in more detail in the following sections Accessibility Tree and Content Information.

The accessibility API is as self-contained as possible. You should not need to use the UNO API outside its accessibility API subset. However, there are some exceptions to this. The most important one is the initial access to the root nodes of the accessibility tree over the toolkit.

Bridges

There are several ways that ATs can be realized. They differ in two important points. The first one is how the AT represents the information it obtains from LibreOffice and presents it to the user. The second difference is how ATs obtain this information in the first place.

In its simplest form, the communication between AT and LibreOffice involves only the accessibility API and, where necessary, some additional features from other parts of the UNO API. Existing ATs, however, do not know anything yet about the accessibility API. They use one of several ways to access LibreOffice by using one or more bridges that translate between different APIs:

  • The UNO access bridge translates between the accessibility API and the Java Accessibility API. Note that this is not the same as the Java version of the accessibility API.
  • The Windows/Java access bridge translates between the Java and the C versions of the Java Accessibility API.
  • The Gnome access bridge translates between the accessibility API and the Gnome Accessibility API.

In order to make LibreOffice accessible, it is necessary to support the accessibility API. The characteristics of the bridges have to be taken into account as well.

Under Windows, LibreOffice itself has a switch that can turn on or off the accessibility support. This switch can be reached through Tools – Options – Accessibility. Under Linux and Solaris, an equivalent setting can be made in the Gnome environment. When accessibility is activated, on every launch LibreOffice will start its own Java VM, which in turn starts all registered AT tools. This will be explained in the next section.

Accessibility Tree

The screen content is presented to AT as a tree - or a forest, to be more specific - of accessibility objects. Each displayed object that wants to be accessible has to support the <idl>com.sun.star.accessibility.XAccessible</idl> interface. From this interface, you obtain the actual accessibility object by calling the <idlm>com.sun.star.accessibility.XAccessible:getAccessibleContext</idlm>() function. The returned object has to at least support the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface.

Accessibility objects are organized in one or more hierarchies, one for each top-level window. So there is a tree for a single top-level window, and a forest when there is more than one top-level window. Internal nodes of a tree are containers of other accessibility objects. A container can represent window frames, toolbars, menus, group shapes, or shapes that contain text. Leaves represent objects like menu entries without sub-menus, buttons, icons, shapes without text, or text paragraphs.

You can move up and down within the tree of a given accessibility object. All functions for obtaining an object's parent and children are part of the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface. The ability to move up towards the tree root is provided by the <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleParent</idlm>() function. Like all other accessibility functions that return a reference to another accessibility object, it returns a reference to a <idl>com.sun.star.accessibility.XAccessible</idl> object. Moving down the tree towards the leaves requires two functions. The <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChildCount</idlm>() function returns the number of children. The <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChild</idlm>() function allows you to access any child by specifying the appropriate index.

Warning.svg

Warning:
Between the call to <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChildCount</idlm>() and the final <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChild</idlm>() call (when accessing all children one after the other) the number of children may have changed. You can keep track of the number of children by registering as listener and waiting for <idlm>com.sun.star.accessibility.AccessibleEventId:CHILD</idlm> events. Additionally, you have to cope with <idl>com.sun.star.lang.IndexOutOfBoundsException</idl> exceptions that denote bad indices.


When children are added or removed from an accessibility object, the indices of the new and remaining children may change. You can use the <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleIndexInParent</idlm>() function to get the current indices.

Content Information

Content information of accessibility objects establishes the connection to the objects that are visible on the screen. This information gives a detailed description of what is visible on the screen, the size of the object, and its location on the screen. Access to the content information is provided by several interfaces of the UNO accessibility API, which are described in the following sections.

The accessibility API allows you to divide the implementation of an accessible object into an accessibility related and an accessibility unrelated part. This is done with the <idl>com.sun.star.accessibility.XAccessible</idl> interface. The <idlm>com.sun.star.accessibility.XAccessible:getAccessibleContext</idlm>() method returns an object that implements the other interfaces related to accessibility. This object may be the same as the object that is made accessible, but it can be a different object as well. Once you have the accessibility object, you can use the usual UNO type cast mechanisms to change from one interface to another.

Listeners and Broadcasters

The <idl>com.sun.star.accessibility.XAccessibleEventBroadcaster</idl> and <idl>com.sun.star.accessibility.XAccessibleEventListener</idl> interface combo lets you register and unregister listeners. Events are represented by <idl>com.sun.star.accessibility.AccessibleEventObject</idl> structure. The different event types are listed and explained in the <idl>com.sun.star.accessibility.AccessibleEventId</idl> constants group.

Again, event types can be divided into two classes depending on whether they describe changes in the structure of the accessibility tree or changes in the internal state or the visual appearance of an accessible object. The first group consists of <idlm>com.sun.star.accessibility.AccessibleEventId:CHILD</idlm> and <idlm>com.sun.star.accessibility.AccessibleEventId:INVALIDATE_ALL_CHILDREN</idlm>. The first denotes a newly inserted or a removed child. The second is used in cases where more than one child has been inserted or removed and tells the listener to re-fetch a complete list of children.

The second group comprises all other event types. Typical members are <idlm>com.sun.star.accessibility.AccessibleEventId:VISIBLE_DATA_CHANGED</idlm> and <idlm>com.sun.star.accessibility.AccessibleEventId:STATE_CHANGED</idlm>, which inform listeners that the visual appearance of an object has changed (for example, to a different text color) or that one of its states has been switched on or off (for example, when an object becomes focused or selected).

The event types <idlm>com.sun.star.accessibility.AccessibleEventId:CONTROLLED_BY_RELATION_CHANGED</idlm>, <idlm>com.sun.star.accessibility.AccessibleEventId:CONTROLLER_FOR_RELATION_CHANGED</idlm>, <idlm>com.sun.star.accessibility.AccessibleEventId:LABEL_FOR_RELATION_CHANGED</idlm>, <idlm>com.sun.star.accessibility.AccessibleEventId:LABELED_BY_RELATION_CHANGED</idlm>, <idlm>com.sun.star.accessibility.AccessibleEventId:MEMBER_OF_RELATION_CHANGED</idlm>, <idlm>com.sun.star.accessibility.AccessibleEventId:CONTENT_FLOWS_FROM_RELATION_CHANGED</idlm> and <idlm>com.sun.star.accessibility.AccessibleEventId:CONTENT_FLOWS_TO_RELATION_CHANGED</idlm> may be thought of as constituting a third group. They describe changes of the more virtual structure formed by relations between accessible objects in different parts of an accessibility tree.

Events are sent after the respective change of an accessible object took place. This enables the listener to retrieve up-to-date values that are sent with the event.

Note pin.svg

Note:
A problem arises when the number of children becomes very large, as with Calc tables where the number of cells in a sheet is huge. Registering at every cell certainly is not an option. The solution to this problem is the introduction of the <idlm>com.sun.star.accessibility.AccessibleStateType:TRANSIENT</idlm> state, which tells an AT not to register but to expect <idlm>com.sun.star.accessibility.AccessibleEventId:ACTIVE_DESCENDANT_CHANGED</idlm> events sent from their parent. To prevent the AT from having to ask every child whether it is transient, the parent must set the <idlm>com.sun.star.accessibility.AccessibleStateType:MANAGES_DESCENDANTS</idlm> state.

Implementing Accessible Objects

Implementation Rules

There are some rules to observe when implementing the UNO accessibility API that go beyond simply following the specifications in the IDL files of the accessibility API's interfaces. These rules have to do with what kind of data ATs expect from an application.

One such rule is that only objects that are visible on the screen are included into the accessibility tree. If, for example, you have a text document with a large number of pages, usually only parts of one or two pages are visible, and only accessibility objects for these parts should be part of the accessibility hierarchy. Another closely related rule is that the bounding boxes of objects are clipped to the visible area.

However, there are exceptions to these rules. For reasons of consistency with the behavior of Java tables represented through the <idl>com.sun.star.accessibility.XAccessibleTable</idl> interface, access is granted to all of their cells regardless of whether they are visible or not. Menus are another example. The whole menu structure is represented, even when only the menu bar is visible.

Another rule is that bounding boxes of accessibility objects as returned by <idlm>com.sun.star.accessibility.XAccessibleComponent:getBounds</idlm>() must not overlap the bounding boxes of their parents. This is crucial to enable ATs to find the accessibility object that lies under a given screen coordinate, such as the mouse position. With properly nesting bounding boxes, ATs can prune whole sub-trees from the search when the bounding box of the root object does not contain the point.

Services

There are only two services in the accessibility API, which have to be supported by any accessible object.

The <idl>com.sun.star.accessibility.Accessible</idl> service contains the <idl>com.sun.star.accessibility.XAccessible</idl> interface and must be supported by every UNO object that is accessible.

The <idl>com.sun.star.accessibility.AccessibleContext</idl> service contains the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface and, optionally, the <idl>com.sun.star.accessibility.XAccessibleEventBroadcaster</idl> interface. This service must be supported by every accessible object that is returned by the <idlm>com.sun.star.accessibility.XAccessible:getAccessibleContext</idlm>() function.

Using the Accessibility API

When you are writing your own ATs and want to use the UNO accessibility API directly, you must first connect to LibreOffice. Connecting to LibreOffice is explained elsewhere in this document. Once a connection is established, the toolkit with its <idl>com.sun.star.awt.XExtendedToolkit</idl> interface can be used to retrieve a list of all currently open top-level windows. From these, you can then get the accessible root nodes of the accessibility object trees associated with the windows. When you register a <idl>com.sun.star.awt.XTopWindowListener</idl> you will then be informed about new top-level windows, as well as top-level windows that have disappeared.

With the top-level accessible objects at hand, you can use the Java version of the accessibility API as it is described in detail in the following sections. To be informed about focus changes - so that, for example, a screen reader can track the currently focused object and read it to the user - an AT has to register all non-transient objects of an accessibility tree.

The general operation of a simple AT consists of the following steps:

  1. Connect to LibreOffice.
  2. Retrieve the currently visible top-level windows and register as top window listener to keep the list up-to-date.
  3. Traverse the trees by getting their root elements from each window. See the description of the <idl>com.sun.star.accessibility.XAccessibleContext</idl> for a code example for this.
  4. Register each accessible object as <idl>com.sun.star.accessibility.XAccessibleEventListener</idl>.
  5. If called back with an <idl>com.sun.star.accessibility.AccessibleEventObject</idl> object, then process two kinds of events:
    • Events that denote a state change with either <idlm>com.sun.star.accessibility.AccessibleEventObject:OldValue</idlm> or <idlm>com.sun.star.accessibility.AccessibleEventObject:NewValue</idlm> containing the <idlm>com.sun.star.accessibility.AccessibleStateType:FOCUSED</idlm> constant indicate that the source object of this event got either focused or unfocused.
    • When receiving events of type <idlm>com.sun.star.accessibility.AccessibleEventId:CHILD</idlm>, register as listener at the object that is specified by the event, as well as all the object's children.

A Simple Screen Reader

To illustrate the use of the UNO accessibility API, we will describe how to implement a simple AT. The simple screen reader, or SSR, will display some information about the currently focused object. As you can see in Illustration 18.1, the SSR consists of three windows. The bottom window logs all events that the SSR receives from any of the accessibility objects to which it is registered.

The simple screen reader shows information on the currently focused object in two different views. A textual display on the top left shows its description, states and bounding box as well as the names of its ancestors. The graphical view on the top right shows the bounding boxes of the object itself (green) and its ancestors (gray). The bottom window logs all events sent by any of the accessibility objects.

The two upper windows display information about the currently focused object, which in this screen shot is a shape in a presentation document. The left window displays the names of all the ancestors of the focused object and the path from that object to the root object of the accessibility tree. The left window also displays the focused object's description, its state, its location, and its size on the screen. In this example, the focused object is named “Rectangle2”, which corresponds to the red rectangular shape. Its parent is called “Drawing View” and the root of the tree has the name of the document, which is “Untitled1”, followed by the product name and some debug information.

The upper right window displays similar information graphically. The focused object is shown as a green rectangle, while its ancestors are drawn as gray rectangles. You can see how the objects are nested. This corresponds to the requirement that the bounding of child objects must not overlap that of their parents. Note that the blue rectangular shape is not visible in this window, because it is a sibling of the focused red rectangle, but does not lie on that object's path to the root of the root object. Also note that some of the rectangles are off-center and smaller than they should be. This is because the rectangles that represent accessible objects, which in turn represent part of the GUI, are drawn with their screen location and size relative to the whole screen; the outermost rectangle that is enclosed by the gray background represents the screen of which the screen shot shows only a part.

The bottom window logs all the events that the SSR receives from the accessible objects it has register as event listener at.

Features

The SSR was designed to be a simple program that illustrates how to use the UNO accessibility API. However, we have not always chosen the most simple way to do something. There are therefore some features that may be useful in the “real” AT:

  • The SSR has a background connection timer task that waits for a LibreOffice application to start and then connects automatically to that application.
  • It uses independent threads to register as listener at a whole accessibility (sub-) tree of new top-level application windows or newly created accessible objects. The same is true for removing the listener from windows not visible anymore or accessible objects that are removed from their tree.
  • There are two different views that display information about the currently focused object. This illustrates how information of a certain accessibility object is retrieved by using different interfaces of the accessibility API.
  • A message area shows all received events regardless of whether they are necessary to keep track of the currently focused object. With this, the SSR serves as simple event monitor as well.

Class Overview

The SSR is implemented with the following classes and interfaces:

SSR

This is the main class of the tool. It is responsible for setting up and managing the GUI

ConnectionTask

The connection task is a thread that waits in the background for a LibreOffice application to start. As soon as there is one, it connects to it and initiates the registration at all of its accessible objects.

RegistrationThread

Each object of this class creates one thread that adds or removes the event listener at all accessible objects in one tree, with one tree per application window. This is done in separate threads so that the normal operation of the tool is not blocked while registering to complex applications with many objects.

EventListenerProxy

This is a singleton class. Its only instance is registered as listener at all accessible objects. It runs in its own thread and delivers the received events eventually to the actual event handler. This de-coupling between event reception and event handling is necessary to avoid deadlocks. Soon this will become obsolete.

EventHandler

There is usually only one object of this class. It prints log messages for all the events it receives and provides special handling some of events:
  • Top window events denoting new or removed application windows are not accessibility events in a strict sense. They have to be listened to, however, to add or remove the event listener to the accessibility objects that correspond to these windows.
  • State events that inform the listener of a set or reset <idlm>com.sun.star.accessibility.AccessibleStateType:FOCUSED</idlm> state. This is the most important event for the SSR in order to keep track of the currently focused object.
  • Events that signal a change of the geometric property of the currently focused object trigger a redisplay of the two windows that display that object. This ensures that you always see the current position of the object.

TextualDisplay

This widget displays textual information about the focused object as described previously.

GraphicalDisplay

This widget displays graphical information about the focused object as described previously.

IaccessibleObjectDisplay

This is the interface supported by the two display widgets. It defines how the event handler tells the displays about focus and geometry changes. You can add other displays as well by adding a widget that implements this interface to the event handler and to the GUI.

MessageArea

The message area at the bottom is a simple text widget that scrolls its content so that the last line that contains the most recent message is always visible.

NameProvider

This is a useful helper class that converts numerical IDs into names, roles, events, or states.

Parts of some of these classes will be explained at later points in this text. Others, like the ConnectionTask class, are a mere technicality with respect to the accessibility API and will not be detailed any further.

Putting the Accessibility Interfaces to Work

Once an accessible object has been obtained by a call to <idlm>com.sun.star.accessibility.XAccessible:getAccessibleContext</idlm>(), you can switch between the interfaces belonging to the accessibility API by using the usual UNO cast mechanisms. There is, however, no way back to the object from which the accessible object has been obtained through procedures provided by the accessibility API.

XAccessibleContext

<idl>com.sun.star.accessibility.XAccessibleContext</idl> is the central interface of the accessibility API. In addition to the hierarchy information described previously, it provides access to some important information. The functions <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleRole</idlm>(), <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleName</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleDescription</idlm>() return descriptions of the object in increasing detail:

Role

The role classifies all accessibility objects into a handful of different classes. Most roles are taken from the Java accessibility API, such as <idlm>com.sun.star.accessibility.AccessibleRole:PUSH_BUTTON</idlm>, <idlm>com.sun.star.accessibility.AccessibleRole:RADIO_BUTTON</idlm>, <idlm>com.sun.star.accessibility.AccessibleRole:SCROLL_BAR</idlm> or <idlm>com.sun.star.accessibility.AccessibleRole:TEXT</idlm>. Some have been defined for the accessibility API so that, in addition to GUI elements, documents can be made accessible. These roles are <idlm>com.sun.star.accessibility.AccessibleRole:DOCUMENT</idlm> for document windows or views, <idlm>com.sun.star.accessibility.AccessibleRole:PARAGRAPH</idlm> for text sections, or <idlm>com.sun.star.accessibility.AccessibleRole:SHAPE</idlm> for graphical objects. Roles are described in the <idl>com.sun.star.accessibility.AccessibleRole</idl> constants group.

Name

Names allow you to distinguish between objects with the same role. For example, the buttons at the bottom of a dialog all have the role <idlm>com.sun.star.accessibility.AccessibleRole:PUSH_BUTTON</idlm>. Their names may be "OK", "Cancel" or "Help". Where necessary, names are made unique with respect to the object's siblings. Names for shapes can be "Rectangle 0", "Ellipse 1", "Rectangle 2", or "Curve 3".

Description

To further describe the purpose of accessibility objects, description strings are provided. Descriptions of shapes can contain their style and some properties whose values differ from that style. If you have changed the color of a rectangle to red, its description may look like "Rectangle with style=default and color=red".

Names and descriptions are strings localized according to the locale returned by <idlm>com.sun.star.accessibility.XAccessibleContext:getLocale</idlm>().

Two functions of the interface have not been mentioned so far. The function <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleRelationSet</idlm>() returns the set of relations defined for an accessibility object. Likewise <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleStateSet</idlm>() returns a set of states that are active for an object.

Path in the SSR

The showParents() method from the TextualDisplay class of the SSR displays the path from a given object to the root of the accessibility tree by printing each object's accessible name indented relative to its father.

private String showParents (XAccessibleContext xContext) {

The method first obtains references to all the objects that belong to this path.

Vector aPathToRoot = new Vector();
while (xContext != null) {
    aPathToRoot.add (xContext);
    // Go up the hierarchy one level to the object's parent.
    try {
        XAccessible xParent = xContext.getAccessibleParent();
        if (xParent != null)
            xContext = xParent.getAccessibleContext();
        else
            xContext = null;
    }
    catch (Exception e) {
        System.err.println ("caught exception " + e + " while getting path to root");
    }
}

This is done in two steps. First, a call to the <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleParent</idlm>() method to get the parent of the object and thereby moving to the previous level in the accessibility tree. Second, from the returned <idls>com.sun.star.accessibility.XAccessible</idls> reference, the accessible context is retrieved by calling <idlm>com.sun.star.accessibility.XAccessible:getAccessibleContext</idlm>(). This is repeated until an object is reached that has no parent and <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleParent</idlm>() returns null.

The path of the accessibility tree is now printed by appending text to the msTextContext member variable, which later is displayed in a JtextArea widget. To cope with accessibility objects that return an empty name, the role of these objects is used to represent them. Note how the indentation string is updated after every object by appending the msIndentation member.

String sIndentation = new String ();
    for (int i=aPathToRoot.size()-1; i>=0; i--) {
        XAccessibleContext xParentContext = (XAccessibleContext)aPathToRoot.get(i);
        String sParentName = xParentContext.getAccessibleName();
        if (sParentName.length() == 0)
            sParentName = "<unnamed> / Role "
                + NameProvider.getRoleName(xParentContext.getAccessibleRole());
        msTextContent += sIndentation + sParentName + "\n";
        sIndentation += msIndentation;
    }

The indentation is returned so that further output can be properly aligned.

return sIndentation;
}

XAccessibleComponent

The <idls>com.sun.star.accessibility.XAccessibleComponent</idls> interface gives access to geometric properties, such as size and position on the screen. This interface should be implemented by every object that has a visible representation, that is, by all objects that are not simple containers.

The coordinates used by the functions of this interface are returned and and are expected in pixel values and not, as is elsewhere in the UDK, in internal coordinates (100th of mm). There are three different origins to which coordinates may be specified:

  • Relative to an object's bounding box. This is relative to the object itself. Used by the <idlm>com.sun.star.accessibility.XAccessibleComponent:containsPoint</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleComponent:getAccessibleAtPoint</idlm>() functions.
  • Relative to an object's parent. Used by the <idlm>com.sun.star.accessibility.XAccessibleComponent:getBounds</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleComponent:getLocation</idlm>() functions.
  • Absolute or relative to the screen origin. Used by the <idlm>com.sun.star.accessibility.XAccessibleComponent:getLocationOnScreen</idlm>().

Because all three coordinate systems are based on pixel values, the <idlm>com.sun.star.accessibility.XAccessibleComponent:getSize</idlm>() function is independent of the coordinate system.

The bounding rectangle that encloses the visual presentation of an object can be retrieved by calling <idlm>com.sun.star.accessibility.XAccessibleComponent:getBounds</idlm>(). If you only need the location or the size, then call <idlm>com.sun.star.accessibility.XAccessibleComponent:getLocation</idlm>() or <idlm>com.sun.star.accessibility.XAccessibleComponent:getSize</idlm>(). The function <idlm>com.sun.star.accessibility.XAccessibleComponent:getLocationOnScreen</idlm>() returns the absolute screen coordinates.

There or two functions that determine whether the bounding boxes of the object or one of its children contain a given test point. The function <idlm>com.sun.star.accessibility.XAccessibleComponent:containsPoint</idlm>() checks whether the test point lies within the bounding box of the object. Children can be tested with <idlm>com.sun.star.accessibility.XAccessibleComponent:getAccessibleAtPoint</idlm>(). When one of the direct children contains the test point, a reference to this object is returned.

In addition to the geometrical functions, there are the two <idlm>com.sun.star.accessibility.XAccessibleComponent:getForeground</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleComponent:getBackground</idlm>() functions that describe an object's appearance. Keep in mind that an object does not necessarily have a monochrome background color. There can be a hatching, gradient, or bitmap as well. The returned background color in this case is an approximation.

Geometrical information in the SSR

The showComponentInfo() method of the TextualDisplay class takes as argument a reference to the accessible object for which geometrical information is shown, as well as the indentation string computed in the showParents() method.

private void showComponentInfo (XAccessibleContext xContext, String sIndentation) {

When given an <idls>com.sun.star.accessibility.XAccessibleContext</idls> reference, you must cast it to a <idls>com.sun.star.accessibility.XAccessibleComponent</idls> reference in order to access geometrical information about an accessible object.

XAccessibleComponent xComponent = (XAccessibleComponent)UnoRuntime.queryInterface(
    XAccessibleComponent.class, xContext);
if (xComponent != null) {

If the cast was successful, then simply call the <idlm>com.sun.star.accessibility.XAccessibleComponent:getLocationOnScreen</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleComponent:getSize</idlm>() methods to obtain the object's bounding box in screen coordinates. If <idlm>com.sun.star.accessibility.XAccessibleComponent:getBounds</idlm>() is called instead, the parent's screen coordinates must be added to obtain an absolute position.

Point aLocation = xComponent.getLocationOnScreen();
msTextContent += sIndentation + "Position : "
    + aLocation.X + ", " + aLocation.Y + "\n";

Size aSize = xComponent.getSize();
msTextContent += sIndentation + "Size : "
    + aSize.Width + ", " + aSize.Height + "\n";
}
}

XAccessibleExtendedComponent

While the <idl>com.sun.star.accessibility.XAccessibleComponent</idl> interface should be implemented by almost every accessible object, the support of the <idls>com.sun.star.accessibility.XAccessibleExtendedComponent</idls> interface is optional. Its most important function, <idlm>com.sun.star.accessibility.XAccessibleExtendedComponent:getFont</idlm>() returns the font used to display text.

The <idlm>com.sun.star.accessibility.XAccessibleExtendedComponent:getTitledBorderText</idlm>() function returns the text that is displayed on an object's window borders, which in the case of LibreOffice is only relevant for top-level windows.

The <idlm>com.sun.star.accessibility.XAccessibleExtendedComponent:getToolTipText</idlm>() function returns the tool tip text that is displayed when the mouse pointer rests long enough over one point of the object.

XAccessibleText

The interface <idls>com.sun.star.accessibility.XAccessibleText</idls> handles read-only text. It serves three purposes: to obtain certain parts of a text, to obtain the text's size and location on the screen, and to handle the caret position. An accessibility object that implements this interface usually represents only a part of a larger text. Typically, this is a single or a small number of paragraphs. You can use the relation types <idlm>com.sun.star.accessibility.AccessibleRelationType:CONTENT_FLOWS_FROM</idlm> and <idlm>com.sun.star.accessibility.AccessibleRelationType:CONTENT_FLOWS_TO</idlm> to explicitly represent the text flow from one text part to another. Without these relations, the text flow has to be determined from the structure of the accessibility tree alone.

Selection

Represented text may contain a selected text portion, which is typically displayed highlighted (inverse). There are four functions to access and modify the selection. The selected text, as well as its start and end index, can be accessed with the <idlm>com.sun.star.accessibility.XAccessibleText:getSelectedText</idlm>(), <idlm>com.sun.star.accessibility.XAccessibleText:getSelectionStart</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleText:getSelectionEnd</idlm>() functions respectively. To modify the selection, call <idlm>com.sun.star.accessibility.XAccessibleText:setSelection</idlm>() with the new start and end indices.

Text type

The functions <idlm>com.sun.star.accessibility.XAccessibleText:getTextAtIndex</idlm>(), <idlm>com.sun.star.accessibility.XAccessibleText:getTextBeforeIndex</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleText:getTextBehindIndex</idlm>() return parts of the text where the part or length of text returned is specified by the text type. Defined in the <idl>com.sun.star.accessibility.AccessibleTextType</idl> constants collection, some of these text types further explanation:

<idlm>com.sun.star.accessibility.AccessibleTextType:LINE</idlm>

The type <idlm>com.sun.star.accessibility.AccessibleTextType:LINE</idlm> indicates all text on a single line as it is displayed on the screen. This may include a hyphen at the line end. The hyphen is not actually part of the text, but is visible on the screen. They are only included in text parts of type <idlm>com.sun.star.accessibility.AccessibleTextType:LINE</idlm>.

<idlm>com.sun.star.accessibility.AccessibleTextType:CHARACTER</idlm>, <idlm>com.sun.star.accessibility.AccessibleTextType:GLYPH</idlm>

Glyph is used in this context to mean that everything between two adjacent cursor positions is considered to be a glyph. In Thai, for example, you can stack up to four (Unicode) characters upon each other. When moving with the cursor keys, those character groups are interpreted as single glyphs, and the cursor can only be set in front or after such glyphs, but not inside.

<idlm>com.sun.star.accessibility.AccessibleTextType:WORD</idlm>, <idlm>com.sun.star.accessibility.AccessibleTextType:SENTENCE</idlm>, <idlm>com.sun.star.accessibility.AccessibleTextType:PARAGRAPH</idlm>

The definition of words, sentences and paragraphs are implementation and locale dependent.

<idlm>com.sun.star.accessibility.AccessibleTextType:ATTRIBUTE_RUN</idlm>

An attribute run is a sequence of characters of maximal length, where all characters have the same attributes. For example the text "This is an example" consists of three attribute runs: "This", "is an" and "example". The first and last one each have only a single attribute, italic respectively bold. The second run has both attributes at the same time. Note that all three spaces belong to one of the attribute runs.

There are other functions to access text. To retrieve the whole text represented by an object, use <idlm>com.sun.star.accessibility.XAccessibleText:getText</idlm>(). Call <idlm>com.sun.star.accessibility.XAccessibleText:getTextRange</idlm>() to get only a part of text between and including two given indices. A single character can be accessed with the <idlm>com.sun.star.accessibility.XAccessibleText:getCharacter</idlm>() function.

To copy a text range to the clipboard, call the <idlm>com.sun.star.accessibility.XAccessibleText:copyText</idlm>() function. See also the related <idlm>com.sun.star.accessibility.XAccessibleEditableText:cutText</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleEditableText:pasteText</idlm>() functions of the <idl>com.sun.star.accessibility.XAccessibleEditableText</idl> interface.

Caret and Text Indices

The caret is often referred to as the cursor and is typically displayed as a vertical line. On the screen, it is always placed between two adjacent glyphs, or at the beginning or the end of a text line. When specifying its position in terms of character positions, the position of the character to its right is used. Thus, the index 0 says that the caret is at the very beginning of the text. When the caret is located behind the last character, then its position equals the text length, that is, the number of characters of the text as returned by <idlm>com.sun.star.accessibility.XAccessibleText:getCharacterCount</idlm>().

When the caret changes its position, an event must be sent to all listeners so that the old and new position can be indicated.

The caret position is returned by the <idlm>com.sun.star.accessibility.XAccessibleText:getCaretPosition</idlm>() function, and can be set by calling <idlm>com.sun.star.accessibility.XAccessibleText:setCaretPosition</idlm>().

Other index-related functions are <idlm>com.sun.star.accessibility.XAccessibleText:getCharacterAttributes</idlm>(), which returns the attributes at the specified index, <idlm>com.sun.star.accessibility.XAccessibleText:getCharacterBounds</idlm>(), which returns the bounding box of the character at the specified index, and <idlm>com.sun.star.accessibility.XAccessibleText:getIndexAtPoint</idlm>(), which returns the index of the character at the specified position.

XAccessibleEditableText

The <idls>com.sun.star.accessibility.XAccessibleEditableText</idls> interface extends the <idls>com.sun.star.accessibility.XAccessibleText</idls> interface by adding functions that let you modify the text. The interface is therefore only implemented when the text represented by the implementing object is readable and writable.

With the functions <idlm>com.sun.star.accessibility.XAccessibleEditableText:deleteText</idlm>(), <idlm>com.sun.star.accessibility.XAccessibleEditableText:insertText</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleEditableText:replaceText</idlm>(), you can delete, insert, and replace text. The <idlm>com.sun.star.accessibility.XAccessibleEditableText:setText</idlm>() function is a special case of <idlm>com.sun.star.accessibility.XAccessibleEditableText:replaceText</idlm>() and replaces the whole text at once.

The <idlm>com.sun.star.accessibility.XAccessibleEditableText:cutText</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleEditableText:pasteText</idlm>() functions, together with <idlm>com.sun.star.accessibility.XAccessibleText:copyText</idlm>(), from the <idl>com.sun.star.accessibility.XAccessibleText</idl> interface provide access to the clipboard.

Finally, the <idlm>com.sun.star.accessibility.XAccessibleEditableText:setAttributes</idlm>() function is the counterpart of <idlm>com.sun.star.accessibility.XAccessibleText:getCharacterAttributes</idlm>() in the <idl>com.sun.star.accessibility.XAccessibleText</idl> interface. With this function, you can replace the existing attributes with the given set. To add one attribute, first use <idlm>com.sun.star.accessibility.XAccessibleText:getCharacterAttributes</idlm>() to get the current set of attributes, add the attribute to that set, and finally call <idlm>com.sun.star.accessibility.XAccessibleEditableText:setAttributes</idlm>() to set the new set of attributes.

XAccessibleTable

The <idl>com.sun.star.accessibility.XAccessibleTable</idl> interface represents two-dimensional tables of data. The Calc application is one example of its implementation. It grants access to individual cells or groups of cells.

Global information about a table can be accessed with two functions: <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleCaption</idlm>() returns the caption and <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleSummary</idlm>() returns a summary describing the content of a table.

A table is organized in horizontal rows and vertical columns. The number of rows and columns - and indirectly the number of cells - can be determined by calling the functions <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleRowCount</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleColumnCount</idlm>(). Here, in contrast to the general rule of only giving access to visible objects, all cells are represented by a table. This exception is necessary to stay consistent with Java tables.

Information on rows and columns is returned by the <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleRowDescription</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleColumnDescription</idlm>() functions. Note that both functions return objects implementing the <idl>com.sun.star.accessibility.XAccessibleTable</idl> interface themselves. The headers of rows and columns can be retrieved by calling <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleRowHeaders</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleColumnHeaders</idlm>().

To obtain a reference to a certain cell specified by its row and column indices, use <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleCellAt</idlm>(). A table cell may span multiple rows and columns. You can determine the number of rows and columns that a cell spans with the <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleRowExtentAt</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleColumnExtentAt</idlm>() functions.

Selections in tables can have two different forms. You can have a multi-selection of rectangular areas of single or multiple cells, or you can select whole rows and columns. The function <idlm>com.sun.star.accessibility.XAccessibleTable:isAccessibleSelected</idlm>() determines whether a single cell that spans a position specified by a row and a column index is selected. To determine whether certain rows or columns are selected, use the <idlm>com.sun.star.accessibility.XAccessibleTable:isAccessibleRowSelected</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleTable:isAccessibleColumnSelected</idlm>() functions. Finally, the functions <idlm>com.sun.star.accessibility.XAccessibleTable:getSelectedAccessibleRows</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleTable:getSelectedAccessibleColumns</idlm>() each return a sequence of indices of the currently selected row and columns.

There are three functions that can be used to switch between cell indices and row and column indices. Cell indices are the same as the child indices used by the <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChildCount</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChild</idlm>() functions of the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface. Row and column indices have been used previously, and specify each cell by stating its row and column. The <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleIndex</idlm>() function returns the corresponding cell index for a given row and column index. The <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleRow</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleTable:getAccessibleColumn</idlm>() functions return the corresponding row and column index, respectively, for a given cell index.

XAccessibleEventBroadcaster

Most accessible objects need to broadcast events that describe changes of its internal state or visual appearance - this can be done with the <idl>com.sun.star.accessibility.XAccessibleEventBroadcaster</idl>interface. If you want to be informed of such changes, you can register a listener with the <idlm>com.sun.star.accessibility.XAccessibleEventBroadcaster:addEventListener</idlm>() function, or remove it with <idlm>com.sun.star.accessibility.XAccessibleEventBroadcaster:removeEventListener</idlm>().

Warning.svg

Warning:
Be sure to cast an object reference to the <idls>com.sun.star.accessibility.XAccessibleEventBroadcaster</idls> interface before calling these functions, because there are other broadcaster interfaces with functions of the same name.


The SSR registers the event listener in separate threads. The major work is done by a method called traverseTree() that takes an accessible context and traverses the whole tree rooted in this object.

public long traverseTree (XAccessibleContext xRoot) {

After casting the context reference to a reference of the <idls>com.sun.star.accessibility.XAccessibleEventBroadcaster</idls> interface, it either adds or removes the listener maListener at the accessibility object.

long nNodeCount = 0;
if (xRoot != null) {
    // Register the root node.
    XAccessibleEventBroadcaster xBroadcaster =
        (XAccessibleEventBroadcaster) UnoRuntime.queryInterface (
            XAccessibleEventBroadcaster.class,
            xRoot);
    if (xBroadcaster != null) {
        if (mbRegister)
            xBroadcaster.addEventListener (maListener);
        else
            xBroadcaster.removeEventListener (maListener);
        nNodeCount += 1;
    }

Once the given object is handled, the traversing of the tree continues by calling this method recursively for every child.

try {
    int nChildCount = xRoot.getAccessibleChildCount();
    for (int i=0; i<nChildCount; i++) {
        XAccessible xChild = xRoot.getAccessibleChild (i);
        if (xChild != null)
            nNodeCount += traverseTree (xChild.getAccessibleContext());
    }
}

Because the iteration over the direct children of the given accessible context may take a while, there is the possibility that some children do not exist anymore. It is therefore important to catch <idls>com.sun.star.lang.IndexOutOfBoundsException</idls> and <idls>com.sun.star.lang.DisposedException</idls> exceptions. Note that this is not a perfect solution, because children that are added to the given object are not handled properly. A better algorithm would listen to events of the new and removed children of the object to which it was recently registered:

catch (com.sun.star.lang.IndexOutOfBoundsException aException) {
    // The set of children has changed since our last call to
    // getAccesibleChildCount(). Don't try any further on this
    // sub-tree.
}
catch (com.sun.star.lang.DisposedException aException) {
    // The child has been destroyed since our last call to
    // getAccesibleChildCount(). That is OK. Don't try any
    // further on this sub-tree.
}
}
return nNodeCount;
}

This method keeps track of how many objects it has added to the listener. This number is used in the run() method to write an informative message.

public void run () {
    System.out.println ("starting registration");
    long nNodeCount = traverseTree (mxRoot);
    System.out.println ("ending registration");
    if (mbShowMessages) {
        if (!mbRegister)
            MessageArea.print ("un");
        MessageArea.println ("registered at " + nNodeCount
            + " objects in accessibility tree of " + mxRoot.getAccessibleName());
    }
}

XAccessibleEventListener

The interface <idl>com.sun.star.accessibility.XAccessibleEventListener</idl> is the counterpart to the accessible event broadcaster, and is called for every change of any accessible object at which it has been registered. The <idlm>com.sun.star.accessibility.XAccessibleEventListener:notifyEvent</idlm>() function is called with an <idl>com.sun.star.accessibility.AccessibleEventObject</idl> structure. That structure comprises four fields: the <idlm>com.sun.star.accessibility.AccessibleEventObject:EventId</idlm> field, which is one of the <idl>com.sun.star.accessibility.AccessibleEventId</idl> constants, describes the type of the event. The object that sent the event is referenced from the Source field. The <idlm>com.sun.star.accessibility.AccessibleEventObject:OldValue</idlm> and <idlm>com.sun.star.accessibility.AccessibleEventObject:NewValue</idlm> fields contain event type specific values that contain the changed value before and after the modification took place. The type of content that is expected in the <idlm>com.sun.star.accessibility.AccessibleEventObject:OldValue</idlm> and <idlm>com.sun.star.accessibility.AccessibleEventObject:NewValue</idlm> fields is explained together with the <idls>com.sun.star.accessibility.AccessibleEventId</idls> event types.

The notifyEvent() method of the EventHandler class is not called directly from the accessibility objects. There is an instance of the EventListenerProxy class in between. That class simply forwards the events at the right time and is therefore not explained in more detail here.

public void notifyEvent (com.sun.star.accessibility.AccessibleEventObject aEvent) {

The one event type that is covered here is the <idlm>com.sun.star.accessibility.AccessibleEventId:CHILD</idlm> event, which is sent when a new accessibility object has been created, or an existing one has been removed.

// Guard against disposed objects.
try {
    switch (aEvent.EventId) {
        case AccessibleEventId.CHILD:
            handleChildEvent (
                objectToContext (aEvent.OldValue),
                objectToContext (aEvent.NewValue));
            break;

The handling of the rest of the event types is omitted here to keep this explanation simple.

Again, it is important to guard against the possibility of events arriving after the object they were sent for has been destroyed. For this simple tool, it is sufficient to silently ignore the resulting exception.

}
}
catch (com.sun.star.lang.DisposedException e) {
}
}

Before showing you the actual handling of child events, you can look at the objectToContext() method that is used to convert the <idlm>com.sun.star.accessibility.AccessibleEventObject:OldValue</idlm> and <idlm>com.sun.star.accessibility.AccessibleEventObject:NewValue</idlm> fields of the event structure from UNO Anys to <idls>com.sun.star.accessibility.XAccessibleContext</idls> references. It takes a weakness of the accessibility API IDL specification into account: the type of the content of the <idlm>com.sun.star.lang.EventObject:Source</idlm> field is not explicitly stated. As a result, it contains references to both the <idls>com.sun.star.accessibility.XAccessible</idls> and the <idls>com.sun.star.accessibility.XAccessibleContext</idls> interfaces. To cope with this, the conversion method first uses the com.sun.star.uno.AnyConverter class to retrieve an <idls>com.sun.star.accessibility.XAccessible</idls> reference from the event source.

private XAccessibleContext objectToContext (Object aObject) {
    XAccessibleContext xContext = null;
    XAccessible xAccessible = null;
    try {
        xAccessible = (XAccessible)AnyConverter.toObject(
            new Type(XAccessible.class), aObject);
    }
    catch (com.sun.star.lang.IllegalArgumentException e) {
    }

If that was successful, the accessible context from the object is returned.

if (xAccessible != null)
    xContext = xAccessible.getAccessibleContext();

If retrieving an <idls>com.sun.star.accessibility.XAccessible</idls> reference from the event's source field failed, this is repeated directly with the <idls>com.sun.star.accessibility.XAccessibleContext</idls> interface.

else
    try {
        xContext = (XAccessibleContext)AnyConverter.toObject(
            new Type(XAccessibleContext.class), aObject);
    }
    catch (com.sun.star.lang.IllegalArgumentException e) {
    }
return xContext;
}

Handling the child event itself is comparably simple: create a new RegistrationThread object that adds (or removes) the listener to the object and all of its children.

private void handleChildEvent (XAccessibleContext aOldChild, XAccessibleContext aNewChild) {
    if (aOldChild != null)
        // Remove event listener from the child and all of its descendants.
        new RegistrationThread (maListenerProxy, aOldChild, false, false);
    else if (aNewChild != null)
        // Add event listener to the new child and all of its descendants.
        new RegistrationThread (maListenerProxy, aNewChild, true, false);
}

XAccessibleSelection

While the <idl>com.sun.star.accessibility.XAccessibleText</idl> and <idl>com.sun.star.accessibility.XAccessibleTable</idl> interfaces already support selection of text and table cells, respectively, there is a special interface for the general case. The <idls>com.sun.star.accessibility.XAccessibleSelection</idls> interface manages a sub-set of an object's children that form the selection. The number of selected children is returned by <idlm>com.sun.star.accessibility.XAccessibleSelection:getSelectedAccessibleChildCount</idlm>(), which, of course, is smaller than or equal to the total number of children as returned by <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChildCount</idlm>() of the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface. The selected children can be retrieved by calling the <idlm>com.sun.star.accessibility.XAccessibleSelection:getSelectedAccessibleChild</idlm>() function. Note that the same index passed to <idlm>com.sun.star.accessibility.XAccessibleSelection:getSelectedAccessibleChild</idlm>() and to <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleChild</idlm>() will generally return different objects.

The selection can be modified with various functions. The functions <idlm>com.sun.star.accessibility.XAccessibleSelection:selectAllAccessibleChildren</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleSelection:clearAccessibleSelection</idlm>() select or deselect, respectively, all of the children. To select or deselect a single child, use <idlm>com.sun.star.accessibility.XAccessibleSelection:selectAccessibleChild</idlm>() or <idlm>com.sun.star.accessibility.XAccessibleSelection:deselectAccessibleChild</idlm>(). Whether a child belongs to the selection can be determined by calling the <idlm>com.sun.star.accessibility.XAccessibleSelection:isAccessibleChildSelected</idlm>() function.

Each child that belongs to the selection is expected to have the <idlm>com.sun.star.accessibility.AccessibleStateType:SELECTED</idlm> state set. When the selection changes, two kinds of events are expected to be broadcast. One for each child that is selected or deselected that tells the listeners about the toggled <idlm>com.sun.star.accessibility.AccessibleStateType:SELECTED</idlm> state, and one event from their parent that informs the listeners of the modified selection as represented by the <idl>com.sun.star.accessibility.XAccessibleSelection</idl> interface.

XAccessibleRelationSet

In addition to the parent-child relationship that defines the accessibility object tree, each accessible object may have one or more relations to other accessible objects, independent of that hierarchy. The types of possible relations are defined and explained in the <idl>com.sun.star.accessibility.AccessibleRelationType</idl> set of constants.

One example is the <idlm>com.sun.star.accessibility.AccessibleRelationType:LABEL_FOR</idlm> and <idlm>com.sun.star.accessibility.AccessibleRelationType:LABELED_BY</idlm> pair of relations that is used to express the case where one object is the label for a one or more controls of the GUI. The label and its controls may be spatially adjacent to make their relationship clear to the sighted user. But in the accessibility object tree, they may belong to different sub-trees. With a set of relations, these objects can be linked together.

Each relation is an <idl>com.sun.star.accessibility.AccessibleRelation</idl> structure that contains the relation type and a set of references to its target objects. In the previous example, there would be one <idlm>com.sun.star.accessibility.AccessibleRelationType:LABEL_FOR</idlm> relation for the label with all its controls in the target set and one <idlm>com.sun.star.accessibility.AccessibleRelationType:LABELED_BY</idlm> relation from each control to the label.

For each relation type there may be one relation belonging to a relation set as represented by the <idl>com.sun.star.accessibility.XAccessibleRelationSet</idl> interface. Therefore, the number of relations that is returned by <idlm>com.sun.star.accessibility.XAccessibleRelationSet:getRelationCount</idlm>() can not be greater than the number of relation types. Relations can be accessed either by calling the <idlm>com.sun.star.accessibility.XAccessibleRelationSet:getRelation</idlm>() function with an index, or by calling the <idlm>com.sun.star.accessibility.AccessibleRelation:RelationType</idlm>() function with a relation type. Note that there are no fixed mappings from relation types to indices. You can test whether a relation set contains a relation of a given type by using the <idlm>com.sun.star.accessibility.XAccessibleRelationSet:containsRelation</idlm>() function.

Note pin.svg

Note:
The relation set returned by <idl>com.sun.star.accessibility.XAccessibleContext:getAccessibleRelationSet</idl>() returns a copy of the relation set of an accessible object. Modifying that copy does not change the relation set of the object.

XAccessibleStateSet

An accessible object can be in one or more states, which are available through the interface <idl>com.sun.star.accessibility.XAccessibleStateSet</idl>. An object that is currently focused will have the <idlm>com.sun.star.accessibility.AccessibleStateType:FOCUSED</idlm> state set. One that belongs to the selection of its parent has the <idlm>com.sun.star.accessibility.AccessibleStateType:SELECTED</idlm> state set. Independent of the current focus and selection, such an object would also have the states <idlm>com.sun.star.accessibility.AccessibleStateType:FOCUSABLE</idlm> and <idlm>com.sun.star.accessibility.AccessibleStateType:SELECTABLE</idlm> set to indicate that it may be focused and may be selected. All states are described in the <idl>com.sun.star.accessibility.AccessibleStateType</idl> constants collection.

Call the <idlm>com.sun.star.accessibility.XAccessibleStateSet:isEmpty</idlm>() function to query whether a state set has no state set at all. To query a state set for one or more states, use the <idlm>com.sun.star.accessibility.XAccessibleStateSet:contains</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleStateSet:containsAll</idlm>() functions respectively. A sequence containing all the set states is returned by the <idlm>com.sun.star.accessibility.XAccessibleStateSet:getStates</idlm>() function.

Note pin.svg

Note:
The state set returned by <idlm>com.sun.star.accessibility.XAccessibleContext:getAccessibleStateSet</idlm>() returns a copy of the state set of an accessible object. Modifying that copy does not change the states of the object. Therefore, modifying a state set is not useful and consequently no modifying functions are supported by the <idl>com.sun.star.accessibility.XAccessibleStateSet</idl> interface. States are set or reset indirectly by using the standard UNO interfaces or the GUI.

List of states in the SSR

The showStates() method of the TextualDisplay class of the SSR first obtains a state set object from the given accessible context and prints a list of all the states contained therein by using the <idlm>com.sun.star.accessibility.XAccessibleStateSet:getStates</idlm>() method to convert the state set into an array of state IDs. It then iterates over all IDs and uses the NameProvider class to convert the numerical IDs into human-readable strings.

private void showStates (XAccessibleContext xContext, String sIndentation) {
    // Get the state set object...
    XAccessibleStateSet xStateSet = xContext.getAccessibleStateSet();
    // ...and retrieve an array of numerical IDs.
    short aStates[] = xStateSet.getStates();

    // Iterate over the array and print the names of the states.
    msTextContent += sIndentation + "States : ";
    for (int i=0; i<aStates.length; i++) {
        if (i > 0)
            msTextContent += ", ";
        msTextContent += NameProvider.getStateName(aStates[i]);
    }
    msTextContent += "\n";
}

XAccessibleValue

In a typical GUI, there are many controls whose characteristic feature can be represented by a single numerical value. Examples are spin boxes, scales and sliders, or combo boxes that contain only numbers, such as the font size. These objects should support the <idls>com.sun.star.accessibility.XAccessibleValue</idls> interface.

The current value can be read and set with the <idlm>com.sun.star.accessibility.XAccessibleValue:getCurrentValue</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleValue:setCurrentValue</idlm>() functions. The valid range of values is returned by the <idlm>com.sun.star.accessibility.XAccessibleValue:getMaximumValue</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleValue:getMinimumValue</idlm>() functions.

XAccessibleImage

The main purpose of the <idls>com.sun.star.accessibility.XAccessibleImage</idls> interface is to be an indicator that an object represents an image or a bitmap. The functions of this interface do not add functionality that is not already present in the <idl>com.sun.star.accessibility.XAccessibleContext</idl> interface.

The <idlm>com.sun.star.accessibility.XAccessibleImage:getAccessibleImageDescription</idlm>() function returns a localized description of the image. The functions <idlm>com.sun.star.accessibility.XAccessibleImage:getAccessibleImageHeight</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleImage:getAccessibleImageWidth</idlm>() return the size of the image in pixels.

XAccessibleAction

With the <idls>com.sun.star.accessibility.XAccessibleAction</idls> interface, an accessible object can provide access to actions that can be performed on the object. These actions may or may not correspond to actions that are already available over the GUI.

The number of available actions is returned by <idlm>com.sun.star.accessibility.XAccessibleAction:getAccessibleActionCount</idlm>(). To execute an action call <idlm>com.sun.star.accessibility.XAccessibleAction:doAccessibleAction</idlm>() with the index of the desired action. The description of an action is returned by the <idlm>com.sun.star.accessibility.XAccessibleAction:getAccessibleActionDescription</idlm>().

The <idlm>com.sun.star.accessibility.XAccessibleAction:getAccessibleActionKeyBinding</idlm>() function tells you what key bindings exist for a certain action. See the description of the <idls>com.sun.star.accessibility.XAccessibleKeyBinding</idls> interface below.

XAccessibleKeyBinding

The purpose of the <idls>com.sun.star.accessibility.XAccessibleKeyBinding</idls> interface is to represent an arbitrary set of key strokes. When a key binding is associated with an action (see the description of the interface above) then each of its key strokes executes that action. A key stroke itself consists of one or more keys to be pressed. See <idl>com.sun.star.awt.KeyStroke</idl> for details.

XAccessibleHypertext

The interface <idl>com.sun.star.accessibility.XAccessibleHypertext</idl> is derived from <idl>com.sun.star.accessibility.XAccessibleText</idl>. This interface represents text that contains hyperlinks. Those hyperlinks are represented by <idl>com.sun.star.accessibility.XAccessibleHyperlink</idl> objects, which are described next.

To iterate over all hyperlinks in a text, use <idlm>com.sun.star.accessibility.XAccessibleHypertext:getHyperLinkCount</idlm>() to determine the number of links. The <idlm>com.sun.star.accessibility.XAccessibleHypertext:getHyperLink</idlm>() function returns the <idl>com.sun.star.accessibility.XAccessibleHyperlink</idl> object for a specific index. If you want to know whether there is a link at a certain text position, use the <idlm>com.sun.star.accessibility.XAccessibleHypertext:getHyperLinkIndex</idlm>() function to obtain the corresponding object. When the returned reference is empty then there is no hyperlink at that position.

XAccessibleHyperlink

Hyperlinks contained in a hypertext document are modeled by the <idls>com.sun.star.accessibility.XAccessibleHyperlink</idls> interface. In its simplest form, a hyperlink corresponds to an HTML link. However, there may be more complex hyperlinks where there is more than one action assigned to a single hyperlink. An example of this is HTML image maps. To give access to the actions, the interface is derived from the <idl>com.sun.star.accessibility.XAccessibleAction</idl> interface. In addition to the information provided by the <idl>com.sun.star.accessibility.XAccessibleAction</idl> interface, you can request an action's anchor and object. A typical return value of the <idlm>com.sun.star.accessibility.XAccessibleHyperlink:getAccessibleActionAnchor</idlm>() function for HTML links would be the text between the <a href…> and </a> tags. Likewise, the <idlm>com.sun.star.accessibility.XAccessibleHyperlink:getAccessibleActionObject</idlm>() function returns a HTML link's URL.

A hyperlink specifies its text relative to the enclosing hypertext by providing a start- and end index through the <idlm>com.sun.star.accessibility.XAccessibleHyperlink:getStartIndex</idlm>() and <idlm>com.sun.star.accessibility.XAccessibleHyperlink:getEndIndex</idlm>() functions. You can ask a link about the validity of the referenced target by calling its <idlm>com.sun.star.accessibility.XAccessibleHyperlink:isValid</idlm>() function. Note that this state is volatile and may change without notice.

Heckert GNU white.svg

Content on this page is licensed under the Public Documentation License (PDL).