summaryrefslogtreecommitdiff
path: root/toolkit/test/accessibility
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/test/accessibility')
-rwxr-xr-xtoolkit/test/accessibility/AWB.sxwbin0 -> 9257 bytes
-rw-r--r--toolkit/test/accessibility/AccTreeNode.java350
-rwxr-xr-xtoolkit/test/accessibility/AccessibilityTree.java377
-rw-r--r--toolkit/test/accessibility/AccessibilityTreeModel.java513
-rw-r--r--toolkit/test/accessibility/AccessibilityTreeModelBase.java122
-rwxr-xr-xtoolkit/test/accessibility/AccessibilityWorkBench.java620
-rw-r--r--toolkit/test/accessibility/AccessibleActionHandler.java72
-rw-r--r--toolkit/test/accessibility/AccessibleActionNode.java48
-rw-r--r--toolkit/test/accessibility/AccessibleCellHandler.java156
-rw-r--r--toolkit/test/accessibility/AccessibleComponentHandler.java102
-rw-r--r--toolkit/test/accessibility/AccessibleContextHandler.java91
-rw-r--r--toolkit/test/accessibility/AccessibleEditableTextHandler.java40
-rw-r--r--toolkit/test/accessibility/AccessibleExtendedComponentHandler.java73
-rw-r--r--toolkit/test/accessibility/AccessibleHyperlinkHandler.java42
-rw-r--r--toolkit/test/accessibility/AccessibleHypertextHandler.java42
-rw-r--r--toolkit/test/accessibility/AccessibleImageHandler.java51
-rw-r--r--toolkit/test/accessibility/AccessibleRelationHandler.java96
-rw-r--r--toolkit/test/accessibility/AccessibleSelectionHandler.java130
-rw-r--r--toolkit/test/accessibility/AccessibleTableHandler.java90
-rw-r--r--toolkit/test/accessibility/AccessibleTextHandler.java792
-rw-r--r--toolkit/test/accessibility/AccessibleTreeCellRenderer.java86
-rw-r--r--toolkit/test/accessibility/AccessibleTreeHandler.java110
-rw-r--r--toolkit/test/accessibility/AccessibleTreeNode.java101
-rw-r--r--toolkit/test/accessibility/AccessibleUNOHandler.java115
-rwxr-xr-xtoolkit/test/accessibility/Canvas.java448
-rw-r--r--toolkit/test/accessibility/CanvasShape.java330
-rw-r--r--toolkit/test/accessibility/ChildEventHandler.java46
-rw-r--r--toolkit/test/accessibility/ContextEventHandler.java52
-rw-r--r--toolkit/test/accessibility/EventHandler.java57
-rw-r--r--toolkit/test/accessibility/EventListener.java124
-rw-r--r--toolkit/test/accessibility/EventLogger.java31
-rw-r--r--toolkit/test/accessibility/EventQueue.java126
-rw-r--r--toolkit/test/accessibility/FrameActionListener.java21
-rw-r--r--toolkit/test/accessibility/GeometryEventHandler.java54
-rw-r--r--toolkit/test/accessibility/HelpWindow.java185
-rwxr-xr-xtoolkit/test/accessibility/InformationWriter.java415
-rw-r--r--toolkit/test/accessibility/MessageArea.java123
-rwxr-xr-xtoolkit/test/accessibility/MessageInterface.java5
-rw-r--r--toolkit/test/accessibility/NodeFactory.java147
-rw-r--r--toolkit/test/accessibility/NodeHandler.java140
-rw-r--r--toolkit/test/accessibility/NodeMap.java112
-rwxr-xr-xtoolkit/test/accessibility/OfficeConnection.java102
-rw-r--r--toolkit/test/accessibility/Options.java88
-rwxr-xr-xtoolkit/test/accessibility/Print.java5
-rw-r--r--toolkit/test/accessibility/QueuedListener.java55
-rw-r--r--toolkit/test/accessibility/QueuedTopWindowListener.java88
-rw-r--r--toolkit/test/accessibility/SelectionDialog.java179
-rwxr-xr-xtoolkit/test/accessibility/SimpleOffice.java389
-rw-r--r--toolkit/test/accessibility/StringNode.java13
-rw-r--r--toolkit/test/accessibility/TableEventHandler.java43
-rw-r--r--toolkit/test/accessibility/TextLogger.java52
-rw-r--r--toolkit/test/accessibility/TextUpdateListener.java170
-rw-r--r--toolkit/test/accessibility/TopWindowListener.java205
-rw-r--r--toolkit/test/accessibility/VectorNode.java50
-rw-r--r--toolkit/test/accessibility/about.html8
-rw-r--r--toolkit/test/accessibility/help.html91
-rw-r--r--toolkit/test/accessibility/jawb.mf3
-rw-r--r--toolkit/test/accessibility/makefile.mk127
-rw-r--r--toolkit/test/accessibility/news.html36
-rw-r--r--toolkit/test/accessibility/ov/ContextView.java125
-rw-r--r--toolkit/test/accessibility/ov/FocusView.java119
-rw-r--r--toolkit/test/accessibility/ov/ListeningObjectView.java60
-rw-r--r--toolkit/test/accessibility/ov/ObjectView.java77
-rw-r--r--toolkit/test/accessibility/ov/ObjectViewContainer.java166
-rw-r--r--toolkit/test/accessibility/ov/SelectionView.java230
-rw-r--r--toolkit/test/accessibility/ov/StateSetView.java249
-rw-r--r--toolkit/test/accessibility/ov/TextView.java123
-rw-r--r--toolkit/test/accessibility/ov/makefile.mk51
-rw-r--r--toolkit/test/accessibility/tools/NameProvider.java259
-rw-r--r--toolkit/test/accessibility/tools/makefile.mk42
70 files changed, 9840 insertions, 0 deletions
diff --git a/toolkit/test/accessibility/AWB.sxw b/toolkit/test/accessibility/AWB.sxw
new file mode 100755
index 000000000000..57931aed1d19
--- /dev/null
+++ b/toolkit/test/accessibility/AWB.sxw
Binary files differ
diff --git a/toolkit/test/accessibility/AccTreeNode.java b/toolkit/test/accessibility/AccTreeNode.java
new file mode 100644
index 000000000000..64a5a5a3c4f6
--- /dev/null
+++ b/toolkit/test/accessibility/AccTreeNode.java
@@ -0,0 +1,350 @@
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.*;
+import java.util.Vector;
+
+/**
+ * The node type for the AccessibleTreeModel.
+ * This implements all the child-handling based on the appropriate
+ * NodeHandlers. Trivial nodes can be implemented by any Object
+ * type.
+ */
+class AccTreeNode
+ extends AccessibleTreeNode
+{
+ class HandlerDescriptor
+ {
+ public HandlerDescriptor (NodeHandler aHandler)
+ {
+ maHandler = aHandler;
+ mnChildCount = -1;
+ }
+ public NodeHandler maHandler;
+ public int mnChildCount;
+ }
+ /// NodeHandlers for this node
+ private Vector maHandlers;
+
+ // The accessible context of this node.
+ private XAccessible mxAccessible;
+ private XAccessibleContext mxContext;
+ private XAccessibleComponent mxComponent;
+ private XAccessibleText mxText;
+ private XAccessibleTable mxTable;
+
+ public AccTreeNode (XAccessible xAccessible, XAccessibleContext xContext, AccessibleTreeNode aParent)
+ {
+ this (xAccessible, xContext, xContext, aParent);
+ }
+
+ public AccTreeNode (XAccessible xAccessible, XAccessibleContext xContext, Object aDisplay, AccessibleTreeNode aParent)
+ {
+ super (aDisplay, aParent);
+
+ maHandlers = new Vector(5);
+ mxContext = xContext;
+ mxAccessible = xAccessible;
+ }
+
+ /** Update the internal data extracted from the corresponding accessible
+ object. This is done by replacing every handler by a new one. An
+ update method at each handler would be better of course.
+ */
+ public void update ()
+ {
+ for (int i=0; i<maHandlers.size(); i++)
+ {
+ System.out.println ("replacing handler " + i);
+ HandlerDescriptor aDescriptor = (HandlerDescriptor)maHandlers.get(i);
+ aDescriptor.maHandler = aDescriptor.maHandler.createHandler (mxContext);
+ aDescriptor.mnChildCount =
+ aDescriptor.maHandler.getChildCount (this);
+ }
+ }
+
+ public XAccessibleContext getContext ()
+ {
+ return mxContext;
+ }
+
+ public XAccessibleComponent getComponent ()
+ {
+ if (mxComponent == null && mxContext != null)
+ mxComponent = (XAccessibleComponent)UnoRuntime.queryInterface(
+ XAccessibleComponent.class, mxContext);
+ return mxComponent;
+ }
+
+ public XAccessibleExtendedComponent getExtendedComponent ()
+ {
+ if (mxComponent == null)
+ getComponent();
+ if (mxComponent != null)
+ return (XAccessibleExtendedComponent)UnoRuntime.queryInterface(
+ XAccessibleExtendedComponent.class, mxComponent);
+ else
+ return null;
+ }
+
+ public XAccessibleText getText ()
+ {
+ if (mxText == null && mxContext != null)
+ mxText = (XAccessibleText)UnoRuntime.queryInterface(
+ XAccessibleText.class, mxContext);
+ return mxText;
+ }
+
+ public XAccessibleEditableText getEditText ()
+ {
+ return (XAccessibleEditableText)UnoRuntime.queryInterface(
+ XAccessibleEditableText.class, mxContext);
+ }
+
+ public XAccessibleTable getTable ()
+ {
+ if (mxTable == null && mxContext != null)
+ mxTable = (XAccessibleTable)UnoRuntime.queryInterface(
+ XAccessibleTable.class, mxContext);
+ return mxTable;
+ }
+
+
+ public XAccessible getAccessible()
+ {
+ if ((mxAccessible == null) && (mxContext != null))
+ mxAccessible = (XAccessible)UnoRuntime.queryInterface(
+ XAccessible.class, mxContext);
+ return mxAccessible;
+ }
+
+ public XAccessibleSelection getSelection ()
+ {
+ return (XAccessibleSelection)UnoRuntime.queryInterface(
+ XAccessibleSelection.class, mxContext);
+ }
+
+ public void addHandler( NodeHandler aHandler )
+ {
+ if (aHandler != null)
+ maHandlers.add (new HandlerDescriptor (aHandler));
+ }
+
+
+ /** iterate over handlers and return child sum */
+ protected HandlerDescriptor getHandlerDescriptor (int i)
+ {
+ HandlerDescriptor aDescriptor = (HandlerDescriptor)maHandlers.get(i);
+ if (aDescriptor.mnChildCount < 0)
+ aDescriptor.mnChildCount =
+ aDescriptor.maHandler.getChildCount (this);
+ return aDescriptor;
+ }
+
+ public int getChildCount()
+ {
+ int nChildCount = 0;
+ for (int i = 0; i < maHandlers.size(); i++)
+ {
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ nChildCount += aDescriptor.mnChildCount;
+ }
+ return nChildCount;
+ }
+
+ /** iterate over handlers until the child is found */
+ public AccessibleTreeNode getChild (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ if( nIndex >= 0 )
+ {
+ for(int i = 0; i < maHandlers.size(); i++)
+ {
+ // check if this handler has the child, and if not
+ // search with next handler
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ if (nIndex < aDescriptor.mnChildCount)
+ return aDescriptor.maHandler.getChild (this, nIndex);
+ else
+ nIndex -= aDescriptor.mnChildCount;
+ }
+ }
+ else
+ throw new IndexOutOfBoundsException();
+
+ // nothing found?
+ return null;
+ }
+
+ public AccessibleTreeNode getChildNoCreate (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ if( nIndex >= 0 )
+ {
+ for(int i = 0; i < maHandlers.size(); i++)
+ {
+ // check if this handler has the child, and if not
+ // search with next handler
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ if (nIndex < aDescriptor.mnChildCount)
+ return aDescriptor.maHandler.getChildNoCreate (this, nIndex);
+ else
+ nIndex -= aDescriptor.mnChildCount;
+ }
+ }
+ else
+ throw new IndexOutOfBoundsException();
+
+ // nothing found?
+ return null;
+ }
+
+ public boolean removeChild (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ boolean bStatus = false;
+ if (nIndex >= 0)
+ {
+ for (int i=0; i<maHandlers.size(); i++)
+ {
+ // check if this handler has the child, and if not
+ // search with next handler
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ if (nIndex < aDescriptor.mnChildCount)
+ {
+ bStatus = aDescriptor.maHandler.removeChild (this, nIndex);
+ aDescriptor.mnChildCount = aDescriptor.maHandler.getChildCount (this);
+ break;
+ }
+ else
+ nIndex -= aDescriptor.mnChildCount;
+ }
+ }
+ else
+ throw new IndexOutOfBoundsException();
+
+ return bStatus;
+ }
+
+
+ public int indexOf (AccessibleTreeNode aNode)
+ {
+ int nBaseIndex = 0;
+ if (aNode != null)
+ {
+ for (int i=0; i<maHandlers.size(); i++)
+ {
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ int nIndex = aDescriptor.maHandler.indexOf (aNode);
+ if (nIndex >= 0)
+ return nBaseIndex + nIndex;
+ else
+ nBaseIndex += aDescriptor.mnChildCount;
+ }
+ }
+
+ return -1;
+ }
+
+ /** this node is a leaf if have no handlers, or is those
+ handlers show no children */
+ public boolean isLeaf()
+ {
+ return (maHandlers.size() == 0);// || (getChildCount() == 0);
+ }
+
+ public boolean equals (Object aOther)
+ {
+ return (this == aOther) || (aOther!=null && aOther.equals(mxContext));
+ }
+
+
+ /** iterate over handlers until the child is found */
+ public void getActions(Vector aActions)
+ {
+ for(int i = 0; i < maHandlers.size(); i++)
+ {
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ NodeHandler aHandler = aDescriptor.maHandler;
+ String[] aHandlerActions = aHandler.getActions (this);
+ for(int j = 0; j < aHandlerActions.length; j++ )
+ {
+ aActions.add( aHandlerActions[j] );
+ }
+ }
+ }
+
+ public void performAction( int nIndex )
+ {
+ if( nIndex >= 0 )
+ {
+ for(int i = 0; i < maHandlers.size(); i++)
+ {
+ // check if this handler has the child, and if not
+ // search with next handler
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ NodeHandler aHandler = aDescriptor.maHandler;
+ int nCount = aHandler.getActions(this).length;
+ if( nCount > nIndex )
+ {
+ aHandler.performAction(this, nIndex );
+ return;
+ }
+ else
+ nIndex -= nCount;
+ }
+ }
+ }
+
+ /** Try to add the specified accessible object as new accessible child of the
+ AccessibleTreeHandler.
+ Note that child is used in another context than
+ it is used in the other methods of this class.
+ */
+ public AccessibleTreeNode addAccessibleChild (XAccessible xChild)
+ {
+ for(int i = 0; i < maHandlers.size(); i++)
+ {
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ if (aDescriptor.maHandler instanceof AccessibleTreeHandler)
+ {
+ AccessibleTreeHandler aHandler = (AccessibleTreeHandler)aDescriptor.maHandler;
+ AccessibleTreeNode aNode = aHandler.addAccessibleChild (this, xChild);
+ aDescriptor.mnChildCount = aHandler.getChildCount (this);
+ return aNode;
+ }
+ }
+ return null;
+ }
+
+ /** Update the specified handlers.
+ @return
+ The returned array containes the indices of the updated children
+ and can be used to create a TreeModelEvent.
+ */
+ public Vector updateChildren (java.lang.Class class1)
+ {
+ return updateChildren (class1, null);
+ }
+
+ public Vector updateChildren (java.lang.Class class1, java.lang.Class class2)
+ {
+ Vector aChildIndices = new Vector();
+ int nOffset = 0;
+ for(int i=0; i < maHandlers.size(); i++)
+ {
+ HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
+ if ((class1.isInstance(aDescriptor.maHandler))
+ || (class2 !=null && class2.isInstance(aDescriptor.maHandler)))
+ {
+ aDescriptor.maHandler.update(this);
+ // Get updated number of children.
+ int nChildCount = aDescriptor.maHandler.getChildCount (this);
+ aDescriptor.mnChildCount = nChildCount;
+ // Fill in the indices of the updated children.
+ for (int j=0; j<nChildCount; j++)
+ aChildIndices.add(new Integer(j+nOffset));
+ }
+ nOffset += aDescriptor.mnChildCount;
+ }
+ return aChildIndices;
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibilityTree.java b/toolkit/test/accessibility/AccessibilityTree.java
new file mode 100755
index 000000000000..819631b41eb8
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibilityTree.java
@@ -0,0 +1,377 @@
+import com.sun.star.accessibility.*;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.uno.UnoRuntime;
+
+import java.util.Vector;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.tree.*;
+import javax.swing.event.*;
+
+
+
+/** This is the tree component that is responsible for displaying the
+ contents of the tree model on the screen.
+*/
+public class AccessibilityTree
+ implements TreeExpansionListener, TreeWillExpandListener
+{
+ /** Create a new accessibility tree. Use the specified message display
+ for displaying messages and the specified canvas to draw the
+ graphical representations of accessible objects on.
+ */
+ public AccessibilityTree ()
+ {
+ maTree = new JTree ();
+
+ AccessibilityTreeModel aModel =
+ new AccessibilityTreeModel (
+ new StringNode ("Please press Update button", null));
+ maTree.setModel (aModel);
+
+ maCellRenderer = new AccessibleTreeCellRenderer();
+ // setCellRenderer (maCellRenderer);
+
+ // allow editing of XAccessibleText interfaces
+ // setEditable (true);
+ // maTreeModel.addTreeModelListener( new TextUpdateListener() );
+
+ maTree.addMouseListener (new MouseListener (this));
+
+ // Listen to expansions and collapses to change the mouse cursor.
+ mnExpandLevel = 0;
+ maTree.addTreeWillExpandListener (this);
+ maTree.addTreeExpansionListener (this);
+ }
+
+ public JTree getComponent ()
+ {
+ return maTree;
+ }
+
+ // Change cursor during expansions to show the user that this is a
+ // lengthy operation.
+ public void treeWillExpand (TreeExpansionEvent e)
+ {
+ if (mnExpandLevel == 0)
+ {
+ maTree.setCursor (new Cursor (Cursor.WAIT_CURSOR));
+ }
+ mnExpandLevel += 1;
+ }
+ public void treeWillCollapse (TreeExpansionEvent e)
+ {
+ if (mnExpandLevel == 0)
+ {
+ maTree.setCursor (new Cursor (Cursor.WAIT_CURSOR));
+ }
+ mnExpandLevel += 1;
+ }
+ public void treeExpanded (TreeExpansionEvent e)
+ {
+ mnExpandLevel -= 1;
+ if (mnExpandLevel == 0)
+ {
+ maTree.setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
+ }
+ }
+ public void treeCollapsed (TreeExpansionEvent e)
+ {
+ mnExpandLevel -= 1;
+ if (mnExpandLevel == 0)
+ {
+ maTree.setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
+ }
+ }
+
+
+
+ public void SetCanvas (Canvas aCanvas)
+ {
+ maCanvas = aCanvas;
+ ((AccessibilityTreeModel)maTree.getModel()).setCanvas (maCanvas);
+ }
+
+ /** Expand the nodes in the subtree rooted in aNode according to the the
+ specified expander. The tree is locked during the expansion.
+ */
+ protected void expandTree (AccessibleTreeNode aNode, Expander aExpander)
+ {
+ if (mnExpandLevel == 0)
+ {
+ maTree.setEnabled (false);
+ }
+ mnExpandLevel += 1;
+
+ ((AccessibilityTreeModel)maTree.getModel()).lock ();
+
+ try
+ {
+ expandTree (new TreePath (aNode.createPath()), aExpander);
+ }
+ catch (Exception e)
+ {
+ // Ignore
+ }
+
+ mnExpandLevel -= 1;
+ if (mnExpandLevel == 0)
+ {
+ maTree.setEnabled (true);
+ ((AccessibilityTreeModel)maTree.getModel()).unlock (aNode);
+ }
+ }
+
+ private TreePath expandTree( TreePath aPath, Expander aExpander )
+ {
+ // return first expanded object
+ TreePath aFirst = null;
+
+ // System.out.print ("e");
+
+ try
+ {
+ // get 'our' object
+ Object aObj = aPath.getLastPathComponent();
+
+ // expand this object, if the Expander tells us so
+ if( aExpander.expand( aObj ) )
+ {
+ maTree.expandPath (aPath);
+ if( aFirst == null )
+ aFirst = aPath;
+ }
+
+ // visit all children
+ if (aObj instanceof AccessibleTreeNode)
+ {
+ AccessibleTreeNode aNode = (AccessibleTreeNode)aObj;
+ int nLength = aNode.getChildCount();
+ for( int i = 0; i < nLength; i++ )
+ {
+ TreePath aRet = expandTree(
+ aPath.pathByAddingChild( aNode.getChild( i ) ),
+ aExpander );
+ if( aFirst == null )
+ aFirst = aRet;
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception while expanding tree path "
+ + aPath + ": " + e);
+ e.printStackTrace ();
+ }
+
+ return aFirst;
+ }
+
+
+ /** Expand all nodes and their subtrees that represent shapes. Call
+ * this method from the outside. */
+ public void expandShapes ()
+ {
+ expandShapes ((AccessibleTreeNode)maTree.getModel().getRoot());
+ }
+ public void expandShapes (AccessibleTreeNode aNode)
+ {
+ expandTree (aNode, new ShapeExpander());
+ }
+
+ /** Expand all nodes */
+ public void expandAll ()
+ {
+ expandAll ((AccessibleTreeNode)maTree.getModel().getRoot());
+ }
+ public void expandAll (AccessibleTreeNode aNode)
+ {
+ expandTree (aNode, new AllExpander());
+ }
+
+
+
+ public void disposing (com.sun.star.lang.EventObject e)
+ {
+ System.out.println ("disposing " + e);
+ }
+
+ /*
+ public Dimension getPreferredSize ()
+ {
+ Dimension aPreferredSize = super.getPreferredSize();
+ Dimension aMinimumSize = super.getMinimumSize();
+ if (aPreferredSize.width < aMinimumSize.width)
+ aPreferredSize.width = aMinimumSize.width;
+ return aPreferredSize;
+ }
+ */
+
+ class MouseListener extends MouseAdapter
+ {
+ public MouseListener (AccessibilityTree aTree)
+ {
+ maTree=aTree;
+ }
+ public void mousePressed(MouseEvent e) { popupTrigger(e); }
+ public void mouseClicked(MouseEvent e) { popupTrigger(e); }
+ public void mouseEntered(MouseEvent e) { popupTrigger(e); }
+ public void mouseExited(MouseEvent e) { popupTrigger(e); }
+ public void mouseReleased(MouseEvent e) { popupTrigger(e); }
+
+ public boolean popupTrigger( MouseEvent e )
+ {
+ boolean bIsPopup = e.isPopupTrigger();
+ if( bIsPopup )
+ {
+ int selRow = maTree.getComponent().getRowForLocation(e.getX(), e.getY());
+ if (selRow != -1)
+ {
+ TreePath aPath = maTree.getComponent().getPathForLocation(e.getX(), e.getY());
+
+ // check for actions
+ Object aObject = aPath.getLastPathComponent();
+ JPopupMenu aMenu = new JPopupMenu();
+ if( aObject instanceof AccTreeNode )
+ {
+ AccTreeNode aNode = (AccTreeNode)aObject;
+
+ Vector aActions = new Vector();
+ aMenu.add (new AccessibilityTree.ShapeExpandAction(maTree, aNode));
+ aMenu.add (new AccessibilityTree.SubtreeExpandAction(maTree, aNode));
+
+ aNode.getActions(aActions);
+ for( int i = 0; i < aActions.size(); i++ )
+ {
+ aMenu.add( new NodeAction(
+ aActions.elementAt(i).toString(),
+ aNode, i ) );
+ }
+ }
+ else if (aObject instanceof AccessibleTreeNode)
+ {
+ AccessibleTreeNode aNode = (AccessibleTreeNode)aObject;
+ String[] aActionNames = aNode.getActions();
+ int nCount=aActionNames.length;
+ if (nCount > 0)
+ {
+ for (int i=0; i<nCount; i++)
+ aMenu.add( new NodeAction(
+ aActionNames[i],
+ aNode,
+ i));
+ }
+ else
+ aMenu = null;
+ }
+ if (aMenu != null)
+ aMenu.show (maTree.getComponent(),
+ e.getX(), e.getY());
+ }
+ }
+
+ return bIsPopup;
+ }
+
+ private AccessibilityTree maTree;
+ }
+
+ class NodeAction extends AbstractAction
+ {
+ private int mnIndex;
+ private AccessibleTreeNode maNode;
+
+ public NodeAction( String aName, AccessibleTreeNode aNode, int nIndex )
+ {
+ super( aName );
+ maNode = aNode;
+ mnIndex = nIndex;
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ maNode.performAction(mnIndex);
+ }
+ }
+
+ // This action expands all shapes in the subtree rooted in the specified node.
+ class ShapeExpandAction extends AbstractAction
+ {
+ private AccessibilityTree maTree;
+ private AccTreeNode maNode;
+ public ShapeExpandAction (AccessibilityTree aTree, AccTreeNode aNode)
+ {
+ super ("Expand Shapes");
+ maTree = aTree;
+ maNode = aNode;
+ }
+ public void actionPerformed (ActionEvent e)
+ {
+ maTree.expandShapes (maNode);
+ }
+ }
+
+ // This action expands all nodes in the subtree rooted in the specified node.
+ class SubtreeExpandAction extends AbstractAction
+ {
+ private AccessibilityTree maTree;
+ private AccTreeNode maNode;
+ public SubtreeExpandAction (AccessibilityTree aTree, AccTreeNode aNode)
+ {
+ super ("Expand Subtree");
+ maTree = aTree;
+ maNode = aNode;
+ }
+ public void actionPerformed (ActionEvent e)
+ {
+ maTree.expandAll (maNode);
+ }
+ }
+
+ /** Predicate class to determine whether a node should be expanded
+ * For use with expandTree method */
+ abstract class Expander
+ {
+ abstract public boolean expand (Object aObject);
+ }
+
+ /** expand all nodes */
+ class AllExpander extends Expander
+ {
+ public boolean expand(Object aObject) { return true; }
+ }
+
+ /** expand all nodes with accessibility roles > 100 */
+ class ShapeExpander extends Expander
+ {
+ public boolean expand (Object aObject)
+ {
+ if (aObject instanceof AccTreeNode)
+ {
+ AccTreeNode aNode = (AccTreeNode)aObject;
+ XAccessibleContext xContext = aNode.getContext();
+ if (xContext != null)
+ if (xContext.getAccessibleRole() >= 100)
+ return true;
+ }
+ return false;
+ }
+ }
+
+
+
+ protected AccessibleTreeCellRenderer
+ maCellRenderer;
+
+
+ private JTree
+ maTree;
+ private Canvas
+ maCanvas;
+ private boolean
+ mbFirstShapeSeen;
+ private int
+ mnExpandLevel;
+}
diff --git a/toolkit/test/accessibility/AccessibilityTreeModel.java b/toolkit/test/accessibility/AccessibilityTreeModel.java
new file mode 100644
index 000000000000..d4981e86b4a0
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibilityTreeModel.java
@@ -0,0 +1,513 @@
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreePath;
+
+
+import java.util.Vector;
+import java.util.HashMap;
+import java.util.Enumeration;
+
+import com.sun.star.accessibility.*;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.Any;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.XServiceName;
+
+public class AccessibilityTreeModel
+ extends AccessibilityTreeModelBase
+{
+ public boolean mbVerbose = false;
+
+ public AccessibilityTreeModel (AccessibleTreeNode aRoot)
+ {
+ // create default node (unless we have a 'proper' node)
+ if( ! (aRoot instanceof AccessibleTreeNode) )
+ aRoot = new StringNode ("Root", null);
+ setRoot (aRoot);
+
+ maNodeMap = new NodeMap();
+
+ maEventListener = new EventListener (this);
+ mxListener = new QueuedListener (maEventListener);
+ }
+
+ public void clear ()
+ {
+ maNodeMap.Clear();
+ }
+
+ /** Lock the tree. While the tree is locked, events from the outside are
+ not processed. Lock the tree when you change its internal structure.
+ */
+ public void lock ()
+ {
+ mnLockCount += 1;
+ }
+
+ /** Unlock the tree. After unlocking the tree as many times as locking
+ it, a treeStructureChange event is sent to the event listeners.
+ @param aNodeHint
+ If not null and treeStructureChange events are thrown then this
+ node is used as root of the modified subtree.
+ */
+ public void unlock (AccessibleTreeNode aNodeHint)
+ {
+ mnLockCount -= 1;
+ if (mnLockCount == 0)
+ fireTreeStructureChanged (
+ new TreeModelEvent (this,
+ new TreePath (aNodeHint.createPath())));
+ }
+
+
+
+
+ /** Inform all listeners (especially the renderer) of a change of the
+ tree's structure.
+ @param aNode This node specifies the sub tree in which all changes
+ take place.
+ */
+ public void FireTreeStructureChanged (AccessibleTreeNode aNode)
+ {
+ }
+
+
+
+
+
+ public synchronized void setRoot (AccessibleTreeNode aRoot)
+ {
+ if (getRoot() == null)
+ super.setRoot (aRoot);
+ else
+ {
+ lock ();
+ maNodeMap.ForEach (new NodeMapCallback () {
+ public void Apply (AccTreeNode aNode)
+ {
+ if (maCanvas != null)
+ maCanvas.removeNode (aNode);
+ removeAccListener ((AccTreeNode)aNode);
+ }
+ });
+ maNodeMap.Clear ();
+
+ setRoot (aRoot);
+ unlock (aRoot);
+ }
+ }
+
+
+ //
+ // child management:
+ //
+
+
+
+ /** Delegate the request to the parent and then register listeners at
+ the child and add the child to the canvas.
+ */
+ public Object getChild (Object aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = (AccessibleTreeNode)super.getChild (aParent, nIndex);
+
+ if (aChild == null)
+ System.out.println ("getChild: child not found");
+ else
+ // Keep translation table up-to-date.
+ addNode (aChild);
+
+ return aChild;
+ }
+
+ public Object getChildNoCreate (Object aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = (AccessibleTreeNode)super.getChildNoCreate (aParent, nIndex);
+
+ return aChild;
+ }
+
+
+
+
+ /** Remove a node (and all children) from the tree model.
+ */
+ protected boolean removeChild (AccessibleTreeNode aNode)
+ {
+ try
+ {
+ if( aNode == null )
+ {
+ System.out.println ("can't remove null node");
+ return false;
+ }
+ else
+ {
+ // depth-first removal of children
+ while (aNode.getChildCount() > 0)
+ if ( ! removeChild (aNode.getChildNoCreate (0)))
+ break;
+
+ // Remove node from its parent.
+ AccessibleTreeNode aParent = aNode.getParent();
+ if (aParent != null)
+ {
+ int nIndex = aParent.indexOf(aNode);
+ aParent.removeChild (nIndex);
+ }
+
+ maNodeMap.RemoveNode (aNode);
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception while removing child "
+ + aNode + " : " + e);
+ e.printStackTrace ();
+ return false;
+ }
+ return true;
+ }
+
+ public void removeNode (XAccessibleContext xNode)
+ {
+ if (xNode != null)
+ {
+ AccessibleTreeNode aNode = maNodeMap.GetNode (xNode);
+ AccessibleTreeNode aRootNode = (AccessibleTreeNode)getRoot();
+ TreeModelEvent aEvent = createEvent (aRootNode, aNode);
+ removeChild (aNode);
+ if (mbVerbose)
+ System.out.println (aNode);
+ fireTreeNodesRemoved (aEvent);
+ maCanvas.repaint ();
+ }
+ }
+
+
+ /** Add add a new child to a parent.
+ @return
+ Returns the new or existing representation of the specified
+ accessible object.
+ */
+ protected AccessibleTreeNode addChild (AccTreeNode aParentNode, XAccessible xNewChild)
+ {
+ AccessibleTreeNode aChildNode = null;
+ try
+ {
+ boolean bRet = false;
+
+ // First make sure that the accessible object does not already have
+ // a representation.
+ aChildNode = maNodeMap.GetNode(xNewChild);
+ if (aChildNode == null)
+ aChildNode = aParentNode.addAccessibleChild (xNewChild);
+ else
+ System.out.println ("node already present");
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception while adding child "
+ + xNewChild + " to parent " + aParentNode + ": " + e);
+ e.printStackTrace ();
+ }
+ return aChildNode;
+ }
+
+ public void addChild (XAccessibleContext xParent, XAccessible xChild)
+ {
+ AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent);
+ if (aParentNode instanceof AccTreeNode)
+ {
+ AccessibleTreeNode aChild = addChild ((AccTreeNode)aParentNode, xChild);
+ if (addNode (aChild))
+ {
+ if (maCanvas != null)
+ maCanvas.updateNode ((AccTreeNode)aParentNode);
+
+ // A call to fireTreeNodesInserted for xNew
+ // should be sufficient but at least the
+ // StringNode object that contains the number of
+ // children also changes and we do not know its
+ // index relative to its parent. Therefore the
+ // more expensive fireTreeStructureChanged is
+ // necessary.
+ fireTreeNodesInserted (createEvent (xParent, xChild));
+ updateNode (xParent, AccessibleTreeHandler.class);
+ }
+ maCanvas.repaint ();
+ }
+ }
+
+
+ /** Add the child node to the internal tree structure.
+ @param aNode
+ The node to insert into the internal tree structure.
+ */
+ protected boolean addNode (AccessibleTreeNode aNode)
+ {
+ boolean bRet = false;
+ try
+ {
+ if ( ! maNodeMap.ValueIsMember (aNode))
+ {
+ if (aNode instanceof AccTreeNode)
+ {
+ AccTreeNode aChild = (AccTreeNode)aNode;
+ XAccessibleContext xChild = aChild.getContext();
+ registerAccListener (aChild);
+ if (maCanvas != null)
+ maCanvas.addNode (aChild);
+ maNodeMap.InsertNode (xChild, aChild);
+ }
+ bRet = true;
+ }
+
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception while adding node "
+ + aNode + ": " + e);
+ e.printStackTrace ();
+ }
+ return bRet;
+ }
+
+
+
+
+ /** create path to node, suitable for TreeModelEvent constructor
+ * @see javax.swing.event.TreeModelEvent#TreeModelEvent
+ */
+ protected Object[] createPath (AccessibleTreeNode aNode)
+ {
+ Vector aPath = new Vector();
+ aNode.createPath (aPath);
+ return aPath.toArray();
+ }
+
+ //
+ // listeners (and helper methods)
+ //
+ // We are registered with listeners as soon as objects are in the
+ // tree cache, and we should get removed as soon as they are out.
+ //
+
+ protected void fireTreeNodesChanged(TreeModelEvent e)
+ {
+ for(int i = 0; i < maTMListeners.size(); i++)
+ {
+ ((TreeModelListener)maTMListeners.get(i)).treeNodesChanged(e);
+ }
+ }
+
+ protected void fireTreeNodesInserted(final TreeModelEvent e)
+ {
+ for(int i = 0; i < maTMListeners.size(); i++)
+ {
+ ((TreeModelListener)maTMListeners.get(i)).treeNodesInserted(e);
+ }
+ }
+
+ protected void fireTreeNodesRemoved(final TreeModelEvent e)
+ {
+ for(int i = 0; i < maTMListeners.size(); i++)
+ {
+ ((TreeModelListener)maTMListeners.get(i)).treeNodesRemoved(e);
+ }
+ }
+
+ protected void fireTreeStructureChanged(final TreeModelEvent e)
+ {
+ for(int i = 0; i < maTMListeners.size(); i++)
+ {
+ ((TreeModelListener)maTMListeners.get(i)).treeStructureChanged(e);
+ }
+ }
+
+ protected TreeModelEvent createEvent (XAccessibleContext xParent)
+ {
+ AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent);
+ return new TreeModelEvent (this, createPath (aParentNode));
+ }
+
+ /** Create a TreeModelEvent object that informs listeners that one child
+ has been removed from or inserted into its parent.
+ */
+ public TreeModelEvent createEvent (XAccessibleContext xParent, XAccessible xChild)
+ {
+ AccessibleTreeNode aParentNode = maNodeMap.GetNode (xParent);
+ return createEvent (aParentNode, xParent);
+ }
+
+ public TreeModelEvent createEvent (AccessibleTreeNode aParentNode, XAccessibleContext xChild)
+ {
+ AccessibleTreeNode aChildNode = null;
+ if (xChild != null)
+ aChildNode = maNodeMap.GetNode (xChild);
+ return createEvent (aParentNode, aChildNode);
+ }
+
+
+
+ protected TreeModelEvent createEvent (
+ AccessibleTreeNode aParentNode,
+ AccessibleTreeNode aChildNode)
+ {
+ Object[] aPathToParent = createPath (aParentNode);
+
+ int nIndexInParent = -1;
+ if (aChildNode != null)
+ nIndexInParent = aParentNode.indexOf (aChildNode);
+ if (mbVerbose)
+ System.out.println (aChildNode + " " + nIndexInParent);
+
+ if (nIndexInParent == -1)
+ // This event may be passed only to treeStructureChanged of the listeners.
+ return new TreeModelEvent (this,
+ aPathToParent);
+ else
+ // General purpose event for removing or inserting known nodes.
+ return new TreeModelEvent (this,
+ aPathToParent,
+ new int[] {nIndexInParent},
+ new Object[] {aChildNode} );
+ }
+
+
+
+
+ /** Create a TreeModelEvent that indicates changes at those children of
+ the specified node with the specified indices.
+ */
+ protected TreeModelEvent createChangeEvent (AccTreeNode aNode, Vector aChildIndices)
+ {
+ // Build a list of child objects that are indicated by the given indices.
+ int nCount = aChildIndices.size();
+ Object aChildObjects[] = new Object[nCount];
+ int nChildIndices[] = new int[nCount];
+ for (int i=0; i<nCount; i++)
+ {
+ int nIndex = ((Integer)aChildIndices.elementAt(i)).intValue();
+ aChildObjects[i] = aNode.getChild (nIndex);
+ nChildIndices[i] = nIndex;
+ }
+
+ return new TreeModelEvent (this,
+ createPath(aNode),
+ nChildIndices,
+ aChildObjects);
+ }
+
+
+
+ /**
+ * broadcast a tree event in a seperate Thread
+ * must override fire method
+ */
+ class EventRunner implements Runnable
+ {
+ public void run()
+ {
+ for(int i = 0; i < maTMListeners.size(); i++)
+ {
+ fire( (TreeModelListener)maTMListeners.get(i) );
+ }
+ }
+
+ protected void fire( TreeModelListener l) { }
+ }
+
+
+
+ protected XAccessibleEventBroadcaster getBroadcaster (Object aObject)
+ {
+ if (aObject instanceof AccTreeNode)
+ return (XAccessibleEventBroadcaster) UnoRuntime.queryInterface (
+ XAccessibleEventBroadcaster.class, ((AccTreeNode)aObject).getContext());
+ else
+ return null;
+ }
+
+ protected void registerAccListener( Object aObject )
+ {
+ // register this as listener for XAccessibleEventBroadcaster
+ // implementations
+ XAccessibleEventBroadcaster xBroadcaster = getBroadcaster( aObject );
+ if (xBroadcaster != null)
+ {
+ xBroadcaster.addEventListener( mxListener );
+ }
+ }
+
+ protected void removeAccListener( Object aObject )
+ {
+ XAccessibleEventBroadcaster xBroadcaster = getBroadcaster( aObject );
+ if (xBroadcaster != null)
+ {
+ xBroadcaster.removeEventListener( mxListener );
+ }
+ }
+
+
+
+ public void setCanvas (Canvas aCanvas)
+ {
+ maCanvas = aCanvas;
+ }
+
+ public Canvas getCanvas ()
+ {
+ return maCanvas;
+ }
+
+ public void updateNode (XAccessibleContext xSource, java.lang.Class class1)
+ {
+ updateNode (xSource, class1,null);
+ }
+
+ /** Get a list of children of the node associated with xSource that are
+ affected by the given handlers. Fire events that these children may
+ have changed in the tree view. Update the canvas representation of
+ xSource.
+ */
+ public AccTreeNode updateNode (XAccessibleContext xSource,
+ java.lang.Class class1, java.lang.Class class2)
+ {
+ AccessibleTreeNode aTreeNode = maNodeMap.GetNode (xSource);
+ AccTreeNode aNode = null;
+ if (mbVerbose)
+ System.out.println ("updating node " + xSource + " " + aTreeNode);
+ if (aTreeNode instanceof AccTreeNode)
+ {
+ aNode = (AccTreeNode) aTreeNode;
+ // Get list of affected children.
+ Vector aChildIndices = (aNode).updateChildren (
+ class1, class2);
+ // Fire events that these children may have changed.
+ fireTreeNodesChanged (
+ createChangeEvent (aNode, aChildIndices));
+ }
+ return aNode;
+ }
+
+ /** The listener to be registered with the accessible objects.
+ * Could be set to 'this' for same-thread event delivery, or to an
+ * instance of QueuedListener for multi-threaded delivery. May
+ * not be changed, since this would trip the
+ * register/removeAccListener logic. */
+ private final XAccessibleEventListener mxListener;
+
+ // Map to translate from accessible object to corresponding tree node.
+ private NodeMap maNodeMap;
+
+ // If the lock count is higher then zero, then no events are processed.
+ private int mnLockCount;
+
+ private Canvas maCanvas;
+
+ private EventListener maEventListener;
+}
diff --git a/toolkit/test/accessibility/AccessibilityTreeModelBase.java b/toolkit/test/accessibility/AccessibilityTreeModelBase.java
new file mode 100644
index 000000000000..e80819bef840
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibilityTreeModelBase.java
@@ -0,0 +1,122 @@
+import javax.swing.tree.TreeModel;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreePath;
+import javax.swing.event.TreeModelEvent;
+import java.util.Vector;
+
+public class AccessibilityTreeModelBase
+ implements TreeModel
+{
+ public AccessibilityTreeModelBase ()
+ {
+ setRoot (null);
+ maTMListeners = new Vector();
+ }
+
+ public synchronized void addTreeModelListener(TreeModelListener l)
+ {
+ maTMListeners.add(l);
+ }
+
+ public synchronized void removeTreeModelListener(TreeModelListener l)
+ {
+ maTMListeners.remove(l);
+ }
+
+ public synchronized int getChildCount(Object aParent)
+ {
+ return (aParent instanceof AccessibleTreeNode) ?
+ ((AccessibleTreeNode)aParent).getChildCount() : 0;
+ }
+
+ public synchronized Object getChild (Object aParent, int nIndex)
+ {
+ Object aChild = null;
+ try
+ {
+ if (aParent != null && aParent instanceof AccessibleTreeNode)
+ aChild = ((AccessibleTreeNode)aParent).getChild(nIndex);
+ else
+ System.out.println ("getChild called for unknown parent node");
+ }
+ catch (com.sun.star.lang.IndexOutOfBoundsException e)
+ {
+ aChild = ("no child " + nIndex + " from " + aParent + ": " + e);
+ }
+ return aChild;
+ }
+
+ public synchronized Object getChildNoCreate (Object aParent, int nIndex)
+ {
+ Object aChild = null;
+ try
+ {
+ if (aParent != null && aParent instanceof AccessibleTreeNode)
+ aChild = ((AccessibleTreeNode)aParent).getChildNoCreate(nIndex);
+ else
+ System.out.println ("getChild called for unknown parent node");
+ }
+ catch (com.sun.star.lang.IndexOutOfBoundsException e)
+ { }
+ return aChild;
+ }
+
+ /** iterate over all children and look for child */
+ public synchronized int getIndexOfChild (Object aParent, Object aChild)
+ {
+ int nIndex = -1;
+ try
+ {
+ if ((aParent instanceof AccessibleTreeNode) && (aChild instanceof AccessibleTreeNode))
+ {
+ AccessibleTreeNode aParentNode = (AccessibleTreeNode) aParent;
+ AccessibleTreeNode aChildNode = (AccessibleTreeNode) aChild;
+
+ int nChildCount = aParentNode.getChildCount();
+ for( int i = 0; i < nChildCount; i++ )
+ {
+ if (aChildNode.equals (aParentNode.getChild (i)))
+ {
+ nIndex = i;
+ break;
+ }
+ }
+ }
+ }
+ catch (com.sun.star.lang.IndexOutOfBoundsException e)
+ {
+ // Return -1 by falling through.
+ }
+
+ // not found?
+ return nIndex;
+ }
+
+ public boolean isLeaf (Object aNode)
+ {
+ return (aNode instanceof AccessibleTreeNode) ?
+ ((AccessibleTreeNode)aNode).isLeaf() : true;
+ }
+
+
+
+ public synchronized Object getRoot()
+ {
+ return maRoot;
+ }
+
+ public void valueForPathChanged(TreePath path, Object newValue)
+ { }
+
+ protected synchronized void setRoot (AccessibleTreeNode aRoot)
+ {
+ maRoot = aRoot;
+ }
+
+
+ // The list of TreeModelListener objects.
+ protected Vector maTMListeners;
+
+ // The root node of the tree. Use setRoot to change it.
+ private AccessibleTreeNode maRoot = null;
+}
diff --git a/toolkit/test/accessibility/AccessibilityWorkBench.java b/toolkit/test/accessibility/AccessibilityWorkBench.java
new file mode 100755
index 000000000000..58ad607fed67
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibilityWorkBench.java
@@ -0,0 +1,620 @@
+import com.sun.star.awt.XWindow;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.PropertyChangeEvent;
+import com.sun.star.container.XEnumerationAccess;
+import com.sun.star.container.XEnumeration;
+import com.sun.star.document.XEventListener;
+import com.sun.star.drawing.XDrawPage;
+import com.sun.star.drawing.XDrawView;
+import com.sun.star.frame.XController;
+import com.sun.star.frame.XFrame;
+import com.sun.star.frame.XFrameActionListener;
+import com.sun.star.frame.FrameActionEvent;
+import com.sun.star.frame.FrameAction;
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.frame.XDesktop;
+import com.sun.star.frame.XModel;
+import com.sun.star.frame.XTerminateListener;
+import com.sun.star.uno.UnoRuntime;
+
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleComponent;
+import com.sun.star.accessibility.XAccessibleExtendedComponent;
+import com.sun.star.accessibility.XAccessibleRelationSet;
+import com.sun.star.accessibility.XAccessibleStateSet;
+
+import com.sun.star.awt.XExtendedToolkit;
+
+import java.util.Vector;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.tree.*;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import java.io.*;
+
+import ov.ObjectViewContainer;
+
+/** This class manages the GUI of the work bench.
+ @see AccessibilityTreeModel
+ for the implementation of the tree view on the left side which also
+ manages the registration of accessibility listeners.
+ @see Canvas
+ for the graphical view of the accessible objects.
+*/
+public class AccessibilityWorkBench
+ extends JFrame
+ implements ActionListener, XTerminateListener, TreeSelectionListener
+
+{
+ public static final String msVersion = "v1.7.2";
+ public String msOptionsFileName = ".AWBrc";
+
+ public static void main (String args[])
+ {
+ int nPortNumber = 5678;
+
+ for (int i=0; i<args.length; i++)
+ {
+ if (args[i].equals ("-h") || args[i].equals ("--help") || args[i].equals ("-?"))
+ {
+ System.out.println ("usage: AccessibilityWorkBench <option>*");
+ System.out.println ("options:");
+ System.out.println (" -p <port-number> Port on which to connect to StarOffice.");
+ System.out.println (" Defaults to 5678.");
+ System.exit (0);
+ }
+ else if (args[i].equals ("-p"))
+ {
+ nPortNumber = Integer.parseInt (args[++i]);
+ }
+ }
+
+ saWorkBench = new AccessibilityWorkBench (nPortNumber);
+ }
+
+
+
+
+ /** Return the one instance of the AccessibilityWorkBench
+ @return
+ Returns null when the AccessibilityWorkBench could not be
+ created successfully.
+ */
+ public static AccessibilityWorkBench Instance ()
+ {
+ return saWorkBench;
+ }
+
+
+
+ /** Create an accessibility work bench that listens at the specified
+ port to Office applications.
+ */
+ private AccessibilityWorkBench (int nPortNumber)
+ {
+ mbInitialized = false;
+
+ Layout ();
+
+ MessageArea.println (System.getProperty ("os.name") + " / "
+ + System.getProperty ("os.arch") + " / "
+ + System.getProperty ("os.version"));
+ MessageArea.println ("Using port " + nPortNumber);
+ office = new SimpleOffice (nPortNumber);
+ info = new InformationWriter ();
+
+ maAccessibilityTree.getComponent().addTreeSelectionListener (this);
+
+ addWindowListener (new WindowAdapter ()
+ { public void windowClosing (WindowEvent e)
+ { System.exit(0); }
+ });
+
+ initialize ();
+ }
+
+
+
+
+ /** Create and arrange the widgets of the GUI.
+ */
+ public void Layout ()
+ {
+ setSize (new Dimension (8000,600));
+
+ JScrollPane aScrollPane;
+ GridBagConstraints constraints;
+
+ // Create new layout.
+ GridBagLayout aLayout = new GridBagLayout ();
+ getContentPane().setLayout (aLayout);
+
+ // Accessible Tree.
+ maAccessibilityTree = new AccessibilityTree ();
+ // maAccessibilityTree.getComponent().setMinimumSize (new Dimension (250,300));
+ JScrollPane aTreeScrollPane = new JScrollPane(
+ maAccessibilityTree.getComponent(),
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ aTreeScrollPane.setPreferredSize (new Dimension (400,300));
+
+ // Object view shows details about the currently selected accessible
+ // object.
+ maObjectViewContainer = new ObjectViewContainer ();
+ // maObjectViewContainer.setPreferredSize (new Dimension (300,100));
+ JScrollPane aObjectViewContainerScrollPane = new JScrollPane(
+ maObjectViewContainer,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ aObjectViewContainerScrollPane.setPreferredSize (new Dimension (400,300));
+
+ // Split pane for tree view and object view.
+ JSplitPane aLeftViewSplitPane = new JSplitPane (
+ JSplitPane.VERTICAL_SPLIT,
+ aTreeScrollPane,
+ aObjectViewContainerScrollPane
+ );
+ aLeftViewSplitPane.setDividerLocation (300);
+
+ // Canvas.
+ maCanvas = new Canvas ();
+ maCanvas.setTree (maAccessibilityTree.getComponent());
+ maAccessibilityTree.SetCanvas (maCanvas);
+ JScrollPane aScrolledCanvas = new JScrollPane(maCanvas,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ aScrolledCanvas.getViewport().setBackground (Color.RED);
+ aScrolledCanvas.setPreferredSize (new Dimension(600,400));
+
+ // Split pane for tree view and canvas.
+ JSplitPane aViewSplitPane = new JSplitPane (
+ JSplitPane.HORIZONTAL_SPLIT,
+ aLeftViewSplitPane,
+ aScrolledCanvas
+ );
+ aViewSplitPane.setOneTouchExpandable(true);
+ aViewSplitPane.setDividerLocation (400);
+
+ // Text output area.
+ maMessageArea = MessageArea.Instance ();
+ // maMessageArea.setPreferredSize (new Dimension (300,50));
+
+ // Split pane for the two views and the message area.
+ JSplitPane aSplitPane = new JSplitPane (JSplitPane.VERTICAL_SPLIT,
+ aViewSplitPane, maMessageArea);
+ aSplitPane.setOneTouchExpandable(true);
+ addGridElement (aViewSplitPane, 0,0, 2,1, 3,3,
+ GridBagConstraints.CENTER, GridBagConstraints.BOTH);
+
+ // Button bar.
+ maButtonBar = new JPanel();
+ GridBagLayout aButtonLayout = new GridBagLayout ();
+ maButtonBar.setLayout (new FlowLayout());
+ addGridElement (maButtonBar, 0,3, 2,1, 1,0,
+ GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL);
+
+ // Buttons.
+ aConnectButton = createButton ("Connect", "connect");
+ aUpdateButton = createButton ("Update", "update");
+ aShapesButton = createButton ("Expand Shapes", "shapes");
+ aExpandButton = createButton ("Expand All", "expand");
+ aQuitButton = createButton ("Quit", "quit");
+ UpdateButtonStates ();
+
+ Options.Instance().Load (msOptionsFileName);
+
+ setJMenuBar (CreateMenuBar ());
+
+ setTitle("Accessibility Workbench " + msVersion);
+
+ pack ();
+ setVisible (true);
+ validate ();
+ repaint();
+ }
+
+
+
+
+ /** Shortcut method for adding an object to a GridBagLayout.
+ */
+ void addGridElement (JComponent object,
+ int x, int y, int width, int height, int weightx, int weighty,
+ int anchor, int fill)
+ {
+ GridBagConstraints constraints = new GridBagConstraints ();
+ constraints.gridx = x;
+ constraints.gridy = y;
+ constraints.gridwidth = width;
+ constraints.gridheight = height;
+ constraints.weightx = weightx;
+ constraints.weighty = weighty;
+ constraints.anchor = anchor;
+ constraints.fill = fill;
+ getContentPane().add (object, constraints);
+ }
+
+
+
+
+ /** Create a new button and place at the right most position into the
+ button bar.
+ */
+ public JButton createButton (String title, String command)
+ {
+ JButton aButton = new JButton (title);
+ aButton.setEnabled (false);
+ aButton.setActionCommand (command);
+ aButton.addActionListener (this);
+
+ maButtonBar.add (aButton);
+ return aButton;
+ }
+
+
+
+
+ /** Create a menu bar for the application.
+ @return
+ Returns the new menu bar. The returned reference is also
+ remembered in the data member <member>maMenuBar</member>.
+ */
+ JMenuBar CreateMenuBar ()
+ {
+ // Menu bar.
+ maMenuBar = new JMenuBar ();
+
+ // File menu.
+ JMenu aFileMenu = new JMenu ("File");
+ maMenuBar.add (aFileMenu);
+ JMenuItem aItem;
+ aItem = new JMenuItem ("Quit");
+ aFileMenu.add (aItem);
+ aItem.addActionListener (this);
+
+ // View menu.
+ JMenu aViewMenu = new JMenu ("View");
+ maMenuBar.add (aViewMenu);
+ ButtonGroup aGroup = new ButtonGroup ();
+ JRadioButtonMenuItem aRadioButton = new JRadioButtonMenuItem ("Whole Screen");
+ aGroup.add (aRadioButton);
+ aViewMenu.add (aRadioButton);
+ aRadioButton.addActionListener (this);
+ aRadioButton = new JRadioButtonMenuItem ("200%");
+ aGroup.add (aRadioButton);
+ aViewMenu.add (aRadioButton);
+ aRadioButton.addActionListener (this);
+ aRadioButton = new JRadioButtonMenuItem ("100%");
+ aGroup.add (aRadioButton);
+ aViewMenu.add (aRadioButton);
+ aRadioButton.addActionListener (this);
+ aRadioButton = new JRadioButtonMenuItem ("50%");
+ aGroup.add (aRadioButton);
+ aViewMenu.add (aRadioButton);
+ aRadioButton.addActionListener (this);
+ aRadioButton = new JRadioButtonMenuItem ("25%");
+ aGroup.add (aRadioButton);
+ aViewMenu.add (aRadioButton);
+ aRadioButton.addActionListener (this);
+ aRadioButton = new JRadioButtonMenuItem ("10%");
+ aGroup.add (aRadioButton);
+ aViewMenu.add (aRadioButton);
+ aRadioButton.addActionListener (this);
+
+ // Options menu.
+ JMenu aOptionsMenu = new JMenu ("Options");
+ maMenuBar.add (aOptionsMenu);
+ JCheckBoxMenuItem aCBItem;
+ aCBItem = new JCheckBoxMenuItem ("Show Descriptions", maCanvas.getShowDescriptions());
+ aOptionsMenu.add (aCBItem);
+ aCBItem.addActionListener (this);
+
+ aCBItem = new JCheckBoxMenuItem ("Show Names", maCanvas.getShowNames());
+ aOptionsMenu.add (aCBItem);
+ aCBItem.addActionListener (this);
+
+ aCBItem = new JCheckBoxMenuItem ("Show Text", maCanvas.getShowText());
+ aOptionsMenu.add (aCBItem);
+ aCBItem.addActionListener (this);
+
+ aCBItem = new JCheckBoxMenuItem ("Antialiased Rendering", maCanvas.getAntialiasing());
+ aOptionsMenu.add (aCBItem);
+ aCBItem.addActionListener (this);
+
+ // Help menu.
+ JMenu aHelpMenu = new JMenu ("Help");
+ maMenuBar.add (aHelpMenu);
+
+ aItem = new JMenuItem ("Help");
+ aHelpMenu.add (aItem);
+ aItem.addActionListener (this);
+
+ aItem = new JMenuItem ("News");
+ aHelpMenu.add (aItem);
+ aItem.addActionListener (this);
+
+ aItem = new JMenuItem ("About");
+ aHelpMenu.add (aItem);
+ aItem.addActionListener (this);
+
+ return maMenuBar;
+ }
+
+
+
+
+ /** Initialize the AWB. This includes clearing the canvas, add
+ listeners, creation of a new tree model for the tree list box and
+ the update of the button states.
+
+ This method may be called any number of times. Note that all
+ actions will be carried out every time. The main purpose of a
+ second call is that of a re-initialization after a reconnect.
+ */
+ protected void initialize ()
+ {
+ maCanvas.clear();
+
+ AccessibilityTreeModel aModel = null;
+ aModel = new AccessibilityTreeModel (createTreeModelRoot());
+
+ aModel.setCanvas (maCanvas);
+ maAccessibilityTree.getComponent().setModel (aModel);
+
+ if (office != null)
+ {
+ // Add terminate listener.
+ if (office.getDesktop() != null)
+ office.getDesktop().addTerminateListener (this);
+
+ XExtendedToolkit xToolkit = office.getExtendedToolkit();
+ // Remove old top window listener.
+ if (maTopWindowListener != null)
+ xToolkit.removeTopWindowListener (maQueuedTopWindowListener);
+ // Add top window listener.
+ if (xToolkit != null)
+ {
+ MessageArea.println ("registering at extended toolkit");
+ maTopWindowListener = new TopWindowListener (aModel, office);
+ maQueuedTopWindowListener = new QueuedTopWindowListener (maTopWindowListener);
+ xToolkit.addTopWindowListener (maQueuedTopWindowListener);
+ maTopWindowListener.Initialize ();
+ }
+ else
+ maTopWindowListener = null;
+ }
+
+ mbInitialized = true;
+ UpdateButtonStates ();
+ }
+
+
+
+
+ /** Update the states of the buttons according to the internal state of
+ the AWB.
+ */
+ protected void UpdateButtonStates ()
+ {
+ aConnectButton.setEnabled (mbInitialized);
+ aQuitButton.setEnabled (mbInitialized);
+ aUpdateButton.setEnabled (mbInitialized);
+ aExpandButton.setEnabled (mbInitialized);
+ aShapesButton.setEnabled (mbInitialized);
+ }
+
+
+
+ /** Callback for GUI actions from the buttons.
+ */
+ public void actionPerformed (java.awt.event.ActionEvent e)
+ {
+ if (e.getActionCommand().equals("connect"))
+ {
+ office.connect();
+ initialize ();
+ }
+ else if (e.getActionCommand().equals("quit"))
+ {
+ AccessibilityTreeModel aModel = (AccessibilityTreeModel)maAccessibilityTree.getComponent().getModel();
+ aModel.clear();
+ System.exit (0);
+ }
+ else if (e.getActionCommand().equals("update"))
+ {
+ initialize ();
+ }
+ else if (e.getActionCommand().equals("shapes"))
+ {
+ Cursor aCursor = getCursor();
+ setCursor (new Cursor (Cursor.WAIT_CURSOR));
+ maAccessibilityTree.expandShapes();
+ setCursor (aCursor);
+ }
+ else if (e.getActionCommand().equals("expand"))
+ {
+ Cursor aCursor = getCursor();
+ setCursor (new Cursor (Cursor.WAIT_CURSOR));
+ maAccessibilityTree.expandAll();
+ setCursor (aCursor);
+ }
+ else if (e.getActionCommand().equals ("Quit"))
+ {
+ System.out.println ("exiting");
+ System.exit (0);
+ }
+ else if (e.getActionCommand().equals ("Show Descriptions"))
+ {
+ maCanvas.setShowDescriptions ( ! maCanvas.getShowDescriptions());
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("Show Names"))
+ {
+ maCanvas.setShowNames ( ! maCanvas.getShowNames());
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("Antialiased Rendering"))
+ {
+ maCanvas.setAntialiasing ( ! maCanvas.getAntialiasing());
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("Help"))
+ {
+ HelpWindow.Instance().loadFile ("help.html");
+ }
+ else if (e.getActionCommand().equals ("News"))
+ {
+ try{
+ HelpWindow.Instance().loadFile ("news.html");
+ } catch (Exception ex) {}
+ }
+ else if (e.getActionCommand().equals ("About"))
+ {
+ HelpWindow.Instance().loadFile ("about.html");
+ }
+ else if (e.getActionCommand().equals ("Whole Screen"))
+ {
+ maCanvas.setZoomMode (Canvas.WHOLE_SCREEN);
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("200%"))
+ {
+ maCanvas.setZoomMode (200);
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("100%"))
+ {
+ maCanvas.setZoomMode (100);
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("50%"))
+ {
+ maCanvas.setZoomMode (50);
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("25%"))
+ {
+ maCanvas.setZoomMode (25);
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else if (e.getActionCommand().equals ("10%"))
+ {
+ maCanvas.setZoomMode (10);
+ Options.Instance().Save (msOptionsFileName);
+ }
+ else
+ {
+ System.err.println("unknown command " + e.getActionCommand());
+ }
+ }
+
+
+
+
+ /** Create an AccessibilityTreeModel root which contains the documents
+ (top windows) that are present at the moment.
+ */
+ private AccessibleTreeNode createTreeModelRoot()
+ {
+ // create root node
+ VectorNode aRoot = new VectorNode ("Accessibility Tree", null);
+ if (maTopWindowListener != null)
+ maTopWindowListener.Initialize ();
+ return aRoot;
+ }
+
+
+ // TreeSelectionListener
+ public void valueChanged (TreeSelectionEvent aEvent)
+ {
+ TreePath aPath = aEvent.getPath();
+ Object aObject = aPath.getLastPathComponent();
+ if (aObject instanceof AccTreeNode)
+ {
+ AccTreeNode aNode = (AccTreeNode) aObject;
+ XAccessibleContext xContext = aNode.getContext();
+ maObjectViewContainer.SetObject (xContext);
+ }
+ }
+
+
+
+
+ // XEventListener
+ public void disposing( com.sun.star.lang.EventObject aSourceObj )
+ {
+ XFrame xFrame = (XFrame)UnoRuntime.queryInterface(XFrame.class, aSourceObj.Source);
+
+ if( xFrame != null )
+ System.out.println("frame disposed");
+ else
+ System.out.println("controller disposed");
+ }
+
+
+
+
+ // XTerminateListener
+ public void queryTermination (final com.sun.star.lang.EventObject aEvent) throws RuntimeException
+ {
+ System.out.println ("Terminate Event : " + aEvent);
+ }
+
+
+
+
+ // XTerminateListener
+ public void notifyTermination (final com.sun.star.lang.EventObject aEvent) throws RuntimeException
+ {
+ System.out.println ("Notifiy Termination Event : " + aEvent);
+ }
+
+
+
+ /// The Singleton Workbench object.
+ private static AccessibilityWorkBench
+ saWorkBench = null;
+
+ protected SimpleOffice
+ office;
+ protected InformationWriter
+ info;
+
+ private XModel
+ mxModel;
+ private JPanel
+ maMainPanel,
+ maButtonBar;
+ private Canvas
+ maCanvas;
+ private AccessibilityTree
+ maAccessibilityTree;
+ private ObjectViewContainer
+ maObjectViewContainer;
+ private JScrollPane
+ maScrollPane;
+ private MessageArea
+ maMessageArea;
+ private JButton
+ aConnectButton,
+ aQuitButton,
+ aUpdateButton,
+ aExpandButton,
+ aShapesButton;
+ private JMenuBar
+ maMenuBar;
+ private String
+ msMessage;
+ private boolean
+ mbInitialized;
+ private TopWindowListener
+ maTopWindowListener;
+ private QueuedTopWindowListener
+ maQueuedTopWindowListener;
+}
diff --git a/toolkit/test/accessibility/AccessibleActionHandler.java b/toolkit/test/accessibility/AccessibleActionHandler.java
new file mode 100644
index 000000000000..0aac7158efde
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleActionHandler.java
@@ -0,0 +1,72 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleAction;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+class AccessibleActionHandler
+ extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleAction xEComponent =
+ (XAccessibleAction) UnoRuntime.queryInterface (
+ XAccessibleAction.class, xContext);
+ if (xEComponent != null)
+ return new AccessibleActionHandler (xEComponent);
+ else
+ return null;
+ }
+
+ public AccessibleActionHandler ()
+ {
+ }
+
+ public AccessibleActionHandler (XAccessibleAction xAction)
+ {
+ if (xAction != null)
+ maChildList.setSize (1 + xAction.getAccessibleActionCount());
+ }
+
+ protected static XAccessibleAction getAction (AccTreeNode aParent)
+ {
+ return (XAccessibleAction) UnoRuntime.queryInterface (
+ XAccessibleAction.class, aParent.getContext());
+ }
+
+ public AccessibleTreeNode createChild (
+ AccessibleTreeNode aParent,
+ int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+
+ if (aParent instanceof AccTreeNode)
+ {
+ XAccessibleAction xAction = getAction ((AccTreeNode)aParent);
+ if( xAction != null )
+ {
+ if (nIndex == 0)
+ aChild = new StringNode ("Number of actions: " + xAction.getAccessibleActionCount(),
+ aParent);
+ else
+ {
+ nIndex -= 1;
+ try
+ {
+ aChild = new AccessibleActionNode (
+ "Action " + nIndex + " : "
+ + xAction.getAccessibleActionDescription (nIndex),
+ aParent,
+ nIndex);
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aChild = new StringNode ("ERROR", aParent);
+ }
+ }
+ }
+ }
+
+ return aChild;
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleActionNode.java b/toolkit/test/accessibility/AccessibleActionNode.java
new file mode 100644
index 000000000000..7c72ac69803e
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleActionNode.java
@@ -0,0 +1,48 @@
+import javax.swing.JOptionPane;
+import com.sun.star.accessibility.XAccessibleAction;
+
+/**
+ Base class for all tree nodes.
+ */
+class AccessibleActionNode
+ extends StringNode
+{
+ public AccessibleActionNode (String aDisplayObject,
+ AccessibleTreeNode aParent,
+ int nActionIndex)
+ {
+ super (aDisplayObject, aParent);
+ mnActionIndex = nActionIndex;
+ }
+
+ public String[] getActions ()
+ {
+ return new String[] {"Perform Action"};
+ }
+
+ /** perform action */
+ public void performAction (int nIndex)
+ {
+ if (nIndex != 0)
+ return;
+ boolean bResult = false;
+ if (getParent() instanceof AccTreeNode)
+ try
+ {
+ bResult = AccessibleActionHandler.getAction(
+ (AccTreeNode)getParent()).doAccessibleAction (
+ mnActionIndex);
+ }
+ catch (com.sun.star.lang.IndexOutOfBoundsException e)
+ {
+ }
+
+ JOptionPane.showMessageDialog (null,
+ "performed action " + mnActionIndex
+ + (bResult?" with":" without") + " success",
+ "Action " + mnActionIndex,
+ JOptionPane.INFORMATION_MESSAGE);
+ }
+
+ private int mnActionIndex;
+}
diff --git a/toolkit/test/accessibility/AccessibleCellHandler.java b/toolkit/test/accessibility/AccessibleCellHandler.java
new file mode 100644
index 000000000000..19b4a9df67ad
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleCellHandler.java
@@ -0,0 +1,156 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleTable;
+import com.sun.star.accessibility.XAccessible;
+
+
+class AccessibleCellHandler extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ AccessibleCellHandler aCellHandler = null;
+ if (xContext != null)
+ {
+ XAccessible xParent = xContext.getAccessibleParent();
+ if (xParent != null)
+ {
+ XAccessibleTable xTable =
+ (XAccessibleTable) UnoRuntime.queryInterface (
+ XAccessibleTable.class, xParent.getAccessibleContext());
+ if (xTable != null)
+ aCellHandler = new AccessibleCellHandler (xTable);
+ }
+ }
+ return aCellHandler;
+
+ }
+
+ public AccessibleCellHandler ()
+ {
+ }
+
+ public AccessibleCellHandler (XAccessibleTable xTable)
+ {
+ if (xTable != null)
+ maChildList.setSize (8);
+ }
+
+ protected static XAccessibleTable getTable(Object aObject)
+ {
+ return (XAccessibleTable) UnoRuntime.queryInterface (
+ XAccessibleTable.class, aObject);
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+ XAccessibleTable xTable = null;
+ XAccessibleContext xContext = null;
+ AccessibleTreeNode aGrandParent = aParent.getParent();
+ if (aGrandParent instanceof AccTreeNode)
+ {
+ xTable = ((AccTreeNode)aGrandParent).getTable();
+ xContext = ((AccTreeNode)aGrandParent).getContext();
+ }
+ if (aParent instanceof AccTreeNode)
+ {
+ xContext = ((AccTreeNode)aParent).getContext();
+ }
+ try
+ {
+ if( xTable != null && xContext != null )
+ {
+ switch( nIndex )
+ {
+ case 0:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nRow = xTable.getAccessibleRow( nChild );
+
+ aChild = new StringNode ("# table row: " + nRow, aParent);
+ }
+ break;
+ case 1:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nCol = xTable.getAccessibleColumn( nChild );
+
+ aChild = new StringNode ("# table column: " + nCol, aParent);
+ }
+ break;
+ case 2:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nRow = xTable.getAccessibleRow( nChild );
+ int nCol = xTable.getAccessibleColumn( nChild );
+ int nExt = xTable.getAccessibleRowExtentAt( nRow, nCol );
+
+ aChild = new StringNode ("# table row extend: " + nExt, aParent);
+ }
+ break;
+ case 3:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nRow = xTable.getAccessibleRow( nChild );
+ int nCol = xTable.getAccessibleColumn( nChild );
+ int nExt = xTable.getAccessibleColumnExtentAt( nRow, nCol );
+
+ aChild = new StringNode ("# table column extend: " + nExt, aParent);
+ }
+ break;
+ case 4:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nRow = xTable.getAccessibleRow( nChild );
+ int nCol = xTable.getAccessibleColumn( nChild );
+ XAccessible xChild =
+ xTable.getAccessibleCellAt( nRow, nCol );
+
+ aChild = new StringNode ("# cell name retrieved from table: " + xChild.getAccessibleContext().getAccessibleName(), aParent);
+ }
+ break;
+ case 5:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nRow = xTable.getAccessibleRow( nChild );
+ int nCol = xTable.getAccessibleColumn( nChild );
+ boolean bSelected =
+ xTable.isAccessibleSelected( nRow, nCol );
+
+ aChild = new StringNode ("cell is selected: " + bSelected, aParent);
+ }
+ break;
+ case 6:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nRow = xTable.getAccessibleRow( nChild );
+ boolean bSelected =
+ xTable.isAccessibleRowSelected( nRow );
+
+ aChild = new StringNode ("table row is selected: " + bSelected, aParent);
+ }
+ break;
+ case 7:
+ {
+ int nChild = xContext.getAccessibleIndexInParent();
+ int nCol = xTable.getAccessibleColumn( nChild );
+ boolean bSelected =
+ xTable.isAccessibleColumnSelected( nCol );
+
+ aChild = new StringNode ("table column is selected: " + bSelected, aParent);
+ }
+ break;
+ default:
+ aChild = new StringNode ("unknown child index " + nIndex, aParent);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ // Return empty child.
+ }
+
+ return aChild;
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleComponentHandler.java b/toolkit/test/accessibility/AccessibleComponentHandler.java
new file mode 100644
index 000000000000..38e5545d23aa
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleComponentHandler.java
@@ -0,0 +1,102 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleComponent;
+
+
+class AccessibleComponentHandler
+ extends NodeHandler
+{
+
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleComponent xComponent =
+ (XAccessibleComponent) UnoRuntime.queryInterface (
+ XAccessibleComponent.class, xContext);
+ if (xComponent != null)
+ return new AccessibleComponentHandler (xComponent);
+ else
+ return null;
+
+ }
+
+ public AccessibleComponentHandler ()
+ {
+ }
+
+ public AccessibleComponentHandler (XAccessibleComponent xComponent)
+ {
+ if (xComponent != null)
+ maChildList.setSize (6);
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+ if (aParent instanceof AccTreeNode)
+ {
+ XAccessibleComponent xComponent =
+ ((AccTreeNode)aParent).getComponent();
+
+ if (xComponent != null)
+ {
+ int nColor;
+ switch (nIndex)
+ {
+ case 0:
+ com.sun.star.awt.Point aLocation = xComponent.getLocation();
+ aChild = new StringNode (
+ "Location: " + aLocation.X + ", " + aLocation.Y,
+ aParent);
+ break;
+ case 1:
+ com.sun.star.awt.Point aScreenLocation = xComponent.getLocationOnScreen();
+ aChild = new StringNode (
+ "Location on Screen: " + aScreenLocation.X + ", " + aScreenLocation.Y,
+ aParent);
+ break;
+ case 2:
+ com.sun.star.awt.Size aSize = xComponent.getSize();
+ aChild = new StringNode (
+ "Size: "+ aSize.Width + ", " + aSize.Height,
+ aParent);
+ break;
+ case 3:
+ com.sun.star.awt.Rectangle aBBox = xComponent.getBounds();
+ aChild = new StringNode (
+ "Bounding Box: "+ aBBox.X + ", " + aBBox.Y + ","
+ + aBBox.Width + ", " + aBBox.Height,
+ aParent);
+ break;
+ case 4:
+ nColor = xComponent.getForeground();
+ aChild = new StringNode ("Foreground color: R"
+ + (nColor>>16&0xff)
+ + "G" + (nColor>>8&0xff)
+ + "B" + (nColor>>0&0xff)
+ + "A" + (nColor>>24&0xff),
+ aParent);
+ break;
+ case 5:
+ nColor = xComponent.getBackground();
+ aChild = new StringNode ("Background color: R"
+ + (nColor>>16&0xff)
+ + "G" + (nColor>>8&0xff)
+ + "B" + (nColor>>0&0xff)
+ + "A" + (nColor>>24&0xff),
+ aParent);
+ break;
+ }
+ }
+ }
+ return aChild;
+ }
+
+ public void update (AccessibleTreeNode aNode)
+ {
+ maChildList.clear();
+ if (aNode instanceof AccTreeNode)
+ if (((AccTreeNode)aNode).getComponent() != null)
+ maChildList.setSize (4);
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleContextHandler.java b/toolkit/test/accessibility/AccessibleContextHandler.java
new file mode 100644
index 000000000000..fd22bcd5367f
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleContextHandler.java
@@ -0,0 +1,91 @@
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleStateSet;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.container.XIndexAccess;
+import java.util.HashMap;
+
+import tools.NameProvider;
+
+class AccessibleContextHandler
+ extends NodeHandler
+{
+ protected int nChildrenCount;
+
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ if (xContext != null)
+ return new AccessibleContextHandler (xContext);
+ else
+ return null;
+ }
+
+ public AccessibleContextHandler ()
+ {
+ super ();
+ }
+
+ public AccessibleContextHandler (XAccessibleContext xContext)
+ {
+ super();
+ if (xContext != null)
+ maChildList.setSize (4);
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ XAccessibleContext xContext = null;
+ if (aParent instanceof AccTreeNode)
+ xContext = ((AccTreeNode)aParent).getContext();
+
+ String sChild = new String();
+ if (xContext != null)
+ {
+ switch( nIndex )
+ {
+ case 0:
+ sChild = "Description: " +
+ xContext.getAccessibleDescription();
+ break;
+ case 1:
+ int nRole = xContext.getAccessibleRole();
+ sChild = "Role: " + nRole + " (" + NameProvider.getRoleName(nRole) + ")";
+ break;
+ case 2:
+ XAccessible xParent = xContext.getAccessibleParent();
+ sChild = "Has parent: " + (xParent!=null ? "yes" : "no");
+ /* if (xParent != ((AccTreeNode)aParent).getAccessible())
+ {
+ sChild += " but that is inconsistent"
+ + "#" + xParent + " # " + ((AccTreeNode)aParent).getAccessible();
+ }
+ */
+ break;
+ case 3:
+ sChild = "";
+ XAccessibleStateSet xStateSet =
+ xContext.getAccessibleStateSet();
+ if (xStateSet != null)
+ {
+ for (short i=0; i<=30; i++)
+ {
+ if (xStateSet.contains (i))
+ {
+ if (sChild.compareTo ("") != 0)
+ sChild += ", ";
+ sChild += NameProvider.getStateName(i);
+ }
+ }
+ }
+ else
+ sChild += "no state set";
+ sChild = "State set: " + sChild;
+
+ /* case 3:
+ sChild = "Child count: " + xContext.getAccessibleChildCount();
+ break;*/
+ }
+ }
+ return new StringNode (sChild, aParent);
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleEditableTextHandler.java b/toolkit/test/accessibility/AccessibleEditableTextHandler.java
new file mode 100644
index 000000000000..a79158c099ba
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleEditableTextHandler.java
@@ -0,0 +1,40 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleEditableText;
+
+
+class AccessibleEditableTextHandler extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleEditableText xText =
+ (XAccessibleEditableText) UnoRuntime.queryInterface (
+ XAccessibleEditableText.class, xContext);
+ if (xText != null)
+ return new AccessibleEditableTextHandler (xText);
+ else
+ return null;
+ }
+
+ public AccessibleEditableTextHandler ()
+ {
+ }
+
+ public AccessibleEditableTextHandler (XAccessibleEditableText xText)
+ {
+ if (xText != null)
+ maChildList.setSize (1);
+ }
+
+ protected static XAccessibleEditableText getEText (AccTreeNode aNode)
+ {
+ return (XAccessibleEditableText) UnoRuntime.queryInterface (
+ XAccessibleEditableText.class, aNode.getContext());
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ return new StringNode ("XAccessibleEditableText is supported", aParent);
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleExtendedComponentHandler.java b/toolkit/test/accessibility/AccessibleExtendedComponentHandler.java
new file mode 100644
index 000000000000..7f9fc17b23a5
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleExtendedComponentHandler.java
@@ -0,0 +1,73 @@
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleExtendedComponent;
+
+
+class AccessibleExtendedComponentHandler
+ extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleExtendedComponent xEComponent =
+ (XAccessibleExtendedComponent) UnoRuntime.queryInterface (
+ XAccessibleExtendedComponent.class, xContext);
+ if (xEComponent != null)
+ return new AccessibleExtendedComponentHandler (xEComponent);
+ else
+ return null;
+ }
+
+ public AccessibleExtendedComponentHandler ()
+ {
+ }
+
+ public AccessibleExtendedComponentHandler (XAccessibleExtendedComponent xEComponent)
+ {
+ if (xEComponent != null)
+ maChildList.setSize (0);
+ }
+
+ private static XAccessibleExtendedComponent getComponent (AccTreeNode aNode)
+ {
+ return (XAccessibleExtendedComponent) UnoRuntime.queryInterface (
+ XAccessibleExtendedComponent.class,
+ aNode.getContext());
+ }
+
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+ if (aParent instanceof AccTreeNode)
+ {
+ XAccessibleExtendedComponent xEComponent = getComponent ((AccTreeNode)aParent);
+
+ if (xEComponent != null)
+ {
+ int nColor;
+ switch( nIndex )
+ {
+ case 0:
+ nColor = xEComponent.getForeground();
+ aChild = new StringNode ("Depricated Foreground color: R"
+ + (nColor>>16&0xff)
+ + "G" + (nColor>>8&0xff)
+ + "B" + (nColor>>0&0xff)
+ + "A" + (nColor>>24&0xff),
+ aParent);
+ break;
+ case 1:
+ nColor = xEComponent.getBackground();
+ aChild = new StringNode ("Depricated Background color: R"
+ + (nColor>>16&0xff)
+ + "G" + (nColor>>8&0xff)
+ + "B" + (nColor>>0&0xff)
+ + "A" + (nColor>>24&0xff),
+ aParent);
+ break;
+ }
+ }
+ }
+ return aChild;
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleHyperlinkHandler.java b/toolkit/test/accessibility/AccessibleHyperlinkHandler.java
new file mode 100644
index 000000000000..674331317f7e
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleHyperlinkHandler.java
@@ -0,0 +1,42 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleHyperlink;
+
+
+class AccessibleHyperlinkHandler extends AccessibleTreeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleHyperlink xLink =
+ (XAccessibleHyperlink) UnoRuntime.queryInterface (
+ XAccessibleHyperlink.class, xContext);
+ if (xLink != null)
+ return new AccessibleHyperlinkHandler (xLink);
+ else
+ return null;
+ }
+
+ public AccessibleHyperlinkHandler ()
+ {
+ }
+
+ public AccessibleHyperlinkHandler (XAccessibleHyperlink xLink)
+ {
+ if (xLink != null)
+ maChildList.setSize (1);
+ }
+
+ protected XAccessibleHyperlink getHyperlink(Object aObject)
+ {
+ XAccessibleHyperlink xHyperlink =
+ (XAccessibleHyperlink) UnoRuntime.queryInterface (
+ XAccessibleHyperlink.class, aObject);
+ return xHyperlink;
+ }
+
+ public AccessibleTreeNode getChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ return new StringNode ("interface XAccessibleHyperlink is supported", aParent);
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleHypertextHandler.java b/toolkit/test/accessibility/AccessibleHypertextHandler.java
new file mode 100644
index 000000000000..aa703942bc4c
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleHypertextHandler.java
@@ -0,0 +1,42 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleHypertext;
+
+
+class AccessibleHypertextHandler extends AccessibleTreeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleHypertext xText =
+ (XAccessibleHypertext) UnoRuntime.queryInterface (
+ XAccessibleHypertext.class, xContext);
+ if (xText != null)
+ return new AccessibleHypertextHandler (xText);
+ else
+ return null;
+ }
+
+ public AccessibleHypertextHandler ()
+ {
+ }
+
+ public AccessibleHypertextHandler (XAccessibleHypertext xText)
+ {
+ if (xText != null)
+ maChildList.setSize (1);
+ }
+
+ protected static XAccessibleHypertext getHypertext (AccTreeNode aNode)
+ {
+ XAccessibleHypertext xHypertext =
+ (XAccessibleHypertext) UnoRuntime.queryInterface (
+ XAccessibleHypertext.class, aNode.getContext());
+ return xHypertext;
+ }
+
+ public AccessibleTreeNode getChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ return new StringNode ("interface XAccessibleHypertext is supported", aParent);
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleImageHandler.java b/toolkit/test/accessibility/AccessibleImageHandler.java
new file mode 100644
index 000000000000..92917e1b9740
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleImageHandler.java
@@ -0,0 +1,51 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleImage;
+
+
+class AccessibleImageHandler extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleImage xImage =
+ (XAccessibleImage) UnoRuntime.queryInterface (
+ XAccessibleImage.class, xContext);
+ if (xImage != null)
+ return new AccessibleImageHandler (xImage);
+ else
+ return null;
+ }
+
+ public AccessibleImageHandler ()
+ {
+ }
+
+ public AccessibleImageHandler (XAccessibleImage xImage)
+ {
+ if (xImage != null)
+ maChildList.setSize (1);
+ }
+
+ protected static XAccessibleImage getImage (AccTreeNode aNode)
+ {
+ return (XAccessibleImage) UnoRuntime.queryInterface (
+ XAccessibleImage.class, aNode.getContext());
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ if (aParent instanceof AccTreeNode)
+ {
+ XAccessibleImage xImage = getImage ((AccTreeNode)aParent);
+ if (xImage != null)
+ return new StringNode (
+ "Image: " +
+ xImage.getAccessibleImageDescription() + " (" +
+ xImage.getAccessibleImageWidth() + "x" +
+ xImage.getAccessibleImageHeight() + ")",
+ aParent);
+ }
+ return null;
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleRelationHandler.java b/toolkit/test/accessibility/AccessibleRelationHandler.java
new file mode 100644
index 000000000000..ea3be4c16264
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleRelationHandler.java
@@ -0,0 +1,96 @@
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.AccessibleRelation;
+import com.sun.star.accessibility.XAccessibleRelationSet;
+import com.sun.star.accessibility.AccessibleRelationType;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+import tools.NameProvider;
+
+class AccessibleRelationHandler
+ extends NodeHandler
+{
+ public NodeHandler createHandler( XAccessibleContext xContext )
+ {
+ AccessibleRelationHandler aHandler = null;
+ if (xContext != null)
+ {
+ XAccessibleRelationSet xRelation = xContext.getAccessibleRelationSet();
+ if (xRelation != null)
+ aHandler = new AccessibleRelationHandler(xContext);
+ }
+ return aHandler;
+ }
+
+ public AccessibleRelationHandler()
+ {
+ }
+
+ public AccessibleRelationHandler( XAccessibleContext xContext )
+ {
+ XAccessibleRelationSet xRelation = xContext.getAccessibleRelationSet();
+ if (xRelation != null)
+ maChildList.setSize( 1 );
+ }
+
+ public AccessibleTreeNode createChild( AccessibleTreeNode aParent,
+ int nIndex )
+ {
+ XAccessibleRelationSet xRelation = null;
+ AccessibleTreeNode aChild = null;
+
+ if( aParent instanceof AccTreeNode )
+ {
+ xRelation =
+ ((AccTreeNode)aParent).getContext().getAccessibleRelationSet();
+ }
+ if( xRelation == null )
+ return aChild;
+
+
+ VectorNode aVNode = new VectorNode( "RelationSet", aParent);
+ int nCount = xRelation.getRelationCount();
+ try
+ {
+ for( int i = 0; i < nCount; i++ )
+ {
+ AccessibleRelation aRelation = xRelation.getRelation( i );
+
+ StringBuffer aBuffer = new StringBuffer();
+ aBuffer.append (NameProvider.getRelationName (aRelation.RelationType));
+ aBuffer.append( ": " );
+
+ for( int j = 0; j < aRelation.TargetSet.length; j++ )
+ {
+ Object aTarget = aRelation.TargetSet[j];
+ XAccessible xAccTarget =
+ (XAccessible)UnoRuntime.queryInterface(
+ XAccessible.class, aTarget );
+ if( xAccTarget == null )
+ {
+ aBuffer.append( aTarget.toString() );
+ }
+ else
+ {
+ aBuffer.append( xAccTarget.getAccessibleContext().
+ getAccessibleName() );
+ }
+ aBuffer.append( ", " );
+ }
+ aBuffer.delete( aBuffer.length() - 2, aBuffer.length() );
+
+ aVNode.addChild( new StringNode( aBuffer.toString(),
+ aParent ) );
+ }
+
+ aChild = aVNode;
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aChild = new StringNode( "IndexOutOfBounds", aParent );
+ }
+
+ return aChild;
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleSelectionHandler.java b/toolkit/test/accessibility/AccessibleSelectionHandler.java
new file mode 100644
index 000000000000..f7ab62807332
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleSelectionHandler.java
@@ -0,0 +1,130 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleSelection;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+
+
+class AccessibleSelectionHandler
+ extends NodeHandler
+{
+ public NodeHandler createHandler( XAccessibleContext xContext )
+ {
+ XAccessibleSelection xSelection =
+ (XAccessibleSelection) UnoRuntime.queryInterface(
+ XAccessibleSelection.class, xContext);
+ return (xSelection == null) ? null :
+ new AccessibleSelectionHandler(xSelection);
+ }
+
+ public AccessibleSelectionHandler()
+ {
+ }
+
+ public AccessibleSelectionHandler( XAccessibleSelection xSelection )
+ {
+ if (xSelection != null)
+ maChildList.setSize( 2 );
+ }
+
+ public AccessibleTreeNode createChild( AccessibleTreeNode aParent,
+ int nIndex )
+ {
+ AccessibleTreeNode aChild = null;
+
+ if( aParent instanceof AccTreeNode )
+ {
+ XAccessibleSelection xSelection =
+ ((AccTreeNode)aParent).getSelection();
+ if( xSelection != null )
+ {
+ switch( nIndex )
+ {
+ case 0:
+ aChild = new StringNode(
+ "getSelectedAccessibleChildCount: " +
+ xSelection.getSelectedAccessibleChildCount(),
+ aParent );
+ break;
+ case 1:
+ {
+ VectorNode aVNode =
+ new VectorNode( "Selected Children", aParent);
+ int nSelected = 0;
+ int nCount = ((AccTreeNode)aParent).getContext().
+ getAccessibleChildCount();
+ try
+ {
+ for( int i = 0; i < nCount; i++ )
+ {
+ try
+ {
+ if( xSelection.isAccessibleChildSelected( i ) )
+ {
+ XAccessible xSelChild = xSelection.
+ getSelectedAccessibleChild(nSelected);
+ XAccessible xNChild =
+ ((AccTreeNode)aParent).
+ getContext().getAccessibleChild( i );
+ aVNode.addChild( new StringNode(
+ i + ": " +
+ xNChild.getAccessibleContext().
+ getAccessibleDescription() + " (" +
+ (xSelChild.equals(xNChild) ? "OK" : "XXX") +
+ ")", aParent ) );
+ }
+ }
+ catch (com.sun.star.lang.DisposedException e)
+ {
+ aVNode.addChild( new StringNode(
+ i + ": caught DisposedException while creating",
+ aParent ));
+ }
+ }
+ aChild = aVNode;
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aChild = new StringNode( "IndexOutOfBounds",
+ aParent );
+ }
+ }
+ break;
+ default:
+ aChild = new StringNode( "ERROR", aParent );
+ break;
+ }
+ }
+ }
+
+ return aChild;
+ }
+
+
+ public String[] getActions (AccessibleTreeNode aNode)
+ {
+ if( aNode instanceof AccTreeNode )
+ {
+ XAccessibleSelection xSelection =
+ ((AccTreeNode)aNode).getSelection();
+ if( xSelection != null )
+ {
+ return new String[] { "Select..." };
+ }
+ }
+ return new String[0];
+ }
+
+ public void performAction (AccessibleTreeNode aNode, int nIndex)
+ {
+ new SelectionDialog( (AccTreeNode)aNode ).show();
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleTableHandler.java b/toolkit/test/accessibility/AccessibleTableHandler.java
new file mode 100644
index 000000000000..c3883f649d5e
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleTableHandler.java
@@ -0,0 +1,90 @@
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleTable;
+
+
+class AccessibleTableHandler extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleTable xTable =
+ (XAccessibleTable) UnoRuntime.queryInterface (
+ XAccessibleTable.class, xContext);
+ if (xTable != null)
+ return new AccessibleTableHandler (xTable);
+ else
+ return null;
+ }
+
+ public AccessibleTableHandler ()
+ {
+ }
+
+ public AccessibleTableHandler (XAccessibleTable xTable)
+ {
+ if (xTable != null)
+ maChildList.setSize (4);
+ }
+
+ protected static XAccessibleTable getTable(Object aObject)
+ {
+ return (XAccessibleTable) UnoRuntime.queryInterface (
+ XAccessibleTable.class, aObject);
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+ XAccessibleTable xTable = null;
+ if (aParent instanceof AccTreeNode)
+ xTable = ((AccTreeNode)aParent).getTable();
+ try
+ {
+ if( xTable != null )
+ {
+ switch( nIndex )
+ {
+ case 0:
+ aChild = new StringNode ("# table rows: " + xTable.getAccessibleRowCount(), aParent);
+ break;
+ case 1:
+ aChild = new StringNode ("# table columns: " + xTable.getAccessibleColumnCount(), aParent);
+ break;
+ case 2:
+ {
+ String sText = "selected rows: ";
+ int[] aSelected = xTable.getSelectedAccessibleRows();
+ for( int i=0; i < aSelected.length; i++ )
+ {
+ sText += aSelected[i];
+ sText += " ";
+ }
+ aChild = new StringNode (sText, aParent);
+ }
+ break;
+ case 3:
+ {
+ String sText = "selected columns: ";
+ int[] aSelected = xTable.getSelectedAccessibleColumns();
+ for( int i=0; i < aSelected.length; i++ )
+ {
+ sText += aSelected[i];
+ sText += " ";
+ }
+ aChild = new StringNode (sText, aParent);
+ }
+ break;
+ default:
+ aChild = new StringNode ("unknown child index " + nIndex, aParent);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ // Return empty child.
+ }
+
+ return aChild;
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleTextHandler.java b/toolkit/test/accessibility/AccessibleTextHandler.java
new file mode 100644
index 000000000000..6fa083b22ea3
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleTextHandler.java
@@ -0,0 +1,792 @@
+
+import com.sun.star.accessibility.AccessibleTextType;
+import com.sun.star.accessibility.TextSegment;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleText;
+import com.sun.star.accessibility.XAccessibleEditableText;
+
+import com.sun.star.awt.Rectangle;
+import com.sun.star.awt.Point;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.lang.IndexOutOfBoundsException;
+import com.sun.star.beans.PropertyValue;
+
+import java.util.Vector;
+import java.awt.Container;
+import java.awt.FlowLayout;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import javax.swing.JDialog;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.Icon;
+import javax.swing.JTextArea;
+import javax.swing.JOptionPane;
+import javax.swing.JCheckBox;
+import javax.swing.JColorChooser;
+import javax.swing.BoxLayout;
+import javax.swing.text.JTextComponent;
+
+
+class AccessibleTextHandler extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ XAccessibleText xText = (XAccessibleText) UnoRuntime.queryInterface (
+ XAccessibleText.class, xContext);
+ if (xText != null)
+ return new AccessibleTextHandler (xText);
+ else
+ return null;
+ }
+
+ public AccessibleTextHandler ()
+ {
+ }
+
+ public AccessibleTextHandler (XAccessibleText xText)
+ {
+ if (xText != null)
+ maChildList.setSize (8);
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+ XAccessibleText xText = null;
+ if (aParent instanceof AccTreeNode)
+ xText = ((AccTreeNode)aParent).getText();
+
+ try
+ {
+ if( xText != null )
+ {
+ switch( nIndex )
+ {
+ case 0:
+ aChild = new StringNode (xText.getText(), aParent);
+ break;
+ case 1:
+ aChild = new StringNode ("# chars: " + xText.getCharacterCount(), aParent);
+ break;
+ case 2:
+ aChild = new StringNode (characters( xText ), aParent);
+ break;
+ case 3:
+ aChild = new StringNode ("selection: "
+ + "[" + xText.getSelectionStart()
+ + "," + xText.getSelectionEnd()
+ + "] \"" + xText.getSelectedText() + "\"",
+ aParent);
+ break;
+ case 4:
+ aChild = new StringNode ("getCaretPosition: " + xText.getCaretPosition(), aParent);
+ break;
+ case 5:
+ {
+ VectorNode aVec = new VectorNode("portions", aParent);
+ aChild = aVec;
+ aVec.addChild(
+ textAtIndexNode( xText, "Character",
+ AccessibleTextType.CHARACTER,
+ aParent ) );
+ aVec.addChild(
+ textAtIndexNode( xText, "Word",
+ AccessibleTextType.WORD,
+ aParent ) );
+ aVec.addChild(
+ textAtIndexNode( xText, "Sentence",
+ AccessibleTextType.SENTENCE,
+ aParent ) );
+ aVec.addChild(
+ textAtIndexNode( xText, "Paragraph",
+ AccessibleTextType.PARAGRAPH,
+ aParent ) );
+ aVec.addChild(
+ textAtIndexNode( xText, "Line",
+ AccessibleTextType.LINE,
+ aParent ) );
+ aVec.addChild(
+ textAtIndexNode( xText, "Attribute",
+ AccessibleTextType.ATTRIBUTE_RUN,
+ aParent ) );
+ aVec.addChild(
+ textAtIndexNode( xText, "Glyph",
+ AccessibleTextType.GLYPH,
+ aParent ) );
+ }
+ break;
+ case 6:
+ aChild = new StringNode (bounds( xText ), aParent);
+ break;
+ case 7:
+ aChild = getAttributes( xText, aParent );
+ break;
+ default:
+ aChild = new StringNode ("unknown child index " + nIndex, aParent);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ // Return empty child.
+ }
+
+ return aChild;
+ }
+
+
+ private String textAtIndexNodeString(
+ int nStart, int nEnd,
+ String sWord, String sBefore, String sBehind)
+ {
+ return "[" + nStart + "," + nEnd + "] "
+ + "\"" + sWord + "\" \t"
+ + "(" + sBefore + ","
+ + "" + sBehind + ")";
+ }
+
+ /** Create a text node that lists all strings of a particular text type
+ */
+ private AccessibleTreeNode textAtIndexNode(
+ XAccessibleText xText,
+ String sName,
+ short nTextType,
+ AccessibleTreeNode aParent)
+ {
+ VectorNode aNode = new VectorNode (sName, aParent);
+
+ // get word at all positions;
+ // for nicer display, compare current word to previous one and
+ // make a new node for every interval, not for every word
+ int nLength = xText.getCharacterCount();
+ if( nLength > 0 )
+ {
+ try
+ {
+ // sWord + nStart mark the current word
+ // make a node as soon as a new one is found; close the last
+ // one at the end
+ TextSegment sWord = xText.getTextAtIndex(0, nTextType);
+ TextSegment sBefore = xText.getTextBeforeIndex(0, nTextType);
+ TextSegment sBehind = xText.getTextBehindIndex(0, nTextType);
+ int nStart = 0;
+ for(int i = 1; i < nLength; i++)
+ {
+ TextSegment sTmp = xText.getTextAtIndex(i, nTextType);
+ TextSegment sTBef = xText.getTextBeforeIndex(i, nTextType);
+ TextSegment sTBeh = xText.getTextBehindIndex(i, nTextType);
+ if( ! ( sTmp.equals( sWord ) && sTBef.equals( sBefore ) &&
+ sTBeh.equals( sBehind ) ) )
+ {
+ aNode.addChild (new StringNode (textAtIndexNodeString(
+ nStart, i,
+ sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode));
+ sWord = sTmp;
+ sBefore = sTBef;
+ sBehind = sTBeh;
+ nStart = i;
+ }
+
+ // don't generate more than 50 children.
+ if (aNode.getChildCount() > 50)
+ {
+ sWord.SegmentText = "...";
+ break;
+ }
+ }
+ aNode.addChild (new StringNode (textAtIndexNodeString(
+ nStart, nLength,
+ sWord.SegmentText, sBefore.SegmentText, sBehind.SegmentText), aNode));
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aNode.addChild (new StringNode (e.toString(), aNode));
+ }
+ catch (com.sun.star.lang.IllegalArgumentException e)
+ {
+ aNode.addChild (new StringNode (e.toString(), aNode));
+ }
+ }
+
+ return aNode;
+ }
+
+
+
+ /** getCharacter (display as array string) */
+ private String characters(XAccessibleText xText)
+ {
+ // get count (max. 30)
+ int nChars = xText.getCharacterCount();
+ if( nChars > 30 )
+ nChars = 30;
+
+ // build up string
+ StringBuffer aChars = new StringBuffer();
+ try
+ {
+ aChars.append( "[" );
+ for( int i = 0; i < nChars; i++)
+ {
+ aChars.append( xText.getCharacter(i) );
+ aChars.append( "," );
+ }
+ if( nChars > 0)
+ {
+ if( nChars == xText.getCharacterCount() )
+ aChars.deleteCharAt( aChars.length() - 1 );
+ else
+ aChars.append( "..." );
+ }
+ aChars.append( "]" );
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aChars.append( " ERROR " );
+ }
+
+ // return result
+ return "getCharacters: " + aChars;
+ }
+
+
+ /** iterate over characters, and translate their positions
+ * back and forth */
+ private String bounds( XAccessibleText xText )
+ {
+ StringBuffer aBuffer = new StringBuffer( "bounds: " );
+ try
+ {
+ // iterate over characters
+ int nCount = xText.getCharacterCount();
+ for(int i = 0; i < nCount; i++ )
+ {
+ // get bounds for this character
+ Rectangle aRect = xText.getCharacterBounds( i );
+
+ // get the character by 'clicking' into the middle of
+ // the bounds
+ Point aMiddle = new Point();
+ aMiddle.X = aRect.X + (aRect.Width / 2) - 1;
+ aMiddle.Y = aRect.Y + (aRect.Height / 2 ) - 1;
+ int nIndex = xText.getIndexAtPoint( aMiddle );
+
+ // get the character, or a '#' for an illegal index
+ if( (nIndex >= 0) && (nIndex < xText.getCharacter(i)) )
+ aBuffer.append( xText.getCharacter(nIndex) );
+ else
+ aBuffer.append( '#' );
+ }
+ }
+ catch( IndexOutOfBoundsException e )
+ { ; } // ignore errors
+
+ return aBuffer.toString();
+ }
+
+
+ private AccessibleTreeNode getAttributes( XAccessibleText xText,
+ AccessibleTreeNode aParent)
+ {
+ String[] aAttributeList = new String[] {
+ "CharBackColor",
+ "CharColor",
+ "CharEscapement",
+ "CharHeight",
+ "CharPosture",
+ "CharStrikeout",
+ "CharUnderline",
+ "CharWeight",
+ "ParaAdjust",
+ "ParaBottomMargin",
+ "ParaFirstLineIndent",
+ "ParaLeftMargin",
+ "ParaLineSpacing",
+ "ParaRightMargin",
+ "ParaTabStops"};
+
+ AccessibleTreeNode aRet;
+
+ try
+ {
+ VectorNode aPortions = new VectorNode ("getAttributes", aParent);
+
+ int nIndex = 0;
+ int nLength = xText.getCharacterCount();
+ while( nIndex < nLength )
+ {
+ // get attribute run
+ String aPortion = null;
+ try
+ {
+ aPortion = xText.getTextAtIndex(
+ nIndex, AccessibleTextType.ATTRIBUTE_RUN).SegmentText;
+ }
+ catch(com.sun.star.lang.IllegalArgumentException e)
+ {
+ aPortion = new String ("");
+ }
+
+ // get attributes and make node with attribute children
+ PropertyValue[] aValues = xText.getCharacterAttributes(nIndex, aAttributeList);
+ VectorNode aAttrs = new VectorNode (aPortion, aPortions);
+ for( int i = 0; i < aValues.length; i++ )
+ {
+ new StringNode( aValues[i].Name + ": " + aValues[i].Value,
+ aAttrs );
+ }
+
+ // get next portion, but advance at least one
+ nIndex += (aPortion.length() > 0) ? aPortion.length() : 1;
+ }
+
+ aRet = aPortions;
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aRet = new StringNode( "Exception caught:" + e, aParent );
+ }
+
+ return aRet;
+ }
+
+
+ static String[] aTextActions =
+ new String[] { "select...", "copy..." };
+ static String[] aEditableTextActions =
+ new String[] { "select...", "copy...",
+ "cut...", "paste...", "edit...", "format..." };
+
+ public String[] getActions (AccessibleTreeNode aNode)
+ {
+ XAccessibleEditableText xEText = null;
+ if (aNode instanceof AccTreeNode)
+ xEText = ((AccTreeNode)aNode).getEditText ();
+
+ return (xEText == null) ? aTextActions : aEditableTextActions;
+ }
+
+ public void performAction (AccessibleTreeNode aNode, int nIndex)
+ {
+ if ( ! (aNode instanceof AccTreeNode))
+ return;
+
+ AccTreeNode aATNode = (AccTreeNode)aNode;
+ TextActionDialog aDialog = null;
+
+ // create proper dialog
+ switch( nIndex )
+ {
+ case 0:
+ aDialog = new TextActionDialog( aATNode,
+ "Select range:",
+ "select" )
+ {
+ boolean action(
+ JTextComponent aText, AccTreeNode aNode )
+ throws IndexOutOfBoundsException
+ {
+ return aNode.getText().setSelection(
+ getSelectionStart(),
+ getSelectionEnd() );
+ }
+ };
+ break;
+ case 1:
+ aDialog = new TextActionDialog( aATNode,
+ "Select range and copy:",
+ "copy" )
+ {
+ boolean action(
+ JTextComponent aText, AccTreeNode aNode )
+ throws IndexOutOfBoundsException
+ {
+ return aNode.getText().copyText(
+ getSelectionStart(),
+ getSelectionEnd() );
+ }
+ };
+ break;
+ case 2:
+ aDialog = new TextActionDialog( aATNode,
+ "Select range and cut:",
+ "cut" )
+ {
+ boolean action(
+ JTextComponent aText, AccTreeNode aNode )
+ throws IndexOutOfBoundsException
+ {
+ return aNode.getEditText().cutText(
+ getSelectionStart(),
+ getSelectionEnd() );
+ }
+ };
+ break;
+ case 3:
+ aDialog = new TextActionDialog( aATNode,
+ "Place Caret and paste:",
+ "paste" )
+ {
+ boolean action(
+ JTextComponent aText, AccTreeNode aNode )
+ throws IndexOutOfBoundsException
+ {
+ return aNode.getEditText().pasteText(
+ aText.getCaretPosition() );
+ }
+ };
+ break;
+ case 4:
+ aDialog = new TextEditDialog( aATNode, "Edit text:",
+ "edit" );
+ break;
+ case 5:
+ aDialog = new TextAttributeDialog( aATNode );
+ break;
+ }
+
+ if( aDialog != null )
+ aDialog.show();
+ }
+
+}
+
+/**
+ * Display a dialog with a text field and a pair of cancel/do-it buttons
+ */
+class TextActionDialog extends JDialog
+ implements ActionListener
+{
+ AccTreeNode aNode;
+ JTextArea aText;
+ String sName;
+ JCheckBox aIndexToggle;
+
+ public TextActionDialog( AccTreeNode aNd,
+ String sExplanation,
+ String sButtonText )
+ {
+ super( AccessibilityWorkBench.Instance() );
+
+ aNode = aNd;
+ sName = sButtonText;
+ init( sExplanation, aNode.getText().getText(), sButtonText );
+// setSize( getPreferredSize() );
+ setSize( 350, 225 );
+ }
+
+ /** build dialog */
+ protected void init( String sExplanation,
+ String sText,
+ String sButtonText )
+ {
+ setTitle( sName );
+
+ // vertical stacking of the elements
+ Container aContent = getContentPane();
+ // aContent.setLayout( new BorderLayout() );
+
+ // label with explanation
+ if( sExplanation.length() > 0 )
+ aContent.add( new JLabel( sExplanation ), BorderLayout.NORTH );
+
+ // the text field
+ aText = new JTextArea();
+ aText.setText( sText );
+ aText.setColumns( Math.min( Math.max( 40, sText.length() ), 20 ) );
+ aText.setRows( sText.length() / 40 + 1 );
+ aText.setLineWrap( true );
+ aText.setEditable( false );
+ aContent.add( aText, BorderLayout.CENTER );
+
+ JPanel aButtons = new JPanel();
+ aButtons.setLayout( new FlowLayout() );
+ aIndexToggle = new JCheckBox( "reverse selection" );
+ aButtons.add( aIndexToggle );
+ JButton aActionButton = new JButton( sButtonText );
+ aActionButton.setActionCommand( "Action" );
+ aActionButton.addActionListener( this );
+ aButtons.add( aActionButton );
+ JButton aCancelButton = new JButton( "cancel" );
+ aCancelButton.setActionCommand( "Cancel" );
+ aCancelButton.addActionListener( this );
+ aButtons.add( aCancelButton );
+
+ // add Panel with buttons
+ aContent.add( aButtons, BorderLayout.SOUTH );
+ }
+
+ void cancel()
+ {
+ hide();
+ dispose();
+ }
+
+ void action()
+ {
+ String sError = null;
+ try
+ {
+ boolean bSuccess = action( aText, aNode );
+ if( !bSuccess )
+ sError = "Can't execute";
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ sError = "Index out of bounds";
+ }
+
+ if( sError != null )
+ JOptionPane.showMessageDialog( AccessibilityWorkBench.Instance(),
+ sError, sName,
+ JOptionPane.ERROR_MESSAGE);
+
+ cancel();
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ String sCommand = e.getActionCommand();
+
+ if( "Cancel".equals( sCommand ) )
+ cancel();
+ else if( "Action".equals( sCommand ) )
+ action();
+ }
+
+
+ int getSelectionStart() { return getSelection(true); }
+ int getSelectionEnd() { return getSelection(false); }
+ int getSelection(boolean bStart)
+ {
+ return ( bStart ^ aIndexToggle.isSelected() )
+ ? aText.getSelectionStart() : aText.getSelectionEnd();
+ }
+
+
+
+ /** override this for dialog-specific action */
+ boolean action( JTextComponent aText, AccTreeNode aNode )
+ throws IndexOutOfBoundsException
+ {
+ return false;
+ }
+}
+
+
+class TextEditDialog extends TextActionDialog
+{
+ public TextEditDialog( AccTreeNode aNode,
+ String sExplanation,
+ String sButtonText )
+ {
+ super( aNode, sExplanation, sButtonText );
+ }
+
+ protected void init( String sExplanation,
+ String sText,
+ String sButtonText )
+ {
+ super.init( sExplanation, sText, sButtonText );
+ aText.setEditable( true );
+ }
+
+
+ /** edit the text */
+ boolean action( JTextComponent aText, AccTreeNode aNode )
+ {
+ // is this text editable? if not, fudge you and return
+ XAccessibleEditableText xEdit = aNode.getEditText();
+ return ( xEdit == null ) ? false :
+ updateText( xEdit, aText.getText() );
+ }
+
+
+ /** update the text */
+ boolean updateText( XAccessibleEditableText xEdit, String sNew )
+ {
+ String sOld = xEdit.getText();
+
+ // false alarm? Early out if no change was done!
+ if( sOld.equals( sNew ) )
+ return false;
+
+ // get the minimum length of both strings
+ int nMinLength = sOld.length();
+ if( sNew.length() < nMinLength )
+ nMinLength = sNew.length();
+
+ // count equal characters from front and end
+ int nFront = 0;
+ while( (nFront < nMinLength) &&
+ (sNew.charAt(nFront) == sOld.charAt(nFront)) )
+ nFront++;
+ int nBack = 0;
+ while( (nBack < nMinLength) &&
+ ( sNew.charAt(sNew.length()-nBack-1) ==
+ sOld.charAt(sOld.length()-nBack-1) ) )
+ nBack++;
+ if( nFront + nBack > nMinLength )
+ nBack = nMinLength - nFront;
+
+ // so... the first nFront and the last nBack characters
+ // are the same. Change the others!
+ String sDel = sOld.substring( nFront, sOld.length() - nBack );
+ String sIns = sNew.substring( nFront, sNew.length() - nBack );
+
+ System.out.println("edit text: " +
+ sOld.substring(0, nFront) +
+ " [ " + sDel + " -> " + sIns + " ] " +
+ sOld.substring(sOld.length() - nBack) );
+
+ boolean bRet = false;
+ try
+ {
+ // edit the text, and use
+ // (set|insert|delete|replace)Text as needed
+ if( nFront+nBack == 0 )
+ bRet = xEdit.setText( sIns );
+ else if( sDel.length() == 0 )
+ bRet = xEdit.insertText( sIns, nFront );
+ else if( sIns.length() == 0 )
+ bRet = xEdit.deleteText( nFront, sOld.length()-nBack );
+ else
+ bRet = xEdit.replaceText(nFront, sOld.length()-nBack,sIns);
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ bRet = false;
+ }
+
+ return bRet;
+ }
+}
+
+
+class TextAttributeDialog extends TextActionDialog
+{
+ public TextAttributeDialog(
+ AccTreeNode aNode )
+ {
+ super( aNode, "Choose attributes, select text, and press 'Set':",
+ "set" );
+ }
+
+ private JCheckBox aBold, aUnderline, aItalics;
+ private Color aForeground, aBackground;
+
+ protected void init( String sExplanation,
+ String sText,
+ String sButtonText )
+ {
+ super.init( sExplanation, sText, sButtonText );
+
+ aForeground = Color.black;
+ aBackground = Color.white;
+
+ JPanel aAttr = new JPanel();
+ aAttr.setLayout( new BoxLayout( aAttr, BoxLayout.Y_AXIS ) );
+
+ aBold = new JCheckBox( "bold" );
+ aUnderline = new JCheckBox( "underline" );
+ aItalics = new JCheckBox( "italics" );
+
+ JButton aForeButton = new JButton("Foreground", new ColorIcon(true));
+ aForeButton.addActionListener( new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ aForeground = JColorChooser.showDialog(
+ TextAttributeDialog.this,
+ "Select Foreground Color",
+ aForeground);
+ }
+ } );
+
+ JButton aBackButton = new JButton("Background", new ColorIcon(false));
+ aBackButton.addActionListener( new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ aBackground = JColorChooser.showDialog(
+ TextAttributeDialog.this,
+ "Select Background Color",
+ aBackground);
+ }
+ } );
+
+ aAttr.add( aBold );
+ aAttr.add( aUnderline );
+ aAttr.add( aItalics );
+ aAttr.add( aForeButton );
+ aAttr.add( aBackButton );
+
+ getContentPane().add( aAttr, BorderLayout.WEST );
+ }
+
+
+ class ColorIcon implements Icon
+ {
+ boolean bForeground;
+ static final int nHeight = 16;
+ static final int nWidth = 16;
+
+ public ColorIcon(boolean bWhich) { bForeground = bWhich; }
+ public int getIconHeight() { return nHeight; }
+ public int getIconWidth() { return nWidth; }
+ public void paintIcon(Component c, Graphics g, int x, int y)
+ {
+ g.setColor( getColor() );
+ g.fillRect( x, y, nHeight, nWidth );
+ g.setColor( c.getForeground() );
+ g.drawRect( x, y, nHeight, nWidth );
+ }
+ Color getColor()
+ {
+ return bForeground ? aForeground : aBackground;
+ }
+ }
+
+
+
+ /** edit the text */
+ boolean action( JTextComponent aText, AccTreeNode aNode )
+ throws IndexOutOfBoundsException
+ {
+ // is this text editable? if not, fudge you and return
+ XAccessibleEditableText xEdit = aNode.getEditText();
+ boolean bSuccess = false;
+ if( xEdit != null )
+ {
+ PropertyValue[] aSequence = new PropertyValue[6];
+ aSequence[0] = new PropertyValue();
+ aSequence[0].Name = "CharWeight";
+ aSequence[0].Value = new Integer( aBold.isSelected() ? 150 : 100 );
+ aSequence[1] = new PropertyValue();
+ aSequence[1].Name = "CharUnderline";
+ aSequence[1].Value = new Integer( aUnderline.isSelected() ? 1 : 0 );
+ aSequence[2] = new PropertyValue();
+ aSequence[2].Name = "CharBackColor";
+ aSequence[2].Value = new Integer( aBackground.getRGB() );
+ aSequence[3] = new PropertyValue();
+ aSequence[3].Name = "CharColor";
+ aSequence[3].Value = new Integer( aForeground.getRGB() );
+ aSequence[4] = new PropertyValue();
+ aSequence[4].Name = "CharPosture";
+ aSequence[4].Value = new Integer( aItalics.isSelected() ? 1 : 0 );
+ aSequence[5] = new PropertyValue();
+ aSequence[5].Name = "CharBackTransparent";
+ aSequence[5].Value = new Boolean( false );
+
+ bSuccess = xEdit.setAttributes( getSelectionStart(),
+ getSelectionEnd(),
+ aSequence );
+ }
+ return bSuccess;
+ }
+
+}
diff --git a/toolkit/test/accessibility/AccessibleTreeCellRenderer.java b/toolkit/test/accessibility/AccessibleTreeCellRenderer.java
new file mode 100644
index 000000000000..deb3cb967133
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleTreeCellRenderer.java
@@ -0,0 +1,86 @@
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreePath;
+import javax.swing.JTree;
+import java.awt.Color;
+import java.awt.Component;
+import java.util.Vector;
+
+
+public class AccessibleTreeCellRenderer
+ extends DefaultTreeCellRenderer
+{
+ public Color
+ maDefaultColor,
+ maChangedColor;
+ protected Vector
+ maChangedLines;
+
+
+
+ public AccessibleTreeCellRenderer ()
+ {
+ maDefaultColor = Color.black;
+ maChangedColor = Color.red;
+ maChangedLines = new Vector ();
+ }
+
+ public Component getTreeCellRendererComponent (
+ JTree tree,
+ Object value,
+ boolean sel,
+ boolean expanded,
+ boolean leaf,
+ int row,
+ boolean hasFocus)
+ {
+ super.getTreeCellRendererComponent(
+ tree, value, sel,
+ expanded, leaf, row,
+ hasFocus);
+
+ if (maChangedLines.size()<=row || maChangedLines.elementAt (row) == null)
+ setTextNonSelectionColor (maDefaultColor);
+ else
+ setTextNonSelectionColor (maChangedColor);
+
+ return this;
+ }
+
+ /** Tell the cell renderer that no changes shall be displayed anymore.
+ */
+ public void clearAllChanges ()
+ {
+ maChangedLines.clear();
+ }
+
+ /** Inform the cell renderer of a new changed line which to paint
+ highlighted when asked to paint it the next time.
+ */
+ public void addChangedLine (int nRow)
+ {
+ if (maChangedLines.size() <= nRow)
+ maChangedLines.setSize (nRow+1);
+ nRow -= 1; // row index is one to large for some reason.
+ maChangedLines.set (nRow, new Boolean (true));
+ }
+
+ /** Inform the cell renderer of a set of changed line which to paint
+ highlighted when asked to paint them the next time.
+ @param aChangedNodes
+ The set of changed nodes. Each entry is a TreePath.
+ @param aTree
+ The JTree that is used to transform the given TreePath objects
+ into rows.
+ */
+ public void addChangedNodes (Vector aChangedNodes, JTree aTree)
+ {
+ for (int i=0; i<aChangedNodes.size(); i++)
+ {
+ TreePath aPath = (TreePath)aChangedNodes.elementAt (i);
+ int nRow = aTree.getRowForPath (aPath);
+ addChangedLine (nRow);
+ }
+ }
+
+}
+
diff --git a/toolkit/test/accessibility/AccessibleTreeHandler.java b/toolkit/test/accessibility/AccessibleTreeHandler.java
new file mode 100644
index 000000000000..f45db8cb5ab9
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleTreeHandler.java
@@ -0,0 +1,110 @@
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+
+/**
+ * Map the tree of accessibility objects into their
+ * AccessibilityTreeModel counterparts.
+ */
+class AccessibleTreeHandler
+ extends NodeHandler
+{
+ protected XAccessibleContext mxContext;
+
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ if (xContext != null)
+ return new AccessibleTreeHandler (xContext);
+ else
+ return null;
+ }
+
+ public AccessibleTreeHandler ()
+ {
+ super();
+ mxContext = null;
+ }
+
+ public AccessibleTreeHandler (XAccessibleContext xContext)
+ {
+ super();
+ mxContext = xContext;
+ if (mxContext != null)
+ // Add one to the number of children to include the string node
+ // that tells you how many children there are.
+ synchronized (maChildList)
+ {
+ maChildList.setSize (1 + mxContext.getAccessibleChildCount());
+ }
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+ if (mxContext != null)
+ {
+ if (nIndex == 0)
+ aChild = new StringNode ("Child count: " + mxContext.getAccessibleChildCount(),
+ aParent);
+ else
+ {
+ // Lower index to skip the string node.
+ nIndex -= 1;
+ try
+ {
+ XAccessible xChild = mxContext.getAccessibleChild (nIndex);
+ aChild = NodeFactory.Instance().createDefaultNode (
+ xChild, aParent);
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aChild = new StringNode ("ERROR: no child with index " + nIndex, aParent);
+ }
+ }
+ }
+ else
+ aChild = new StringNode ("XAccessibleContext interface not supported", aParent);
+ return aChild;
+ }
+
+ /** Try to add the specified accessible child into the lists of
+ children. The insertion position is determined from the
+ getIndexInParent method of the child.
+ */
+ public AccessibleTreeNode addAccessibleChild (AccessibleTreeNode aParent, XAccessible xChild)
+ {
+ AccessibleTreeNode aChild = null;
+
+ if (xChild != null)
+ {
+ XAccessibleContext xContext = xChild.getAccessibleContext();
+ if (xContext != null)
+ {
+ int nIndex = xContext.getAccessibleIndexInParent() + 1;
+ synchronized (maChildList)
+ {
+ if ((nIndex >= 0) || (nIndex <= maChildList.size()))
+ {
+ aChild = NodeFactory.Instance().createDefaultNode (xChild, aParent);
+ maChildList.insertElementAt (aChild, nIndex);
+ }
+ }
+ }
+ }
+ return aChild;
+ }
+
+
+ /** Update only the child count node. Trust on other ways to update the
+ accessible children.
+ */
+ public void update (AccessibleTreeNode aNode)
+ {
+ synchronized (maChildList)
+ {
+ maChildList.setElementAt (null, 0);
+ }
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleTreeNode.java b/toolkit/test/accessibility/AccessibleTreeNode.java
new file mode 100644
index 000000000000..f9b0799e4423
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleTreeNode.java
@@ -0,0 +1,101 @@
+import java.util.Vector;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+/**
+ Base class for all tree nodes.
+ */
+class AccessibleTreeNode
+{
+ /// The parent node. It is null for the root node.
+ protected AccessibleTreeNode maParent;
+
+ /// The object to be displayed.
+ private Object maDisplayObject;
+
+ public AccessibleTreeNode (Object aDisplayObject, AccessibleTreeNode aParent)
+ {
+ maDisplayObject = aDisplayObject;
+ maParent = aParent;
+ }
+
+ public void update ()
+ {
+ // Empty
+ }
+
+ public AccessibleTreeNode getParent ()
+ {
+ return maParent;
+ }
+
+ public Object getDisplayObject ()
+ {
+ return maDisplayObject;
+ }
+
+ public int getChildCount ()
+ {
+ return 0;
+ }
+
+ public AccessibleTreeNode getChild (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ throw new IndexOutOfBoundsException();
+ }
+
+ public AccessibleTreeNode getChildNoCreate (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ throw new IndexOutOfBoundsException();
+ }
+
+ public boolean removeChild (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ throw new IndexOutOfBoundsException();
+ }
+
+ public int indexOf (AccessibleTreeNode aNode)
+ {
+ return -1;
+ }
+
+ /** Create a path to this node by first asking the parent for its path
+ and then appending this object.
+ */
+ public void createPath (java.util.Vector aPath)
+ {
+ if (maParent != null)
+ maParent.createPath (aPath);
+ aPath.add (this);
+ }
+
+ public Object[] createPath ()
+ {
+ Vector aPath = new Vector (1);
+ createPath (aPath);
+ return aPath.toArray();
+ }
+
+ public boolean isLeaf()
+ {
+ return true;
+ }
+
+ public String toString()
+ {
+ return maDisplayObject.toString();
+ }
+
+ /** get names of suported actions */
+ public String[] getActions ()
+ {
+ return new String[] {};
+ }
+
+ /** perform action */
+ public void performAction (int nIndex)
+ {
+ }
+}
diff --git a/toolkit/test/accessibility/AccessibleUNOHandler.java b/toolkit/test/accessibility/AccessibleUNOHandler.java
new file mode 100644
index 000000000000..d52e60cd721f
--- /dev/null
+++ b/toolkit/test/accessibility/AccessibleUNOHandler.java
@@ -0,0 +1,115 @@
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.AccessibleRelation;
+import com.sun.star.accessibility.XAccessibleRelationSet;
+import com.sun.star.accessibility.AccessibleRelationType;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.XTypeProvider;
+import com.sun.star.uno.Type;
+
+
+/** This handler displays lower level UNO information. These are the
+ supported services, interfaces, and the implementation name.
+*/
+class AccessibleUNOHandler
+ extends NodeHandler
+{
+ public NodeHandler createHandler (XAccessibleContext xContext)
+ {
+ if (xContext == null)
+ return null;
+ else
+ return new AccessibleUNOHandler (xContext);
+ }
+
+ public AccessibleUNOHandler()
+ {
+ }
+
+ public AccessibleUNOHandler (XAccessibleContext xContext)
+ {
+ maChildList.setSize (3);
+ }
+
+ private XServiceInfo GetServiceInfo (AccessibleTreeNode aNode)
+ {
+ XServiceInfo xServiceInfo = null;
+ if (aNode instanceof AccTreeNode)
+ xServiceInfo = (XServiceInfo)UnoRuntime.queryInterface(
+ XServiceInfo.class, ((AccTreeNode)aNode).getContext());
+ return xServiceInfo;
+ }
+ private XTypeProvider GetTypeProvider (AccessibleTreeNode aNode)
+ {
+ XTypeProvider xTypeProvider = null;
+ if (aNode instanceof AccTreeNode)
+ xTypeProvider = (XTypeProvider)UnoRuntime.queryInterface(
+ XTypeProvider.class, ((AccTreeNode)aNode).getContext());
+ return xTypeProvider;
+ }
+
+ public AccessibleTreeNode createChild (AccessibleTreeNode aParent,
+ int nIndex)
+ {
+ AccessibleTreeNode aChild = null;
+ XServiceInfo xServiceInfo;
+ switch (nIndex)
+ {
+ case 0 : // Implemenation name.
+ xServiceInfo = GetServiceInfo (aParent);
+ aChild = new StringNode ("Implementation name: " +
+ (xServiceInfo!=null ? xServiceInfo.getImplementationName()
+ : "<XServiceInfo not supported>"),
+ aParent);
+ break;
+ case 1 :
+ xServiceInfo = GetServiceInfo (aParent);
+ if (xServiceInfo == null)
+ aChild = new StringNode (
+ "Supported services: <XServiceInfo not supported>",
+ aParent);
+ else
+ aChild = CreateServiceTree (aParent, xServiceInfo);
+ break;
+ case 2 :
+ XTypeProvider xTypeProvider = GetTypeProvider (aParent);
+ if (xTypeProvider == null)
+ aChild = new StringNode (
+ "Supported interfaces: <XTypeProvider not supported>",
+ aParent);
+ else
+ aChild = CreateInterfaceTree (aParent, xTypeProvider);
+ break;
+ }
+
+ return aChild;
+ }
+
+
+ private AccessibleTreeNode CreateServiceTree (AccessibleTreeNode aParent,
+ XServiceInfo xServiceInfo)
+ {
+ String[] aServiceNames = xServiceInfo.getSupportedServiceNames();
+ VectorNode aNode = new VectorNode ("Supported Services", aParent);
+
+ int nCount = aServiceNames.length;
+ for (int i=0; i<nCount; i++)
+ aNode.addChild (new StringNode (aServiceNames[i], aParent));
+
+ return aNode;
+ }
+
+ private AccessibleTreeNode CreateInterfaceTree (AccessibleTreeNode aParent,
+ XTypeProvider xTypeProvider)
+ {
+ Type[] aTypes = xTypeProvider.getTypes();
+ VectorNode aNode = new VectorNode ("Supported Interfaces", aParent);
+
+ int nCount = aTypes.length;
+ for (int i=0; i<nCount; i++)
+ aNode.addChild (new StringNode (aTypes[i].getTypeName(), aParent));
+
+ return aNode;
+ }
+}
diff --git a/toolkit/test/accessibility/Canvas.java b/toolkit/test/accessibility/Canvas.java
new file mode 100755
index 000000000000..a1d8fb0f7d08
--- /dev/null
+++ b/toolkit/test/accessibility/Canvas.java
@@ -0,0 +1,448 @@
+import java.util.*;
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.tree.*;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import java.awt.geom.Rectangle2D;
+
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleComponent;
+
+/** This canvas displays accessible objects graphically. Each accessible
+ object with graphical representation is represented by an
+ CanvasShape object and has to be added by the
+ <member>addAccessible</member> member function.
+
+ <p>The canvas listens to selection events of the associated JTree and
+ highlights the first selected node of that tree.</p>
+*/
+class Canvas
+ extends JPanel
+ implements MouseListener, MouseMotionListener, TreeSelectionListener//, Scrollable
+{
+ // This constant can be passed to SetZoomMode to always show the whole screen.
+ public static final int WHOLE_SCREEN = -1;
+
+ public Canvas ()
+ {
+ super (true);
+ maObjects = new java.util.HashMap ();
+ maNodes = new Vector ();
+ maObjectList = new Vector ();
+ maContexts = new Vector ();
+ addMouseListener (this);
+ addMouseMotionListener (this);
+ maBoundingBox = new Rectangle (0,0,100,100);
+ maTree = null;
+ mnHOffset = 0;
+ mnVOffset = 0;
+ mnScale = 1;
+ setShowText(false);
+ setShowDescriptions (true);
+ setShowNames (true);
+ setAntialiasing (true);
+ maLastWidgetSize = new Dimension (0,0);
+ }
+
+ /** Tell the canvas which tree view to use to highlight accessible
+ objects.
+ */
+ public void setTree (JTree aTree)
+ {
+ if (maTree != null)
+ maTree.removeTreeSelectionListener (this);
+ maTree = aTree;
+ if (maTree != null)
+ maTree.addTreeSelectionListener (this);
+ }
+
+
+
+
+ public void addNode (AccTreeNode aNode)
+ {
+ if (maNodes.indexOf (aNode) == -1)
+ {
+ maNodes.add (aNode);
+
+ CanvasShape aObject = (CanvasShape) maObjects.get (aNode);
+ if (aObject == null)
+ {
+ aObject = new CanvasShape (aNode);
+ // Update bounding box that includes all objects.
+ if (maObjects.size() == 0)
+ maBoundingBox = aObject.getBBox();
+ else
+ maBoundingBox = maBoundingBox.union (aObject.getBBox());
+
+ maObjects.put (aNode, aObject);
+ maObjectList.add (aObject);
+
+ }
+ repaint ();
+ }
+ }
+
+ public void removeNode (AccTreeNode aNode)
+ {
+ int i = maNodes.indexOf (aNode);
+ if( i != -1 )
+ {
+ Object aObject = maObjects.get(aNode);
+ maObjectList.remove (aObject);
+ maObjects.remove (aObject);
+ maNodes.remove (aNode);
+ repaint ();
+ }
+ }
+
+ public void updateNode (AccTreeNode aNode)
+ {
+ int i = maNodes.indexOf (aNode);
+ if (i != -1)
+ {
+ CanvasShape aObject = (CanvasShape)maObjects.get(aNode);
+ if (aObject != null)
+ aObject.update();
+ }
+ }
+
+ public void updateNodeGeometry (AccTreeNode aNode)
+ {
+ CanvasShape aObject = (CanvasShape)maObjects.get(aNode);
+ if (aObject != null)
+ aObject.updateGeometry();
+ }
+
+ public void clear ()
+ {
+ while (maNodes.size() > 0)
+ removeNode ((AccTreeNode)maNodes.elementAt(0));
+
+ maNodes.clear();
+ maObjects.clear();
+ maObjectList.clear();
+ }
+
+ public boolean getShowDescriptions ()
+ {
+ return Options.GetBoolean ("ShowDescriptions");
+ }
+
+ public void setShowDescriptions (boolean bNewValue)
+ {
+ Options.SetBoolean ("ShowDescriptions", bNewValue);
+ repaint ();
+ }
+
+ public boolean getShowNames ()
+ {
+ return Options.GetBoolean ("ShowNames");
+ }
+
+ public void setShowNames (boolean bNewValue)
+ {
+ Options.SetBoolean ("ShowNames", bNewValue);
+ repaint ();
+ }
+
+ public boolean getAntialiasing ()
+ {
+ return Options.GetBoolean ("Antialiasing");
+ }
+
+ public void setAntialiasing (boolean bNewValue)
+ {
+ Options.SetBoolean ("Antialiasing", bNewValue);
+ repaint ();
+ }
+
+ public boolean getShowText ()
+ {
+ return Options.GetBoolean ("ShowText");
+ }
+
+ public void setShowText (boolean bNewValue)
+ {
+ Options.SetBoolean ("ShowText", bNewValue);
+ repaint ();
+ }
+
+ public void setZoomMode (int nZoomMode)
+ {
+ Options.SetInteger ("ZoomMode", nZoomMode);
+ repaint ();
+ }
+
+ public int getZoomMode ()
+ {
+ return Options.GetInteger ("ZoomMode", WHOLE_SCREEN);
+ }
+
+
+ public void paintComponent (Graphics g)
+ {
+ synchronized (g)
+ {
+ super.paintComponent (g);
+
+ Graphics2D g2 = (Graphics2D)g;
+ if (getAntialiasing())
+ g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ else
+ g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_OFF);
+
+ setupTransformation ();
+
+ // Draw the screen representation to give a hint of the location of the
+ // accessible object on the screen.
+ Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Rectangle2D.Double aScreen = new Rectangle2D.Double (
+ mnHOffset,
+ mnVOffset,
+ mnScale*aScreenSize.getWidth(),
+ mnScale*aScreenSize.getHeight());
+ // Fill the screen rectangle and draw a frame arround it to increase its visibility.
+ g2.setColor (new Color (250,240,230));
+ g2.fill (aScreen);
+ g2.setColor (Color.BLACK);
+ g2.draw (aScreen);
+
+ synchronized (maObjectList)
+ {
+ int nCount = maObjectList.size();
+ boolean bShowDescriptions = getShowDescriptions();
+ boolean bShowNames = getShowNames();
+ boolean bShowText = getShowText();
+ for (int i=0; i<nCount; i++)
+ {
+ CanvasShape aCanvasShape = (CanvasShape)maObjectList.elementAt(i);
+ aCanvasShape.paint (
+ g2,
+ mnHOffset, mnVOffset, mnScale,
+ bShowDescriptions, bShowNames, bShowText);
+ }
+ }
+
+ // Paint highlighted frame around active object as the last thing.
+ if (maActiveObject != null)
+ maActiveObject.paint_highlight (
+ g2,
+ mnHOffset, mnVOffset, mnScale);
+ }
+ }
+
+
+
+
+ /** Set up the transformation so that the graphical display can show a
+ centered representation of the whole screen.
+ */
+ private void setupTransformation ()
+ {
+ // Turn off scrollbars when showing the whole screen. Otherwise show them when needed.
+ JViewport aViewport = (JViewport)getParent();
+ JScrollPane aScrollPane = (JScrollPane)aViewport.getParent();
+ int nZoomMode = getZoomMode();
+ if (nZoomMode == WHOLE_SCREEN)
+ {
+ if (aScrollPane.getHorizontalScrollBarPolicy()
+ != JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
+ aScrollPane.setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ if (aScrollPane.getVerticalScrollBarPolicy()
+ != JScrollPane.VERTICAL_SCROLLBAR_NEVER)
+ aScrollPane.setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_NEVER);
+ }
+ else
+ {
+ if (aScrollPane.getHorizontalScrollBarPolicy()
+ != JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
+ aScrollPane.setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ if (aScrollPane.getVerticalScrollBarPolicy()
+ != JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
+ aScrollPane.setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+ }
+
+ Dimension aScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension aWidgetSize = aViewport.getSize();
+ {
+ if ((aScreenSize.getWidth() > 0) && (aScreenSize.getHeight() > 0))
+ {
+ if (nZoomMode == WHOLE_SCREEN)
+ {
+ // Calculate the scales that would map the screen onto the
+ // widget in both of the coordinate axes and select the
+ // smaller
+ // of the two: it maps the screen onto the widget in both
+ // axes at the same time.
+ double nHScale = (aWidgetSize.getWidth() - 10) / aScreenSize.getWidth();
+ double nVScale = (aWidgetSize.getHeight() - 10) / aScreenSize.getHeight();
+ if (nHScale < nVScale)
+ mnScale = nHScale;
+ else
+ mnScale = nVScale;
+ }
+ else
+ {
+ mnScale = nZoomMode / 100.0;
+ }
+
+ // Calculate offsets that center the scaled screen inside the widget.
+ mnHOffset = (aWidgetSize.getWidth() - mnScale*aScreenSize.getWidth()) / 2.0;
+ mnVOffset = (aWidgetSize.getHeight() - mnScale*aScreenSize.getHeight()) / 2.0;
+ if (mnHOffset < 0)
+ mnHOffset = 0;
+ if (mnVOffset < 0)
+ mnVOffset = 0;
+
+ setPreferredSize (new Dimension (
+ (int)(2*mnHOffset + mnScale * aScreenSize.getWidth()),
+ (int)(2*mnVOffset + mnScale * aScreenSize.getHeight())));
+ revalidate ();
+ }
+ else
+ {
+ // In case of a degenerate (not yet initialized?) screen size
+ // use some meaningless default values.
+ mnScale = 1;
+ mnHOffset = 0;
+ mnVOffset = 0;
+ }
+ }
+ maLastWidgetSize = aWidgetSize;
+ }
+
+
+
+ /** Call getAccessibleAt to determine accessible object under mouse.
+ */
+ public void mouseClicked (MouseEvent e)
+ {
+ }
+
+ public void mousePressed (MouseEvent e)
+ {
+ CanvasShape aObjectUnderMouse = FindCanvasShapeUnderMouse (e);
+ highlightObject (aObjectUnderMouse);
+ if ((e.getModifiers() & InputEvent.CTRL_MASK) != 0)
+ {
+ maTree.expandPath (aObjectUnderMouse.getPath());
+ }
+ }
+
+ public void mouseReleased (MouseEvent e)
+ {
+ }
+
+ public void mouseEntered (MouseEvent e)
+ {
+ }
+
+ public void mouseExited (MouseEvent e)
+ {
+ // Deselect currently active object.
+ if (maActiveObject != null)
+ {
+ maActiveObject.unhighlight ();
+ maActiveObject = null;
+ repaint ();
+ }
+ }
+
+ public void mouseDragged (MouseEvent e)
+ {
+ }
+
+ public void mouseMoved (MouseEvent e)
+ {
+ if ((e.getModifiers() & InputEvent.SHIFT_MASK) != 0)
+ highlightObject (FindCanvasShapeUnderMouse (e));
+ }
+
+ protected CanvasShape FindCanvasShapeUnderMouse (MouseEvent e)
+ {
+ int nObjects = maObjects.size();
+ CanvasShape aObjectUnderMouse = null;
+ int nCount = maObjectList.size();
+ for (int i=nCount-1; i>=0; --i)
+ {
+ CanvasShape aObject = (CanvasShape)maObjectList.elementAt(i);
+ if (aObject != null)
+ if (aObject.contains (e.getX(),e.getY()))
+ {
+ aObjectUnderMouse = aObject;
+ break;
+ }
+ }
+ return aObjectUnderMouse;
+ }
+
+ protected boolean highlightObject (CanvasShape aNewActiveObject)
+ {
+ if (aNewActiveObject != maActiveObject)
+ {
+ if (maActiveObject != null)
+ maActiveObject.unhighlight();
+
+ maActiveObject = aNewActiveObject;
+ if (maActiveObject != null)
+ {
+ if (maTree != null)
+ {
+ maTree.scrollPathToVisible (maActiveObject.getPath());
+ maTree.setSelectionPath (maActiveObject.getPath());
+ maTree.repaint ();
+ }
+ maActiveObject.highlight ();
+ repaint ();
+ }
+ return true;
+ }
+ else
+ return false;
+ }
+
+ /** Called when the selection of the tree changes. Highlight the
+ corresponding graphical representation of the first selected object.
+ */
+ public void valueChanged (javax.swing.event.TreeSelectionEvent event)
+ {
+ TreePath aPath = event.getPath();
+ Object aObject = aPath.getLastPathComponent();
+ if (aObject instanceof AccTreeNode)
+ {
+ CanvasShape aCanvasShape = (CanvasShape)maObjects.get ((AccTreeNode)aObject);
+ if (highlightObject (aCanvasShape))
+ repaint();
+ }
+ }
+
+ private int
+ mnXAnchor,
+ mnYAnchor,
+ maResizeFlag;
+ private double
+ mnHOffset,
+ mnVOffset,
+ mnScale;
+ private CanvasShape
+ maActiveObject;
+ private java.util.HashMap
+ maObjects;
+ private Vector
+ maObjectList,
+ maContexts,
+ maNodes;
+ private Rectangle
+ maBoundingBox;
+ private JTree
+ maTree;
+ // The size of the widget at the last call of setupTransformation()
+ private Dimension
+ maLastWidgetSize;
+}
diff --git a/toolkit/test/accessibility/CanvasShape.java b/toolkit/test/accessibility/CanvasShape.java
new file mode 100644
index 000000000000..57cedebb9e88
--- /dev/null
+++ b/toolkit/test/accessibility/CanvasShape.java
@@ -0,0 +1,330 @@
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.tree.*;
+import java.awt.geom.Rectangle2D;
+
+import com.sun.star.beans.XPropertyChangeListener;
+import com.sun.star.beans.PropertyChangeEvent;
+
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleComponent;
+import com.sun.star.accessibility.XAccessibleExtendedComponent;
+import com.sun.star.accessibility.XAccessibleText;
+import com.sun.star.accessibility.XAccessibleStateSet;
+import com.sun.star.accessibility.AccessibleStateType;
+
+class CanvasShape
+{
+ public final Color maHighlightColor = Color.red;
+ public final Color maSelectionColor = Color.green;
+ public final Color maFocusColor = Color.blue;
+
+ // public AccessibleObject (XAccessibleContext xContext, TreePath aPath)
+ public CanvasShape (AccTreeNode aNode)
+ {
+ maNode = aNode;
+ mxContext = aNode.getContext();
+ msName = "name unknown";
+ msDescription = "description unknown";
+ maShape = new Rectangle2D.Double (-10,-10,10,10);
+ maPosition = new Point (-10,-10);
+ maSize = new Dimension (10,10);
+ maFgColor = java.awt.Color.black;
+ maBgColor = Color.blue;
+ mnRole = -1;
+ mbHighlighted = false;
+ mbSelected = false;
+ mbFocused = false;
+ mxComponent = aNode.getComponent();
+
+ update ();
+ }
+
+
+
+ /** Update the data obtained from the xAccessible.
+ */
+ public void update ()
+ {
+ if (mxContext != null)
+ {
+ msName = mxContext.getAccessibleName();
+ msDescription = mxContext.getAccessibleDescription();
+ mnRole = mxContext.getAccessibleRole();
+
+ // Extract the selected and focused flag.
+ XAccessibleStateSet xStateSet = mxContext.getAccessibleStateSet ();
+ if (xStateSet != null)
+ {
+ mbSelected = xStateSet.contains (AccessibleStateType.SELECTED);
+ mbFocused = xStateSet.contains (AccessibleStateType.FOCUSED);
+ }
+ }
+
+ updateGeometry ();
+ if (mxComponent != null)
+ {
+ // Note: alpha values in office 0..255 have to be mapped to
+ // 255..0 in Java
+ Color aCol = new Color (mxComponent.getForeground(), true);
+ maFgColor = new Color (aCol.getRed (),
+ aCol.getGreen (),
+ aCol.getBlue (),
+ 0xff - aCol.getAlpha ());
+ aCol = new Color (mxComponent.getBackground(), true);
+ maBgColor = new Color (aCol.getRed (),
+ aCol.getGreen (),
+ aCol.getBlue (),
+ 0xff - aCol.getAlpha ());
+ }
+ }
+
+ public void updateGeometry ()
+ {
+ if (mxComponent != null)
+ {
+ com.sun.star.awt.Point aLocationOnScreen = mxComponent.getLocationOnScreen();
+ com.sun.star.awt.Size aSizeOnScreen = mxComponent.getSize();
+ maPosition = new Point (
+ aLocationOnScreen.X,
+ aLocationOnScreen.Y);
+ maSize = new Dimension (
+ aSizeOnScreen.Width,
+ aSizeOnScreen.Height);
+ }
+ }
+
+
+ /** Paint the object into the specified canvas. It is transformed
+ according to the specified offset and scale.
+ */
+ public void paint (Graphics2D g,
+ double nXOffset, double nYOffset, double nScaleFactor,
+ boolean bShowDescription, boolean bShowName, boolean bShowText)
+ {
+ try{
+ // Transform the object's position and size according to the
+ // specified offset and scale.
+ Point aLocation = new Point();
+ maShape = new Rectangle2D.Double (
+ maPosition.x * nScaleFactor + nXOffset,
+ maPosition.y * nScaleFactor + nYOffset,
+ maSize.width * nScaleFactor,
+ maSize.height * nScaleFactor);
+
+ // Fill the object's bounding box with its background color if it
+ // has no children.
+ if (mxContext.getAccessibleChildCount() == 0)
+ {
+ g.setColor (maBgColor);
+ g.fill (maShape);
+ }
+
+ // Remove alpha channel from color before drawing the frame.
+ Color color = maFgColor;
+ if (maFgColor.getAlpha()<128)
+ color = new Color (maFgColor.getRed(), maFgColor.getGreen(), maFgColor.getBlue());
+ g.setColor (color);
+ g.draw (maShape);
+
+ if (mbFocused)
+ {
+ g.setColor (maFocusColor);
+ for (int x=0; x<=2; x++)
+ for (int y=0; y<=2; y++)
+ g.fill (
+ new Rectangle2D.Double (
+ maShape.x + x/2.0 * maShape.width-3,
+ maShape.y + y/2.0 * maShape.height-3,
+ 6,
+ 6));
+ }
+ if (mbSelected)
+ {
+ g.setColor (maSelectionColor);
+ for (int x=0; x<=2; x++)
+ for (int y=0; y<=2; y++)
+ g.draw (
+ new Rectangle2D.Double (
+ maShape.x + x/2.0 * maShape.width-2,
+ maShape.y + y/2.0 * maShape.height-2,
+ 4,
+ 4));
+ }
+
+ // Write the object's text OR name and description.
+ g.setColor (maFgColor);
+ if (bShowName)
+ paintName (g);
+ if (bShowDescription)
+ paintDescription (g);
+ if (bShowText)
+ paintText (g);
+ }
+ catch (Exception e)
+ { // don't care
+ }
+ }
+
+ public void paint_highlight (Graphics2D g,
+ double nXOffset, double nYOffset, double nScaleFactor)
+ {
+ if (mbHighlighted)
+ g.setColor (maHighlightColor);
+ else
+ g.setColor (maFgColor);
+ g.draw (maShape);
+ }
+
+
+
+
+ private void paintName (Graphics2D g)
+ {
+ g.drawString ("Name: " + msName,
+ (float)maShape.x+5,
+ (float)maShape.y+15);
+ }
+
+
+
+ private void paintDescription (Graphics2D g)
+ {
+ g.drawString ("Description: " + msDescription,
+ (float)maShape.x+5,
+ (float)maShape.y+35);
+ }
+
+
+
+
+ private void paintText (Graphics2D g)
+ {
+ XAccessibleText xText = null;
+ // get XAccessibleText
+ xText = maNode.getText();
+
+ // Draw every character in the text string.
+ if (xText != null)
+ {
+ String sText = xText.getText();
+ try
+ {
+ for(int i = 0; i < sText.length(); i++)
+ {
+ com.sun.star.awt.Rectangle aRect =
+ xText.getCharacterBounds(i);
+
+ double x = maShape.x + aRect.X;
+ double y = maShape.y + aRect.Y + aRect.Height;
+
+ g.drawString(sText.substring(i, i+1), (float)x, (float)y);
+ }
+ }
+ catch (com.sun.star.lang.IndexOutOfBoundsException e)
+ {}
+ }
+ }
+
+
+
+
+ /** Callback for disposing events.
+ */
+ public void disposing (com.sun.star.lang.EventObject e)
+ {
+ System.out.println ("Disposing");
+ }
+
+
+
+
+ /** Compute whether the specified point lies inside the object's
+ bounding box.
+ */
+ public boolean contains (int x, int y)
+ {
+ return (maShape.contains (x,y));
+ }
+
+ public void highlight ()
+ {
+ mbHighlighted = true;
+ }
+
+ public void unhighlight ()
+ {
+ mbHighlighted = false;
+ }
+
+ public boolean isHighlighted ()
+ {
+ return mbHighlighted;
+ }
+
+ public Rectangle getBBox ()
+ {
+ return new Rectangle (maPosition, maSize);
+ }
+
+ public Point getOrigin ()
+ {
+ return maPosition;
+ }
+
+ public TreePath getPath ()
+ {
+ return new TreePath (maNode.createPath());
+ }
+
+ public int getRole ()
+ {
+ return mnRole;
+ }
+
+ public XAccessibleContext getContext ()
+ {
+ return mxContext;
+ }
+
+ public XAccessibleComponent getComponent ()
+ {
+ return mxComponent;
+ }
+
+ public String toString ()
+ {
+ return ">"+msName+", "+msDescription+" +"+maPosition.x+"+"+maPosition.y
+ +"x"+maSize.width+"x"+maSize.height+"<";
+ }
+
+ private AccTreeNode
+ maNode;
+ private XAccessibleContext
+ mxContext;
+ private XAccessibleComponent
+ mxComponent;
+ private String
+ msDescription,
+ msName;
+ private Rectangle2D.Double
+ maShape;
+ private Point
+ maPosition;
+ private Dimension
+ maTransformedSize,
+ maSize;
+ private Color
+ maFgColor,
+ maBgColor;
+ private boolean
+ // Highlighting objects is an internal concept. Corresponds to selection in the tree view.
+ mbHighlighted,
+ // Set when the accessible object is selected.
+ mbSelected,
+ // Set when the accessible object is focused.
+ mbFocused;
+ private int
+ mnRole;
+}
diff --git a/toolkit/test/accessibility/ChildEventHandler.java b/toolkit/test/accessibility/ChildEventHandler.java
new file mode 100644
index 000000000000..b73c90feac6d
--- /dev/null
+++ b/toolkit/test/accessibility/ChildEventHandler.java
@@ -0,0 +1,46 @@
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.uno.UnoRuntime;
+
+import java.io.PrintStream;
+
+class ChildEventHandler
+ extends EventHandler
+{
+ public ChildEventHandler (AccessibleEventObject aEvent, AccessibilityTreeModel aTreeModel)
+ {
+ super (aEvent, aTreeModel);
+ mxOldChild = (XAccessible)UnoRuntime.queryInterface(
+ XAccessible.class, aEvent.OldValue);
+ mxNewChild = (XAccessible)UnoRuntime.queryInterface(
+ XAccessible.class, aEvent.NewValue);
+ }
+
+ public void PrintOldAndNew (PrintStream out)
+ {
+ if (mxOldChild != null)
+ out.println (" removing child " + mxOldChild);
+ if (mxNewChild != null)
+ out.println (" adding child " + mxNewChild);
+ }
+
+ public void Process ()
+ {
+ // Insertion and removal of children should be mutually exclusive.
+ // But this is a test tool and should take everything into account.
+ if (mxOldChild != null)
+ {
+ maTreeModel.removeNode (mxOldChild.getAccessibleContext());
+ maTreeModel.updateNode (mxEventSource, AccessibleTreeHandler.class);
+ }
+
+ if (mxNewChild != null)
+ {
+ maTreeModel.addChild (mxEventSource, mxNewChild);
+ }
+ }
+
+
+ private XAccessible mxOldChild;
+ private XAccessible mxNewChild;
+}
diff --git a/toolkit/test/accessibility/ContextEventHandler.java b/toolkit/test/accessibility/ContextEventHandler.java
new file mode 100644
index 000000000000..ab7166fdede1
--- /dev/null
+++ b/toolkit/test/accessibility/ContextEventHandler.java
@@ -0,0 +1,52 @@
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.AnyConverter;
+
+import java.io.PrintStream;
+
+import tools.NameProvider;
+
+class ContextEventHandler
+ extends EventHandler
+{
+ public ContextEventHandler (AccessibleEventObject aEvent, AccessibilityTreeModel aTreeModel)
+ {
+ super (aEvent, aTreeModel);
+ }
+
+ public void PrintOldAndNew (PrintStream out)
+ {
+ switch (mnEventId)
+ {
+ case AccessibleEventId.STATE_CHANGED:
+ try
+ {
+ int nOldValue = AnyConverter.toInt (maEvent.OldValue);
+ out.println (" turning off state " + nOldValue + " ("
+ + NameProvider.getStateName (nOldValue) + ")");
+ }
+ catch (com.sun.star.lang.IllegalArgumentException e)
+ {}
+ try
+ {
+ int nNewValue = AnyConverter.toInt (maEvent.NewValue);
+ out.println (" turning on state " + nNewValue + " ("
+ + NameProvider.getStateName (nNewValue) + ")");
+ }
+ catch (com.sun.star.lang.IllegalArgumentException e)
+ {}
+ break;
+
+ default:
+ super.PrintOldAndNew (out);
+ }
+
+ }
+
+ public void Process ()
+ {
+ maTreeModel.updateNode (mxEventSource, AccessibleContextHandler.class);
+ }
+}
diff --git a/toolkit/test/accessibility/EventHandler.java b/toolkit/test/accessibility/EventHandler.java
new file mode 100644
index 000000000000..69f7fd2144f0
--- /dev/null
+++ b/toolkit/test/accessibility/EventHandler.java
@@ -0,0 +1,57 @@
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.uno.UnoRuntime;
+
+import java.io.PrintStream;
+
+import tools.NameProvider;
+
+/** Base class for handling of accessibility events.
+*/
+class EventHandler
+{
+ public EventHandler (AccessibleEventObject aEvent, AccessibilityTreeModel aTreeModel)
+ {
+ maEvent = aEvent;
+ maTreeModel = aTreeModel;
+
+ mnEventId = aEvent.EventId;
+
+ mxEventSource = (XAccessibleContext)UnoRuntime.queryInterface(
+ XAccessibleContext.class, aEvent.Source);
+ if (mxEventSource == null)
+ {
+ XAccessible xAccessible = (XAccessible)UnoRuntime.queryInterface(
+ XAccessible.class, aEvent.Source);
+ if (xAccessible != null)
+ mxEventSource = xAccessible.getAccessibleContext();
+ }
+ }
+
+ public void Print (PrintStream out)
+ {
+ out.println ("Event id is " + mnEventId
+ + " (" + NameProvider.getEventName(mnEventId)+")"
+ + " for " + mxEventSource.getAccessibleName() + " / "
+ + NameProvider.getRoleName (mxEventSource.getAccessibleRole()));
+ PrintOldAndNew (out);
+ }
+
+ public void PrintOldAndNew (PrintStream out)
+ {
+ out.println (" old value is " + maEvent.OldValue);
+ out.println (" new value is " + maEvent.NewValue);
+ }
+
+ public void Process ()
+ {
+ System.out.println ("processing of event " + maEvent + " not implemented");
+ }
+
+ protected AccessibleEventObject maEvent;
+ protected AccessibilityTreeModel maTreeModel;
+
+ protected int mnEventId;
+ protected XAccessibleContext mxEventSource;
+}
diff --git a/toolkit/test/accessibility/EventListener.java b/toolkit/test/accessibility/EventListener.java
new file mode 100644
index 000000000000..619c7fdd355e
--- /dev/null
+++ b/toolkit/test/accessibility/EventListener.java
@@ -0,0 +1,124 @@
+
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.event.TreeModelListener;
+import javax.swing.event.TreeModelEvent;
+
+import java.util.Vector;
+import java.util.HashMap;
+import java.util.Enumeration;
+
+import com.sun.star.accessibility.*;
+import com.sun.star.uno.*;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.Any;
+import com.sun.star.lang.EventObject;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.XServiceName;
+
+/** Objects of this class (usually one, singleton?) listen to accessible
+ events of all objects in all trees.
+*/
+public class EventListener
+{
+ public boolean mbVerbose = false;
+
+ public EventListener (AccessibilityTreeModel aTreeModel)
+ {
+ maTreeModel = aTreeModel;
+ }
+
+
+ private static String objectToString(Object aObject)
+ {
+ if (aObject == null)
+ return null;
+ else
+ return aObject.toString();
+ }
+
+
+
+ /** This method handles accessibility objects that are being disposed.
+ */
+ public void disposing (XAccessibleContext xContext)
+ {
+ if (mbVerbose)
+ System.out.println("disposing " + xContext);
+ maTreeModel.removeNode (xContext);
+ }
+
+ /** This method is called from accessible objects that broadcast
+ modifications of themselves or from their children. The event is
+ processed only, except printing some messages, if the tree is not
+ locked. It should be locked during changes to its internal
+ structure like expanding nodes.
+ */
+ public void notifyEvent (AccessibleEventObject aEvent)
+ {
+ EventHandler aHandler;
+
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId.CHILD:
+ aHandler = new ChildEventHandler (aEvent, maTreeModel);
+ break;
+
+ case AccessibleEventId.BOUNDRECT_CHANGED:
+ case AccessibleEventId.VISIBLE_DATA_CHANGED:
+ aHandler = new GeometryEventHandler (aEvent, maTreeModel);
+ break;
+
+
+ case AccessibleEventId.NAME_CHANGED:
+ case AccessibleEventId.DESCRIPTION_CHANGED:
+ case AccessibleEventId.STATE_CHANGED:
+ case AccessibleEventId.SELECTION_CHANGED:
+ aHandler = new ContextEventHandler (aEvent, maTreeModel);
+ break;
+
+ case AccessibleEventId.TABLE_MODEL_CHANGED:
+ case AccessibleEventId.TABLE_CAPTION_CHANGED:
+ case AccessibleEventId.TABLE_COLUMN_DESCRIPTION_CHANGED:
+ case AccessibleEventId.TABLE_COLUMN_HEADER_CHANGED:
+ case AccessibleEventId.TABLE_ROW_DESCRIPTION_CHANGED:
+ case AccessibleEventId.TABLE_ROW_HEADER_CHANGED:
+ case AccessibleEventId.TABLE_SUMMARY_CHANGED:
+ aHandler = new TableEventHandler (aEvent, maTreeModel);
+ break;
+
+ case AccessibleEventId.ACTION_CHANGED:
+ aHandler = new EventHandler (aEvent, maTreeModel);
+ break;
+
+ case AccessibleEventId.HYPERTEXT_CHANGED:
+ aHandler = new EventHandler (aEvent, maTreeModel);
+ break;
+
+ case AccessibleEventId.ACTIVE_DESCENDANT_CHANGED:
+ case AccessibleEventId.CARET_CHANGED:
+ case AccessibleEventId.TEXT_CHANGED:
+ case AccessibleEventId.VALUE_CHANGED:
+ aHandler = new EventHandler (aEvent, maTreeModel);
+ break;
+
+ default:
+ aHandler = null;
+ break;
+ }
+
+ if (aHandler == null)
+ System.out.println (" unhandled event");
+ else
+ {
+ if (mbVerbose)
+ aHandler.Print (System.out);
+ aHandler.Process ();
+ }
+ }
+
+
+ private AccessibilityTreeModel maTreeModel;
+}
diff --git a/toolkit/test/accessibility/EventLogger.java b/toolkit/test/accessibility/EventLogger.java
new file mode 100644
index 000000000000..de0b8e6aee9d
--- /dev/null
+++ b/toolkit/test/accessibility/EventLogger.java
@@ -0,0 +1,31 @@
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+
+class EventLogger
+{
+ public static synchronized EventLogger Instance ()
+ {
+ if (maInstance == null)
+ maInstance = new EventLogger();
+ return maInstance;
+ }
+
+ private EventLogger ()
+ {
+ try
+ {
+ maFrame = new JFrame ();
+ maLogger = new TextLogger ();
+ maFrame.setContentPane (new JScrollPane (maLogger));
+
+ maFrame.setSize (400,300);
+ maFrame.setVisible (true);
+ }
+ catch (Exception e)
+ {}
+ }
+
+ private static EventLogger maInstance = null;
+ private JFrame maFrame;
+ private TextLogger maLogger;
+}
diff --git a/toolkit/test/accessibility/EventQueue.java b/toolkit/test/accessibility/EventQueue.java
new file mode 100644
index 000000000000..9c90af9c63b7
--- /dev/null
+++ b/toolkit/test/accessibility/EventQueue.java
@@ -0,0 +1,126 @@
+import com.sun.star.accessibility.*;
+import com.sun.star.lang.EventObject;
+
+import java.util.LinkedList;
+
+/** The event queue singleton dispatches events received from OpenOffice.org
+ applications in a thread separate from the AWB main thread.
+
+ The queue of event objects, LinkedList<Runnable> The queue object will
+ also serve as lock for the consumer/producer type syncronization.
+*/
+class EventQueue
+ implements Runnable
+{
+ public boolean mbVerbose = false;
+ public boolean mbHandleDisposingEventsSynchronous = true;
+
+ public synchronized static EventQueue Instance ()
+ {
+ if (maInstance == null)
+ maInstance = new EventQueue ();
+ return maInstance;
+ }
+
+ public void addEvent (Runnable aEvent)
+ {
+ synchronized (maMonitor)
+ {
+ if (mbVerbose)
+ System.out.println ("queing regular event " + aEvent);
+ maRegularQueue.addLast (aEvent);
+ maMonitor.notify ();
+ }
+ }
+
+
+ public void addDisposingEvent (Runnable aEvent)
+ {
+ if (mbHandleDisposingEventsSynchronous)
+ aEvent.run ();
+ else
+ synchronized (maMonitor)
+ {
+ if (mbVerbose)
+ System.out.println ("queing disposing event " + aEvent);
+ maDisposingQueue.addLast (aEvent);
+ maMonitor.notify ();
+ }
+ }
+
+
+ private EventQueue ()
+ {
+ maMonitor = new Boolean (true);
+ maRegularQueue = new LinkedList();
+ maDisposingQueue = new LinkedList();
+ new Thread(this, "AWB.EventQueue").start();
+ }
+
+
+ /// This thread's main method: deliver all events
+ public void run()
+ {
+ // in an infinite loop, check for events to deliver, then
+ // wait on lock (which will be notified when new events arrive)
+ while( true )
+ {
+ Runnable aEvent = null;
+ do
+ {
+ synchronized (maMonitor)
+ {
+ if (maDisposingQueue.size() > 0)
+ {
+ aEvent = (Runnable)maDisposingQueue.removeFirst();
+ if (mbVerbose)
+ System.out.println ("delivering disposing event " + aEvent);
+ }
+ else if (maRegularQueue.size() > 0)
+ {
+ aEvent = (Runnable)maRegularQueue.removeFirst();
+ if (mbVerbose)
+ System.out.println ("delivering regular event " + aEvent);
+ }
+ else
+ aEvent = null;
+ }
+ if (aEvent != null)
+ {
+ try
+ {
+ aEvent.run();
+ }
+ catch( Throwable e )
+ {
+ System.out.println(
+ "caught exception during event delivery: " + e );
+ e.printStackTrace();
+ }
+ }
+ }
+ while( aEvent != null );
+
+ try
+ {
+ synchronized (maMonitor)
+ {
+ maMonitor.wait();
+ }
+ }
+ catch (Exception e)
+ {
+ // can't wait? odd!
+ System.err.println("Can't wait!");
+ e.printStackTrace();
+ }
+ }
+ }
+
+ private static EventQueue maInstance = null;
+ private Object maMonitor;
+ private LinkedList maRegularQueue;
+ private LinkedList maDisposingQueue;
+}
+
+
diff --git a/toolkit/test/accessibility/FrameActionListener.java b/toolkit/test/accessibility/FrameActionListener.java
new file mode 100644
index 000000000000..30324fb9bc52
--- /dev/null
+++ b/toolkit/test/accessibility/FrameActionListener.java
@@ -0,0 +1,21 @@
+import com.sun.star.frame.XFrameActionListener;
+import com.sun.star.frame.FrameActionEvent;
+
+import com.sun.star.lang.EventObject;
+
+public class FrameActionListener
+ implements XFrameActionListener
+{
+ public FrameActionListener ()
+ {
+ }
+
+ public void frameAction (com.sun.star.frame.FrameActionEvent aEvent)
+ {
+ System.out.println ("frame action");
+ }
+
+ public void disposing (com.sun.star.lang.EventObject aEvent)
+ {
+ }
+}
diff --git a/toolkit/test/accessibility/GeometryEventHandler.java b/toolkit/test/accessibility/GeometryEventHandler.java
new file mode 100644
index 000000000000..07236785e862
--- /dev/null
+++ b/toolkit/test/accessibility/GeometryEventHandler.java
@@ -0,0 +1,54 @@
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.uno.UnoRuntime;
+
+import java.io.PrintStream;
+import java.util.LinkedList;
+
+class GeometryEventHandler
+ extends EventHandler
+{
+ public GeometryEventHandler (AccessibleEventObject aEvent, AccessibilityTreeModel aTreeModel)
+ {
+ super (aEvent, aTreeModel);
+ }
+
+ public void PrintOldAndNew (PrintStream out)
+ {
+ out.println (" children not relevant");
+ }
+
+ public void Process ()
+ {
+ AccTreeNode aNode = maTreeModel.updateNode (mxEventSource,
+ AccessibleComponentHandler.class,
+ AccessibleExtendedComponentHandler.class);
+
+ // Update the graphical representation of aNode in the Canvas.
+ Canvas aCanvas = maTreeModel.getCanvas();
+ if (aCanvas != null)
+ {
+ // Iterate over all nodes in the sub-tree rooted in aNode.
+ LinkedList aShapeQueue = new LinkedList();
+ aShapeQueue.addLast (aNode);
+ while (aShapeQueue.size() > 0)
+ {
+ // Remove the first node from the queue and update its
+ // graphical representation.
+ AccTreeNode aShapeNode = (AccTreeNode) aShapeQueue.getFirst();
+ aShapeQueue.removeFirst();
+ aCanvas.updateNodeGeometry (aShapeNode);
+
+ // Add the node's children to the queue.
+ int nChildCount = maTreeModel.getChildCount (aShapeNode);
+ for (int i=0; i<nChildCount; i++)
+ {
+ Object aTreeNode = maTreeModel.getChildNoCreate (aShapeNode, i);
+ if (aTreeNode instanceof AccTreeNode)
+ aShapeQueue.addLast (aTreeNode);
+ }
+ }
+ aCanvas.repaint ();
+ }
+ }
+}
diff --git a/toolkit/test/accessibility/HelpWindow.java b/toolkit/test/accessibility/HelpWindow.java
new file mode 100644
index 000000000000..74627ad99761
--- /dev/null
+++ b/toolkit/test/accessibility/HelpWindow.java
@@ -0,0 +1,185 @@
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JEditorPane;
+import javax.swing.JButton;
+import java.net.URL;
+import javax.swing.event.HyperlinkListener;
+import javax.swing.event.HyperlinkEvent;
+import java.net.MalformedURLException;
+import java.io.IOException;
+import java.io.File;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.event.ActionListener;
+import java.util.LinkedList;
+
+class HelpWindow
+ implements ActionListener
+{
+ public static synchronized HelpWindow Instance ()
+ {
+ if (maInstance == null)
+ maInstance = new HelpWindow();
+ return maInstance;
+ }
+
+ public void loadFile (String sFilename)
+ {
+ File aFile = new File (sFilename);
+ try
+ {
+ loadURL (aFile.toURL());
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace (System.err);
+ }
+ }
+ public void loadURL (String sURL)
+ {
+ try
+ {
+ loadURL (new URL (sURL));
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace (System.err);
+ }
+ }
+
+
+
+
+ public void loadURL (URL aURL)
+ {
+ maHistory.addLast (aURL);
+ selectHistoryPage (maHistory.size()-1);
+ maFrame.toFront ();
+ }
+
+
+
+
+ private HelpWindow ()
+ {
+ try
+ {
+ maCurrentHistoryEntry = -1;
+ maHistory = new LinkedList();
+
+ maFrame = new JFrame ();
+ maFrame.addWindowListener (new WindowAdapter ()
+ {
+ public void windowClosing (WindowEvent e)
+ {
+ maInstance = null;
+ }
+ });
+ maContent = createContentWidget();
+
+ maFrame.getContentPane().setLayout (new GridBagLayout());
+ GridBagConstraints aConstraints = new GridBagConstraints ();
+ aConstraints.gridx = 0;
+ aConstraints.gridy = 0;
+ aConstraints.gridwidth = 3;
+ aConstraints.weightx = 1;
+ aConstraints.weighty = 1;
+ aConstraints.fill = GridBagConstraints.BOTH;
+ maFrame.getContentPane().add (new JScrollPane (maContent), aConstraints);
+
+ aConstraints = new GridBagConstraints();
+ aConstraints.gridx = 0;
+ aConstraints.gridy = 1;
+ maPrevButton = new JButton ("Prev");
+ maFrame.getContentPane().add (maPrevButton, aConstraints);
+ maPrevButton.addActionListener (this);
+
+ aConstraints = new GridBagConstraints();
+ aConstraints.gridx = 1;
+ aConstraints.gridy = 1;
+ maNextButton = new JButton ("Next");
+ maFrame.getContentPane().add (maNextButton, aConstraints);
+ maNextButton.addActionListener (this);
+
+ aConstraints = new GridBagConstraints();
+ aConstraints.gridx = 2;
+ aConstraints.gridy = 1;
+ aConstraints.anchor = GridBagConstraints.EAST;
+ JButton aButton = new JButton ("Close");
+ maFrame.getContentPane().add (aButton, aConstraints);
+ aButton.addActionListener (this);
+
+ maFrame.setSize (600,400);
+ maFrame.setVisible (true);
+ }
+ catch (Exception e)
+ {}
+ }
+
+ public void actionPerformed (java.awt.event.ActionEvent e)
+ {
+ if (e.getActionCommand().equals("Prev"))
+ {
+ selectHistoryPage (maCurrentHistoryEntry - 1);
+ }
+ else if (e.getActionCommand().equals("Next"))
+ {
+ selectHistoryPage (maCurrentHistoryEntry + 1);
+ }
+ else if (e.getActionCommand().equals("Close"))
+ {
+ maFrame.dispose ();
+ maInstance = null;
+ }
+ }
+
+ private JEditorPane createContentWidget ()
+ {
+ JEditorPane aContent = new JEditorPane ();
+ aContent.setEditable (false);
+ aContent.addHyperlinkListener (new HyperlinkListener()
+ {
+ public void hyperlinkUpdate (HyperlinkEvent e)
+ {
+ if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
+ HelpWindow.Instance().loadURL (e.getURL());
+ }
+ });
+ return aContent;
+ }
+
+ private void selectHistoryPage (int i)
+ {
+ if (i < 0)
+ i = 0;
+ else if (i >= maHistory.size()-1)
+ i = maHistory.size()-1;
+ if (i != maCurrentHistoryEntry)
+ {
+ URL aURL = (URL)maHistory.get (i);
+ try
+ {
+ maContent.setPage (aURL);
+ }
+ catch (java.io.IOException ex)
+ {
+ ex.printStackTrace(System.err);
+ }
+
+ maCurrentHistoryEntry = i;
+ }
+
+ maPrevButton.setEnabled (maCurrentHistoryEntry > 0);
+ maNextButton.setEnabled (maCurrentHistoryEntry < maHistory.size()-1);
+ }
+
+ private static HelpWindow maInstance = null;
+ private JFrame maFrame;
+ private JEditorPane maContent;
+ private LinkedList maHistory;
+ private int maCurrentHistoryEntry;
+ private JButton maPrevButton;
+ private JButton maNextButton;
+}
diff --git a/toolkit/test/accessibility/InformationWriter.java b/toolkit/test/accessibility/InformationWriter.java
new file mode 100755
index 000000000000..e119d2037350
--- /dev/null
+++ b/toolkit/test/accessibility/InformationWriter.java
@@ -0,0 +1,415 @@
+import java.lang.Thread;
+
+import com.sun.star.awt.Rectangle;
+import com.sun.star.awt.XWindow;
+
+import com.sun.star.beans.Property;
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.XPropertySet;
+import com.sun.star.beans.XPropertySetInfo;
+
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XChild;
+import com.sun.star.container.XEnumerationAccess;
+import com.sun.star.container.XEnumeration;
+
+import com.sun.star.frame.XComponentLoader;
+import com.sun.star.frame.XController;
+import com.sun.star.frame.XDesktop;
+import com.sun.star.frame.XFrame;
+import com.sun.star.frame.XTasksSupplier;
+import com.sun.star.frame.XTask;
+
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.XServiceName;
+import com.sun.star.lang.XTypeProvider;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.Type;
+
+import com.sun.star.drawing.XDrawView;
+import com.sun.star.drawing.XDrawPage;
+import com.sun.star.drawing.XShapes;
+import com.sun.star.drawing.XShape;
+import com.sun.star.drawing.XShapeDescriptor;
+
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleComponent;
+import com.sun.star.accessibility.XAccessibleRelationSet;
+import com.sun.star.accessibility.XAccessibleStateSet;
+
+public class InformationWriter
+{
+ public InformationWriter ()
+ {
+ }
+
+ public void drawPageTest (XInterface xPage)
+ {
+ try
+ {
+ printProperty (xPage, "BorderBottom ", "BorderBottom");
+ printProperty (xPage, "BorderLeft ", "BorderLeft");
+ printProperty (xPage, "BorderRight ", "BorderRight");
+ printProperty (xPage, "BorderTop ", "BorderTop");
+ printProperty (xPage, "Height ", "Height");
+ printProperty (xPage, "Width ", "Width");
+ printProperty (xPage, "Number ", "Number");
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception while testing draw page:" + e);
+ }
+ }
+
+ public void printProperty (XInterface xObject, String prefix, String name)
+ {
+ try
+ {
+ XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xObject);
+ MessageArea.println (prefix +
+ xPropertySet.getPropertyValue (name));
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while getting property "
+ + name + " : " + e);
+ }
+ }
+
+
+
+ public void showShapes (XDrawPage xPage)
+ {
+ try
+ {
+ XIndexAccess xShapeList = (XIndexAccess) UnoRuntime.queryInterface(
+ XIndexAccess.class, xPage);
+
+ MessageArea.println ("There are " + xShapeList.getCount()
+ + " shapes");
+ for (int i=0; i<xShapeList.getCount(); i++)
+ {
+ XShape xShape = (XShape) UnoRuntime.queryInterface(
+ XShape.class, xShapeList.getByIndex (i));
+
+ XShapeDescriptor xShapeDescriptor =
+ (XShapeDescriptor) UnoRuntime.queryInterface(
+ XShapeDescriptor.class, xShape);
+ String sName = xShapeDescriptor.getShapeType ();
+ MessageArea.println (" shape " + i + " : " + sName);
+
+ XPropertySet xPropertySet =
+ (XPropertySet) UnoRuntime.queryInterface(
+ XPropertySet.class, xShape);
+ Integer nZOrder =
+ (Integer) xPropertySet.getPropertyValue ("ZOrder");
+ MessageArea.println (" zorder = " + nZOrder);
+ }
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception in showShapes: " + e);
+ }
+ }
+
+
+
+
+ /** @descr Print all available services of the given object to the
+ standard output.
+ */
+ public void showServices (XInterface xObject)
+ {
+ try
+ {
+ MessageArea.println ("Services:");
+ XMultiServiceFactory xMSF = (XMultiServiceFactory) UnoRuntime.queryInterface (
+ XMultiServiceFactory.class,
+ xObject
+ );
+ if (xMSF == null)
+ MessageArea.println (" object does not support interface XMultiServiceFactory");
+ else
+ {
+ String[] sServiceNames = xMSF.getAvailableServiceNames ();
+ MessageArea.println (" object can create "
+ + sServiceNames.length + " services");
+ for (int i=0; i<sServiceNames.length; i++)
+ MessageArea.println (" service " + i + " : " + sServiceNames[i]);
+ }
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception in showServices : " + e);
+ }
+ }
+
+ /** @descr Print the service and implementation name of the given
+ object.
+ */
+ public void showInfo (XInterface xObject)
+ {
+ try
+ {
+ System.out.println ("Info:");
+ // Use interface XServiceName to retrieve name of (main) service.
+ XServiceName xSN = (XServiceName) UnoRuntime.queryInterface (
+ XServiceName.class, xObject);
+ if (xSN == null)
+ MessageArea.println (" interface XServiceName not supported");
+ else
+ {
+ MessageArea.println (" Service name : " + xSN.getServiceName ());
+ }
+
+ // Use interface XServiceInfo to retrieve information about
+ // supported services.
+ XServiceInfo xSI = (XServiceInfo) UnoRuntime.queryInterface (
+ XServiceInfo.class, xObject);
+ if (xSI == null)
+ MessageArea.println (" interface XServiceInfo not supported");
+ else
+ {
+ MessageArea.println (" Implementation name : "
+ + xSI.getImplementationName ());
+ }
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception in showInfo : " + e);
+ }
+ }
+
+
+
+
+ /** @descr Print information about supported interfaces.
+ */
+ public void showInterfaces (XInterface xObject)
+ {
+ try
+ {
+ MessageArea.println ("Interfaces:");
+ // Use interface XTypeProvider to retrieve a list of supported
+ // interfaces.
+ XTypeProvider xTP = (XTypeProvider) UnoRuntime.queryInterface (
+ XTypeProvider.class, xObject);
+ if (xTP == null)
+ MessageArea.println (" interface XTypeProvider not supported");
+ else
+ {
+ Type[] aTypeList = xTP.getTypes ();
+ MessageArea.println (" object supports " + aTypeList.length
+ + " interfaces");
+ for (int i=0; i<aTypeList.length; i++)
+ MessageArea.println (" " + i + " : "
+ + aTypeList[i].getTypeName());
+ }
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception in showInterfaces : " + e);
+ }
+ }
+
+
+ /** @descr Print information concerning the accessibility of the given
+ object.
+ */
+ public boolean showAccessibility (XInterface xObject, int depth)
+ {
+ try
+ {
+ // Create indentation string.
+ String sIndent = "";
+ while (depth-- > 0)
+ sIndent += " ";
+
+ // Get XAccessibleContext object if given object does not
+ // already support this interface.
+ XAccessibleContext xContext
+ = (XAccessibleContext) UnoRuntime.queryInterface (
+ XAccessibleContext.class, xObject);
+ if (xContext == null)
+ {
+ XAccessible xAccessible
+ = (XAccessible) UnoRuntime.queryInterface (
+ XAccessible.class, xObject);
+ if (xAccessible == null)
+ {
+ MessageArea.println (sIndent + "given object " + xObject
+ + " is not accessible");
+ return false;
+ }
+ else
+ xContext = xAccessible.getAccessibleContext();
+ }
+
+ // Print information about the accessible context.
+ if (xContext != null)
+ {
+ MessageArea.println (sIndent + "Name : "
+ + xContext.getAccessibleName());
+ MessageArea.println (sIndent + "Description : "
+ + xContext.getAccessibleDescription());
+ MessageArea.println (sIndent + "Role : "
+ + xContext.getAccessibleRole());
+ String sHasParent;
+ if (xContext.getAccessibleParent() != null)
+ {
+ MessageArea.println (sIndent + "Has parent : yes");
+ MessageArea.println (sIndent + "Parent index : "
+ + xContext.getAccessibleIndexInParent());
+ }
+ else
+ MessageArea.println (sIndent + "Has parent : no");
+ MessageArea.println (sIndent + "Child count : "
+ + xContext.getAccessibleChildCount());
+ MessageArea.print (sIndent + "Relation set : ");
+ XAccessibleRelationSet xRelationSet
+ = xContext.getAccessibleRelationSet();
+ if (xRelationSet != null)
+ {
+ MessageArea.print (xRelationSet.getRelationCount() + " (");
+ for (int i=0; i<xRelationSet.getRelationCount(); i++)
+ {
+ if (i > 0)
+ MessageArea.print (", ");
+ MessageArea.print (xRelationSet.getRelation(i).toString());
+ }
+ MessageArea.println (")");
+ }
+ else
+ MessageArea.println ("no relation set");
+
+ MessageArea.print (sIndent + "State set : ");
+ XAccessibleStateSet xStateSet =
+ xContext.getAccessibleStateSet();
+ if (xStateSet != null)
+ {
+ XIndexAccess xStates =
+ (XIndexAccess) UnoRuntime.queryInterface (
+ XIndexAccess.class, xStateSet);
+ MessageArea.print (xStates.getCount() + " (");
+ for (int i=0; i<xStates.getCount(); i++)
+ {
+ if (i > 0)
+ MessageArea.print (", ");
+ MessageArea.print (xStates.getByIndex(i).toString());
+ }
+ MessageArea.println (")");
+ }
+ else
+ MessageArea.println ("no state set");
+
+ showAccessibleComponent (xContext, sIndent);
+ }
+ else
+ MessageArea.println ("object has no accessible context.");
+
+ // showInfo (xContext);
+ // showServices (xContext);
+ // showInterfaces (xContext);
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception in showAccessibility :" + e);
+ }
+ return true;
+ }
+
+
+
+
+ /** @descr Print information about the given accessible component.
+ */
+ public void showAccessibleComponent (XInterface xObject, String sIndent)
+ {
+ try
+ {
+ XAccessibleComponent xComponent =
+ (XAccessibleComponent) UnoRuntime.queryInterface (
+ XAccessibleComponent.class, xObject);
+
+ // Print information about the accessible context.
+ if (xComponent != null)
+ {
+ MessageArea.println (sIndent + "Position : "
+ + xComponent.getLocation().X+", "
+ + xComponent.getLocation().Y);
+ MessageArea.println (sIndent + "Screen position : "
+ + xComponent.getLocationOnScreen().X+", "
+ + xComponent.getLocationOnScreen().Y);
+ MessageArea.println (sIndent + "Size : "
+ + xComponent.getSize().Width+", "
+ + xComponent.getSize().Height);
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println (
+ "caught exception in showAccessibleComponent : " + e);
+ }
+ }
+
+
+ /** Show a textual representation of the accessibility subtree rooted in
+ xRoot.
+ */
+ public boolean showAccessibilityTree (XAccessible xRoot, int depth)
+ {
+ try
+ {
+ if ( ! showAccessibility (xRoot, depth))
+ return false;
+
+ String sIndent = "";
+ for (int i=0; i<depth; i++)
+ sIndent += " ";
+
+ // Iterate over children and show them.
+ XAccessibleContext xContext = xRoot.getAccessibleContext();
+ if (xContext != null)
+ {
+ int n = xContext.getAccessibleChildCount();
+ for (int i=0; i<n; i++)
+ {
+ MessageArea.println (sIndent + "child " + i + " :");
+ showAccessibilityTree (xContext.getAccessibleChild(i),depth+1);
+ }
+ }
+ else
+ MessageArea.println ("Accessible object has no context");
+ }
+ catch (Exception e)
+ {
+ System.out.println (
+ "caught exception in showAccessibleTree : " + e);
+ return false;
+ }
+
+ return true;
+ }
+
+ public void showProperties (XInterface xObject)
+ {
+ XPropertySet xSet = (XPropertySet) UnoRuntime.queryInterface (
+ XPropertySet.class, xObject);
+ if (xSet == null)
+ MessageArea.println ("object does not support XPropertySet");
+ else
+ {
+ XPropertySetInfo xInfo = xSet.getPropertySetInfo ();
+ Property[] aProperties = xInfo.getProperties ();
+ int n = aProperties.length;
+ for (int i=0; i<n; i++)
+ MessageArea.println (i + " : " + aProperties[i].Name +", " + aProperties[i].Type);
+ }
+ }
+}
diff --git a/toolkit/test/accessibility/MessageArea.java b/toolkit/test/accessibility/MessageArea.java
new file mode 100644
index 000000000000..c9d95995e066
--- /dev/null
+++ b/toolkit/test/accessibility/MessageArea.java
@@ -0,0 +1,123 @@
+import java.awt.Font;
+import java.awt.Rectangle;
+import java.awt.Color;
+import java.awt.Graphics;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JScrollBar;
+
+
+
+/** A message area displays text in a scrollable text widget. It is a
+ singleton. Other objects can access it directly to display messages.
+*/
+public class MessageArea
+ extends JScrollPane
+{
+ public static synchronized MessageArea Instance ()
+ {
+ if (saInstance == null)
+ saInstance = new MessageArea ();
+ return saInstance;
+ }
+
+
+
+
+ /** Create a new message area. This method is private because the class is
+ a singleton and may therefore not be instanciated from the outside.
+ */
+ private MessageArea ()
+ {
+ maText = new JTextArea();
+ maText.setBackground (new Color (255,250,240));
+ maText.setFont (new Font ("Helvetica", Font.PLAIN, 9));
+ setViewportView (maText);
+ setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+ setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+
+ printMessage (
+ "class path is " + System.getProperty ("java.class.path") + "\n");
+ }
+
+
+
+
+ /** Show the given string at the end of the message area and scroll to make
+ it visible.
+ */
+ public static synchronized void print (String aMessage)
+ {
+ print (0, aMessage);
+ }
+
+
+
+
+ /** Show the given string at the end of the message area and scroll to make
+ it visible. Indent the string as requested.
+ */
+ public static synchronized void print (int nIndentation, String aMessage)
+ {
+ while (nIndentation-- > 0)
+ aMessage = " " + aMessage;
+ Instance().printMessage(aMessage);
+ }
+
+
+
+
+ /** Show the given string at the end of the message area and scroll to make
+ it visible.
+ */
+ public static void println (String aMessage)
+ {
+ println (0, aMessage);
+ }
+
+
+
+
+ /** Show the given string at the end of the message area and scroll to make
+ it visible.
+ */
+ public static void println (int nIndentation, String aMessage)
+ {
+ print (nIndentation, aMessage+"\n");
+ }
+
+
+
+
+ public void paintComponent (Graphics g)
+ {
+ synchronized (g)
+ {
+ JScrollBar sb = getVerticalScrollBar();
+ if (sb != null)
+ {
+ int nScrollBarValue = sb.getMaximum() - sb.getVisibleAmount() - 1;
+ sb.setValue (nScrollBarValue);
+ }
+ super.paintComponent (g);
+ }
+ }
+
+
+
+
+ /** Append the given string to the end of the text and scroll so that it
+ becomes visible. This is an internal method. Use one of the static
+ and public ones.
+ */
+ private synchronized void printMessage (String aMessage)
+ {
+ maText.append (aMessage);
+ }
+
+
+
+
+ private static MessageArea saInstance = null;
+ private JTextArea maText;
+}
diff --git a/toolkit/test/accessibility/MessageInterface.java b/toolkit/test/accessibility/MessageInterface.java
new file mode 100755
index 000000000000..ad189bb8214f
--- /dev/null
+++ b/toolkit/test/accessibility/MessageInterface.java
@@ -0,0 +1,5 @@
+interface MessageInterface
+{
+ void message (String text);
+}
+
diff --git a/toolkit/test/accessibility/NodeFactory.java b/toolkit/test/accessibility/NodeFactory.java
new file mode 100644
index 000000000000..403c482e5ea1
--- /dev/null
+++ b/toolkit/test/accessibility/NodeFactory.java
@@ -0,0 +1,147 @@
+import com.sun.star.accessibility.*;
+import java.util.Vector;
+
+import tools.NameProvider;
+
+/** This singleton class creates nodes for given accessible objects.
+*/
+class NodeFactory
+{
+ public synchronized static NodeFactory Instance ()
+ {
+ if (maInstance == null)
+ {
+ maInstance = new NodeFactory();
+ }
+ return maInstance;
+ }
+
+ private NodeFactory ()
+ {
+ mbVerbose = false;
+
+ maContextHandler = new AccessibleContextHandler();
+ maTextHandler = new AccessibleTextHandler();
+ maEditableTextHandler = new AccessibleEditableTextHandler();
+ maComponentHandler = new AccessibleComponentHandler();
+ maExtendedComponentHandler = new AccessibleExtendedComponentHandler();
+ maActionHandler = new AccessibleActionHandler();
+ maImageHandler = new AccessibleImageHandler();
+ maTableHandler = new AccessibleTableHandler();
+ maCellHandler = new AccessibleCellHandler();
+ maHypertextHandler = new AccessibleHypertextHandler();
+ maHyperlinkHandler = new AccessibleHyperlinkHandler();
+ maSelectionHandler = new AccessibleSelectionHandler();
+ maRelationHandler = new AccessibleRelationHandler();
+ maTreeHandler = new AccessibleTreeHandler();
+ maUNOHandler = new AccessibleUNOHandler();
+ }
+
+
+ /** add default handlers based on the supported interfaces */
+ private void addDefaultHandlers (AccTreeNode aNode, XAccessibleContext xContext)
+ {
+ if (false)
+ {
+ // Slow but complete version: try each handler type separately.
+ aNode.addHandler (maContextHandler.createHandler (xContext));
+ aNode.addHandler (maTextHandler.createHandler (xContext));
+ aNode.addHandler (maEditableTextHandler.createHandler (xContext));
+ aNode.addHandler (maComponentHandler.createHandler (xContext));
+ aNode.addHandler (maExtendedComponentHandler.createHandler (xContext));
+ aNode.addHandler (maActionHandler.createHandler (xContext));
+ aNode.addHandler (maImageHandler.createHandler (xContext));
+ aNode.addHandler (maTableHandler.createHandler (xContext));
+ aNode.addHandler (maCellHandler.createHandler (xContext));
+ aNode.addHandler (maHypertextHandler.createHandler (xContext));
+ aNode.addHandler (maHyperlinkHandler.createHandler (xContext));
+ aNode.addHandler (maSelectionHandler.createHandler (xContext));
+ aNode.addHandler (maRelationHandler.createHandler (xContext));
+ aNode.addHandler (maUNOHandler.createHandler (xContext));
+ aNode.addHandler (maTreeHandler.createHandler (xContext));
+ }
+ else
+ {
+ // Exploit dependencies between interfaces.
+ NodeHandler aHandler;
+ aNode.addHandler (maContextHandler.createHandler (xContext));
+
+ aHandler = maTextHandler.createHandler (xContext);
+ if (aHandler != null)
+ {
+ aNode.addHandler (aHandler);
+ aNode.addHandler (maEditableTextHandler.createHandler (xContext));
+ aNode.addHandler (maHypertextHandler.createHandler (xContext));
+ aNode.addHandler (maHyperlinkHandler.createHandler (xContext));
+ }
+ aHandler = maComponentHandler.createHandler (xContext);
+ if (aHandler != null)
+ {
+ aNode.addHandler (aHandler);
+ aNode.addHandler (maExtendedComponentHandler.createHandler (xContext));
+ }
+ aNode.addHandler (maActionHandler.createHandler (xContext));
+ aNode.addHandler (maImageHandler.createHandler (xContext));
+ aNode.addHandler (maTableHandler.createHandler (xContext));
+ aNode.addHandler (maRelationHandler.createHandler (xContext));
+ aNode.addHandler (maCellHandler.createHandler (xContext));
+ aNode.addHandler (maSelectionHandler.createHandler (xContext));
+ aNode.addHandler (maUNOHandler.createHandler (xContext));
+ aNode.addHandler (maTreeHandler.createHandler (xContext));
+ }
+ }
+
+ /** create a node with the default handlers */
+ public AccTreeNode createDefaultNode (XAccessible xAccessible, AccessibleTreeNode aParent)
+ {
+ // default: aObject + aDisplay
+ String sDisplay;
+
+ // if we are accessible, we use the context + name instead
+ XAccessibleContext xContext = null;
+ if (xAccessible != null)
+ xContext = xAccessible.getAccessibleContext();
+ if (xContext != null)
+ {
+ sDisplay = xContext.getAccessibleName();
+ if (sDisplay.length()==0)
+ {
+ sDisplay = "<no name> Role: "
+ + NameProvider.getRoleName (
+ xContext.getAccessibleRole());
+ }
+ }
+ else
+ sDisplay = new String ("not accessible");
+
+
+ // create node, and add default handlers
+ AccTreeNode aNode = new AccTreeNode (xAccessible, xContext, sDisplay, aParent);
+ addDefaultHandlers (aNode, xContext);
+
+ if (aNode == null)
+ System.out.println ("createDefaultNode == null");
+ return aNode;
+ }
+
+ private static NodeFactory maInstance = null;
+
+ private boolean mbVerbose;
+
+ // default handlers
+ private NodeHandler maContextHandler = new AccessibleContextHandler();
+ private NodeHandler maTextHandler = new AccessibleTextHandler();
+ private NodeHandler maEditableTextHandler = new AccessibleEditableTextHandler();
+ private NodeHandler maComponentHandler = new AccessibleComponentHandler();
+ private NodeHandler maExtendedComponentHandler = new AccessibleExtendedComponentHandler();
+ private NodeHandler maActionHandler = new AccessibleActionHandler();
+ private NodeHandler maImageHandler = new AccessibleImageHandler();
+ private NodeHandler maTableHandler = new AccessibleTableHandler();
+ private NodeHandler maCellHandler = new AccessibleCellHandler();
+ private NodeHandler maHypertextHandler = new AccessibleHypertextHandler();
+ private NodeHandler maHyperlinkHandler = new AccessibleHyperlinkHandler();
+ private NodeHandler maSelectionHandler = new AccessibleSelectionHandler();
+ private NodeHandler maRelationHandler = new AccessibleRelationHandler();
+ private NodeHandler maTreeHandler = new AccessibleTreeHandler();
+ private NodeHandler maUNOHandler = new AccessibleUNOHandler();
+}
diff --git a/toolkit/test/accessibility/NodeHandler.java b/toolkit/test/accessibility/NodeHandler.java
new file mode 100644
index 000000000000..b39741b1f398
--- /dev/null
+++ b/toolkit/test/accessibility/NodeHandler.java
@@ -0,0 +1,140 @@
+import java.util.Vector;
+
+
+/**
+ * Map an arbitrary object into parts of a tree node.
+ */
+abstract class NodeHandler
+{
+ /** This vector is used as cache for the child objects.
+ */
+ protected Vector maChildList;
+
+
+ public abstract NodeHandler createHandler (
+ com.sun.star.accessibility.XAccessibleContext xContext);
+
+ public NodeHandler ()
+ {
+ maChildList = new Vector ();
+ }
+
+ /** Clear the cache of child objects.
+ */
+ public void clear ()
+ {
+ synchronized (maChildList)
+ {
+ maChildList = new Vector ();
+ }
+ }
+
+ /** This factory method creates an individual handler for the specified
+ object that may hold information to accelerate the access to its children.
+ */
+ // public abstract NodeHandler createHandler (Object aObject);
+
+ /** return the number of children this object has */
+ public int getChildCount(Object aObject)
+ {
+ synchronized (maChildList)
+ {
+ return maChildList.size();
+ }
+ }
+
+ /**
+ * return a child object. Complex
+ * children have to be AccTreeNode instances.
+ * @see AccTreeNode
+ */
+ public AccessibleTreeNode getChild (AccessibleTreeNode aParent, int nIndex)
+ {
+ synchronized (maChildList)
+ {
+ AccessibleTreeNode aChild = (AccessibleTreeNode)maChildList.get(nIndex);
+ if (aChild == null)
+ {
+ aChild = createChild (aParent, nIndex);
+ if (aChild == null)
+ aChild = new StringNode ("could not create child", aParent);
+ maChildList.setElementAt (aChild, nIndex);
+ }
+ return aChild;
+ }
+ }
+
+ public AccessibleTreeNode getChildNoCreate (AccessibleTreeNode aParent, int nIndex)
+ {
+ synchronized (maChildList)
+ {
+ return (AccessibleTreeNode)maChildList.get(nIndex);
+ }
+ }
+
+ /** Remove the specified child from the list of children.
+ */
+ public boolean removeChild (AccessibleTreeNode aNode, int nIndex)
+ {
+ try
+ {
+ synchronized (maChildList)
+ {
+ System.out.println (" removing child at position " + nIndex + ": "
+ + maChildList.elementAt (nIndex));
+ maChildList.remove (nIndex);
+ }
+ }
+ catch (Exception e)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ public int indexOf (AccessibleTreeNode aNode)
+ {
+ synchronized (maChildList)
+ {
+ return maChildList.indexOf (aNode);
+ }
+ }
+
+ /** Create a child object for the specified data. This method is called
+ usually from getChild and put there into the cache.
+ */
+ public abstract AccessibleTreeNode createChild (
+ AccessibleTreeNode aParent, int nIndex);
+
+ //
+ // The following methods support editing of children and actions.
+ // They have default implementations for no actions and read-only.
+ //
+
+ /** May this child be changed? */
+ public boolean isChildEditable (AccessibleTreeNode aNode, int nIndex)
+ {
+ return false;
+ }
+
+ /** change this child's value */
+ // public void setChild(Object aObject, int nIndex) { }
+
+
+ /** get names of suported actions */
+ public String[] getActions (AccessibleTreeNode aNode)
+ {
+ return new String[] {};
+ }
+
+ /** perform action */
+ public void performAction (AccessibleTreeNode aNode, int nIndex)
+ {
+ }
+
+ /** Update all children.
+ */
+ public void update (AccessibleTreeNode aNode)
+ {
+ }
+}
diff --git a/toolkit/test/accessibility/NodeMap.java b/toolkit/test/accessibility/NodeMap.java
new file mode 100644
index 000000000000..43479278aec4
--- /dev/null
+++ b/toolkit/test/accessibility/NodeMap.java
@@ -0,0 +1,112 @@
+import com.sun.star.accessibility.XAccessibleContext;
+
+import java.util.HashMap;
+
+abstract class NodeMapCallback
+{
+ public abstract void Apply (AccTreeNode aNode);
+}
+
+/** This map translates from XAccessible objects to our internal
+ representations.
+*/
+class NodeMap
+{
+ public NodeMap ()
+ {
+ maXAccessibleToNode = new HashMap ();
+ }
+
+ /** Clear the whole map.
+ */
+ public void Clear ()
+ {
+ maXAccessibleToNode.clear();
+ }
+
+ /** @return
+ whether the new node was different from a previous one
+ repspectively was the first one set.
+ */
+ public boolean InsertNode (XAccessibleContext xContext, AccessibleTreeNode aNode)
+ {
+ AccessibleTreeNode aPreviousNode = (AccessibleTreeNode)maXAccessibleToNode.put (
+ xContext,
+ aNode);
+ return aPreviousNode != aNode;
+ }
+
+ protected void RemoveNode (AccessibleTreeNode aNode)
+ {
+ try
+ {
+ if ((aNode != null) && (aNode instanceof AccTreeNode))
+ {
+ maXAccessibleToNode.remove (((AccTreeNode)aNode).getContext());
+ }
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception while removing node "
+ + aNode + " : " + e);
+ e.printStackTrace();
+ }
+ }
+
+
+ public void ForEach (NodeMapCallback aFunctor)
+ {
+ Object[] aNodes = maXAccessibleToNode.values().toArray();
+ for (int i=0; i<aNodes.length; i++)
+ {
+ if (aNodes[i] != null && (aNodes[i] instanceof AccTreeNode))
+ {
+ try
+ {
+ aFunctor.Apply ((AccTreeNode)aNodes[i]);
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception applying functor to "
+ + i + "th node " + aNodes[i] + " : " + e);
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ AccessibleTreeNode GetNode (XAccessibleContext xContext)
+ {
+ return (AccessibleTreeNode)maXAccessibleToNode.get (xContext);
+ }
+
+ AccessibleTreeNode GetNode (Object aObject)
+ {
+ if (aObject instanceof XAccessibleContext)
+ return GetNode ((XAccessibleContext)aObject);
+ else
+ return null;
+ }
+
+ XAccessibleContext GetAccessible (AccessibleTreeNode aNode)
+ {
+ if ((aNode != null) && (aNode instanceof AccTreeNode))
+ return ((AccTreeNode)aNode).getContext();
+ else
+ return null;
+ }
+
+ boolean IsMember (XAccessibleContext xContext)
+ {
+ return maXAccessibleToNode.containsKey(xContext);
+ }
+
+ boolean ValueIsMember (AccessibleTreeNode aNode)
+ {
+ return maXAccessibleToNode.containsValue(aNode);
+ }
+
+
+
+ private HashMap maXAccessibleToNode;
+}
diff --git a/toolkit/test/accessibility/OfficeConnection.java b/toolkit/test/accessibility/OfficeConnection.java
new file mode 100755
index 000000000000..4cc5bee1ed78
--- /dev/null
+++ b/toolkit/test/accessibility/OfficeConnection.java
@@ -0,0 +1,102 @@
+// base classes
+import com.sun.star.uno.UnoRuntime;
+
+// factory for creating components
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.bridge.XUnoUrlResolver;
+import com.sun.star.frame.XComponentLoader;
+import com.sun.star.frame.XDesktop;
+import com.sun.star.frame.XModel;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.uno.XInterface;
+
+// Exceptions
+import com.sun.star.uno.RuntimeException;
+
+
+/** @descr This class establishes a connection to a StarOffice application.
+ */
+public class OfficeConnection
+{
+ public OfficeConnection (int nPortNumber)
+ {
+ mnDefaultPort = nPortNumber;
+ connect ();
+ }
+
+ /** @descr Return the service manager that represents the connected
+ StarOffice application
+ */
+ public XMultiServiceFactory getServiceManager ()
+ {
+ if ( ! mbInitialized)
+ connect ();
+ return maServiceManager;
+ }
+
+ /** @descr Return a flag that indicates if the constructor has been able to
+ establish a valid connection.
+ */
+ public boolean connectionIsValid ()
+ {
+ return getServiceManager() != null;
+ }
+
+ /** @descr Connect to a already running StarOffice application.
+ */
+ private void connect ()
+ {
+ connect (msDefaultHost, mnDefaultPort);
+ }
+
+ private void connect (String hostname)
+ {
+ connect (hostname, mnDefaultPort);
+ }
+
+ /** @descr Connect to a already running StarOffice application that has
+ been started with a command line argument like
+ "-accept=socket,host=localhost,port=5678;urp;"
+ */
+ private void connect (String hostname, int portnumber)
+ {
+ mbInitialized = true;
+ // Set up connection string.
+ String sConnectString = "uno:socket,host=" + hostname + ",port=" + portnumber
+ + ";urp;StarOffice.ServiceManager";
+
+
+ // connect to a running office and get the ServiceManager
+ try
+ {
+ // Create a URL Resolver.
+ XMultiServiceFactory aLocalServiceManager =
+ com.sun.star.comp.helper.Bootstrap.createSimpleServiceManager();
+ XUnoUrlResolver aURLResolver = (XUnoUrlResolver) UnoRuntime.queryInterface (
+ XUnoUrlResolver.class,
+ aLocalServiceManager.createInstance ("com.sun.star.bridge.UnoUrlResolver")
+ );
+
+ maServiceManager = (XMultiServiceFactory) UnoRuntime.queryInterface (
+ XMultiServiceFactory.class,
+ aURLResolver.resolve (sConnectString)
+ );
+ }
+
+ catch (Exception e)
+ {
+ MessageArea.println ("Could not connect with " + sConnectString + " : " + e);
+ MessageArea.println ("Please start OpenOffice/StarOffice with "
+ + "\"-accept=socket,host=localhost,port=5678;urp;\"");
+ }
+ }
+
+ private int mnDefaultPort = 5678;
+ private final String msDefaultHost = "localhost";
+ private XMultiServiceFactory maServiceManager = null;
+
+ /** A value of true just indicates that it has been tried to establish a connection,
+ not that that has been successfull.
+ */
+ private boolean mbInitialized = false;
+}
diff --git a/toolkit/test/accessibility/Options.java b/toolkit/test/accessibility/Options.java
new file mode 100644
index 000000000000..9b0f6f01889c
--- /dev/null
+++ b/toolkit/test/accessibility/Options.java
@@ -0,0 +1,88 @@
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Properties;
+
+/** Load from and save options into a file.
+*/
+class Options
+ extends Properties
+{
+ static public Options Instance ()
+ {
+ if (saOptions == null)
+ saOptions = new Options ();
+ return saOptions;
+ }
+
+ static public void SetString (String sName, String sValue)
+ {
+ Instance().setProperty (sName, sValue);
+ }
+
+ static public String GetString (String sName)
+ {
+ return Instance().getProperty (sName);
+ }
+
+ static public void SetBoolean (String sName, boolean bValue)
+ {
+ Instance().setProperty (sName, Boolean.toString(bValue));
+ }
+
+ static public boolean GetBoolean (String sName)
+ {
+ return Boolean.getBoolean(Instance().getProperty (sName));
+ }
+
+ static public void SetInteger (String sName, int nValue)
+ {
+ Instance().setProperty (sName, Integer.toString(nValue));
+ }
+
+ static public int GetInteger (String sName, int nDefault)
+ {
+ String sValue = Instance().getProperty (sName);
+ if (sValue == null)
+ return nDefault;
+ else
+ return Integer.parseInt (sValue);
+ }
+
+ public void Load (String sBaseName)
+ {
+ try
+ {
+ load (new FileInputStream (ProvideFile(sBaseName)));
+ }
+ catch (java.io.IOException e)
+ {
+ // Ignore a non-existing options file.
+ }
+ }
+
+ public void Save (String sBaseName)
+ {
+ try
+ {
+ store (new FileOutputStream (ProvideFile(sBaseName)), null);
+ }
+ catch (java.io.IOException e)
+ {
+ }
+ }
+
+ private Options ()
+ {
+ }
+
+ private File ProvideFile (String sBaseName)
+ {
+ return new File (
+ System.getProperty ("user.home"),
+ sBaseName);
+ }
+
+ static private Options saOptions = null;
+}
diff --git a/toolkit/test/accessibility/Print.java b/toolkit/test/accessibility/Print.java
new file mode 100755
index 000000000000..e4d21dc4e092
--- /dev/null
+++ b/toolkit/test/accessibility/Print.java
@@ -0,0 +1,5 @@
+interface Print
+{
+ void print (String text);
+ void println (String text);
+}
diff --git a/toolkit/test/accessibility/QueuedListener.java b/toolkit/test/accessibility/QueuedListener.java
new file mode 100644
index 000000000000..b92d7ac487e6
--- /dev/null
+++ b/toolkit/test/accessibility/QueuedListener.java
@@ -0,0 +1,55 @@
+import com.sun.star.accessibility.*;
+import com.sun.star.lang.EventObject;
+import com.sun.star.uno.*;
+import com.sun.star.accessibility.*;
+
+import java.util.LinkedList;
+
+class QueuedListener
+ implements XAccessibleEventListener
+{
+ public QueuedListener (EventListener aListener)
+ {
+ maListener = aListener;
+ }
+
+
+ public void disposing( final EventObject aEvent)
+ {
+ XAccessibleContext xContext = (XAccessibleContext)UnoRuntime.queryInterface(
+ XAccessibleContext.class, aEvent.Source);
+ if (xContext == null)
+ {
+ XAccessible xAccessible = (XAccessible)UnoRuntime.queryInterface(
+ XAccessible.class, aEvent.Source);
+ if (xAccessible != null)
+ xContext = xAccessible.getAccessibleContext();
+ }
+ final XAccessibleContext xSource = xContext;
+ EventQueue.Instance().addDisposingEvent (new Runnable()
+ {
+ public void run()
+ {
+ if (QueuedListener.this.maListener != null)
+ QueuedListener.this.maListener.disposing (xSource);
+ }
+ }
+ );
+ }
+
+ public void notifyEvent( final AccessibleEventObject aEvent )
+ {
+ EventQueue.Instance().addEvent (new Runnable()
+ {
+ public void run()
+ {
+ QueuedListener.this.maListener.notifyEvent( aEvent );
+ }
+ }
+ );
+ }
+
+ private EventListener maListener;
+}
+
+
diff --git a/toolkit/test/accessibility/QueuedTopWindowListener.java b/toolkit/test/accessibility/QueuedTopWindowListener.java
new file mode 100644
index 000000000000..61b3472d2002
--- /dev/null
+++ b/toolkit/test/accessibility/QueuedTopWindowListener.java
@@ -0,0 +1,88 @@
+import com.sun.star.awt.XTopWindowListener;
+import com.sun.star.lang.EventObject;
+
+class QueuedTopWindowListener
+ implements XTopWindowListener
+{
+ public QueuedTopWindowListener (TopWindowListener aListener)
+ {
+ maListener = aListener;
+ }
+
+ public void windowOpened (final com.sun.star.lang.EventObject aEvent) throws RuntimeException
+ {
+ EventQueue.Instance().addEvent (new Runnable()
+ {
+ public void run()
+ {
+ QueuedTopWindowListener.this.maListener.windowOpened (aEvent);
+ }
+ }
+ );
+ }
+
+
+
+
+ public void windowClosing (final com.sun.star.lang.EventObject aEvent) throws RuntimeException
+ {
+ // Ignored.
+ }
+
+
+
+
+ public void windowClosed (final com.sun.star.lang.EventObject aEvent) throws RuntimeException
+ {
+ EventQueue.Instance().addEvent (new Runnable()
+ {
+ public void run()
+ {
+ QueuedTopWindowListener.this.maListener.windowClosed (aEvent);
+ }
+ }
+ );
+ }
+
+
+
+
+ public void windowMinimized (final com.sun.star.lang.EventObject aEvent)
+ throws RuntimeException
+ {
+ System.out.println ("QueuedTopWindowListener: Top window minimized: " + aEvent);
+ }
+
+ public void windowNormalized (final com.sun.star.lang.EventObject aEvent)
+ throws RuntimeException
+ {
+ System.out.println ("QueuedTopWindowListener: Top window normalized: " + aEvent);
+ }
+
+ public void windowActivated (final com.sun.star.lang.EventObject aEvent)
+ throws RuntimeException
+ {
+ System.out.println ("QueuedTopWindowListener: Top window actived: " + aEvent);
+ }
+
+ public void windowDeactivated (final com.sun.star.lang.EventObject aEvent)
+ throws RuntimeException
+ {
+ System.out.println ("QueuedTopWindowListener: Top window deactived: " + aEvent);
+ }
+
+ public void disposing( final EventObject aEvent)
+ {
+ EventQueue.Instance().addDisposingEvent (new Runnable()
+ {
+ public void run()
+ {
+ if (QueuedTopWindowListener.this.maListener != null)
+ QueuedTopWindowListener.this.maListener.disposing (aEvent);
+ }
+ }
+ );
+ }
+
+ private TopWindowListener maListener;
+}
diff --git a/toolkit/test/accessibility/SelectionDialog.java b/toolkit/test/accessibility/SelectionDialog.java
new file mode 100644
index 000000000000..a632e9f77a0c
--- /dev/null
+++ b/toolkit/test/accessibility/SelectionDialog.java
@@ -0,0 +1,179 @@
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleSelection;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Vector;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+
+
+
+/**
+ * Display a dialog with a list-box of children and select/deselect buttons
+ */
+class SelectionDialog extends JDialog
+ implements ActionListener
+{
+ public SelectionDialog (AccTreeNode aNode)
+ {
+ super (AccessibilityWorkBench.Instance());
+
+ maNode = aNode;
+
+ Layout();
+ }
+
+ /** build dialog */
+ protected void Layout ()
+ {
+ setTitle( "Select" );
+
+ // vertical stacking of the elements
+ Container aContent = getContentPane();
+
+ // label with explanation
+ aContent.add( new JLabel( "Select/Deselect child elements" ),
+ BorderLayout.NORTH );
+
+ // the JListBox
+ maChildrenSelector = new JList (GetChildrenList());
+ maChildrenSelector.setPreferredSize (new Dimension (500,300));
+ aContent.add (maChildrenSelector, BorderLayout.CENTER);
+ maChildrenSelector.setSelectionMode (ListSelectionModel.SINGLE_SELECTION);
+
+ JPanel aButtons = new JPanel();
+ aButtons.setLayout( new FlowLayout() );
+
+ JButton aButton;
+
+ aButton = new JButton( "Select" );
+ aButton.setActionCommand( "Select" );
+ aButton.addActionListener( this );
+ aButtons.add( aButton );
+
+ aButton = new JButton( "Deselect" );
+ aButton.setActionCommand( "Deselect" );
+ aButton.addActionListener( this );
+ aButtons.add( aButton );
+
+ aButton = new JButton( "Select all" );
+ aButton.setActionCommand( "Select all" );
+ aButton.addActionListener( this );
+ aButtons.add( aButton );
+
+ aButton = new JButton( "Clear Selection" );
+ aButton.setActionCommand( "Clear Selection" );
+ aButton.addActionListener( this );
+ aButtons.add( aButton );
+
+ aButton = new JButton( "Close" );
+ aButton.setActionCommand( "Close" );
+ aButton.addActionListener( this );
+ aButtons.add( aButton );
+
+ // add Panel with buttons
+ aContent.add( aButtons, BorderLayout.SOUTH );
+
+ setSize( getPreferredSize() );
+ }
+
+ /** Get a list of all children
+ */
+ private Vector GetChildrenList ()
+ {
+ mxSelection = maNode.getSelection();
+
+ XAccessibleContext xContext = maNode.getContext();
+ int nCount = xContext.getAccessibleChildCount();
+ Vector aChildVector = new Vector();
+ for(int i = 0; i < nCount; i++)
+ {
+ try
+ {
+ XAccessible xChild = xContext.getAccessibleChild(i);
+ XAccessibleContext xChildContext = xChild.getAccessibleContext();
+ aChildVector.add( i + " " + xChildContext.getAccessibleName());
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ aChildVector.add( "ERROR: IndexOutOfBoundsException" );
+ }
+ }
+ return aChildVector;
+ }
+
+
+ void close ()
+ {
+ hide();
+ dispose();
+ }
+
+ void select()
+ {
+ try
+ {
+ mxSelection.selectAccessibleChild (maChildrenSelector.getSelectedIndex());
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ JOptionPane.showMessageDialog( AccessibilityWorkBench.Instance(),
+ "Can't select: IndexOutofBounds",
+ "Error in selectAccessibleChild",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ void deselect()
+ {
+ try
+ {
+ mxSelection.deselectAccessibleChild(
+ maChildrenSelector.getSelectedIndex());
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ JOptionPane.showMessageDialog( AccessibilityWorkBench.Instance(),
+ "Can't deselect: IndexOutofBounds",
+ "Error in deselectAccessibleChild",
+ JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ void selectAll()
+ {
+ mxSelection.selectAllAccessibleChildren();
+ }
+
+ void clearSelection()
+ {
+ mxSelection.clearAccessibleSelection();
+ }
+
+
+
+ public void actionPerformed(ActionEvent e)
+ {
+ String sCommand = e.getActionCommand();
+
+ if( "Close".equals( sCommand ) )
+ close();
+ else if ( "Select".equals( sCommand ) )
+ select();
+ else if ( "Deselect".equals( sCommand ) )
+ deselect();
+ else if ( "Clear Selection".equals( sCommand ) )
+ clearSelection();
+ else if ( "Select all".equals( sCommand ) )
+ selectAll();
+ }
+
+ private JList maChildrenSelector;
+ private XAccessibleSelection mxSelection;
+ private AccTreeNode maNode;
+}
diff --git a/toolkit/test/accessibility/SimpleOffice.java b/toolkit/test/accessibility/SimpleOffice.java
new file mode 100755
index 000000000000..4417267675af
--- /dev/null
+++ b/toolkit/test/accessibility/SimpleOffice.java
@@ -0,0 +1,389 @@
+import java.lang.Thread;
+
+import com.sun.star.awt.Rectangle;
+import com.sun.star.awt.XWindow;
+
+import com.sun.star.beans.PropertyValue;
+import com.sun.star.beans.XPropertySet;
+
+import com.sun.star.container.XIndexAccess;
+import com.sun.star.container.XChild;
+import com.sun.star.container.XEnumerationAccess;
+import com.sun.star.container.XEnumeration;
+
+import com.sun.star.frame.XComponentLoader;
+import com.sun.star.frame.XController;
+import com.sun.star.frame.XDesktop;
+import com.sun.star.frame.XFrame;
+import com.sun.star.frame.XModel;
+import com.sun.star.frame.XTasksSupplier;
+import com.sun.star.frame.XTask;
+
+import com.sun.star.lang.XComponent;
+import com.sun.star.lang.XMultiServiceFactory;
+import com.sun.star.lang.XServiceInfo;
+import com.sun.star.lang.XServiceName;
+import com.sun.star.lang.XTypeProvider;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.Type;
+
+import com.sun.star.drawing.XDrawView;
+import com.sun.star.drawing.XDrawPage;
+import com.sun.star.drawing.XShapes;
+import com.sun.star.drawing.XShape;
+import com.sun.star.drawing.XShapeDescriptor;
+
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleComponent;
+import com.sun.star.accessibility.XAccessibleRelationSet;
+import com.sun.star.accessibility.XAccessibleStateSet;
+
+import com.sun.star.awt.XExtendedToolkit;
+
+
+/** This class tries to simplify some tasks like loading a document or
+ getting various objects.
+*/
+public class SimpleOffice
+{
+ XDesktop mxDesktop = null;
+ OfficeConnection aConnection;
+ int mnPortNumber;
+
+ public SimpleOffice (int nPortNumber)
+ {
+ mnPortNumber = nPortNumber;
+ connect ();
+ getDesktop ();
+ }
+
+ public void connect ()
+ {
+ aConnection = new OfficeConnection (mnPortNumber);
+ mxDesktop = null;
+ getDesktop ();
+ }
+
+ public XModel loadDocument (String URL)
+ {
+ XModel xModel = null;
+ try
+ {
+ // Load the document from the specified URL.
+ XComponentLoader xLoader =
+ (XComponentLoader)UnoRuntime.queryInterface(
+ XComponentLoader.class, mxDesktop);
+
+ XComponent xComponent = xLoader.loadComponentFromURL (
+ URL,
+ "_blank",
+ 0,
+ new PropertyValue[0]
+ );
+
+ xModel = (XModel) UnoRuntime.queryInterface(
+ XModel.class, xComponent);
+ }
+ catch (java.lang.NullPointerException e)
+ {
+ MessageArea.println ("caught exception while loading "
+ + URL + " : " + e);
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while loading "
+ + URL + " : " + e);
+ }
+ return xModel;
+ }
+
+
+
+
+ public XModel getModel (String name)
+ {
+ XModel xModel = null;
+ try
+ {
+ XTasksSupplier xTasksSupplier =
+ (XTasksSupplier) UnoRuntime.queryInterface(
+ XTasksSupplier.class, mxDesktop);
+ XEnumerationAccess xEA = xTasksSupplier.getTasks();
+ XEnumeration xE = xEA.createEnumeration();
+ while (xE.hasMoreElements())
+ {
+ XTask xTask = (XTask) UnoRuntime.queryInterface(
+ XTask.class, xE.nextElement());
+ MessageArea.print (xTask.getName());
+ }
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while getting Model " + name
+ + ": " + e);
+ }
+ return xModel;
+ }
+
+
+ public XModel getModel (XDrawView xView)
+ {
+ XController xController = (XController) UnoRuntime.queryInterface(
+ XController.class, xView);
+ if (xController != null)
+ return xController.getModel();
+ else
+ {
+ MessageArea.println ("can't cast view to controller");
+ return null;
+ }
+ }
+
+ public XDesktop getDesktop ()
+ {
+ if (mxDesktop != null)
+ return mxDesktop;
+ try
+ {
+ // Get the factory of the connected office.
+ XMultiServiceFactory xMSF = aConnection.getServiceManager ();
+ if (xMSF == null)
+ {
+ MessageArea.println ("can't connect to office");
+ return null;
+ }
+ else
+ MessageArea.println ("Connected successfully.");
+
+ // Create a new desktop.
+ mxDesktop = (XDesktop) UnoRuntime.queryInterface(
+ XDesktop.class,
+ xMSF.createInstance ("com.sun.star.frame.Desktop")
+ );
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while creating desktop: "
+ + e);
+ }
+
+ return mxDesktop;
+ }
+
+
+ /** Return a reference to the extended toolkit which is a broadcaster of
+ top window, key, and focus events.
+ */
+ public XExtendedToolkit getExtendedToolkit ()
+ {
+ XExtendedToolkit xToolkit = null;
+ try
+ {
+ // Get the factory of the connected office.
+ XMultiServiceFactory xMSF = aConnection.getServiceManager ();
+ if (xMSF != null)
+ {
+ xToolkit = (XExtendedToolkit) UnoRuntime.queryInterface(
+ XExtendedToolkit.class,
+ xMSF.createInstance ("stardiv.Toolkit.VCLXToolkit")
+ );
+ }
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while creating extended toolkit: " + e);
+ }
+
+ return xToolkit;
+ }
+
+
+
+ public XAccessible getAccessibleObject (XInterface xObject)
+ {
+ XAccessible xAccessible = null;
+ try
+ {
+ xAccessible = (XAccessible) UnoRuntime.queryInterface(
+ XAccessible.class, xObject);
+ }
+ catch (Exception e)
+ {
+ MessageArea.println (
+ "caught exception while getting accessible object" + e);
+ e.printStackTrace();
+ }
+ return xAccessible;
+ }
+
+ /** Return the root object of the accessibility hierarchy.
+ */
+ public XAccessible getAccessibleRoot (XAccessible xAccessible)
+ {
+ try
+ {
+ XAccessible xParent = null;
+ do
+ {
+ XAccessibleContext xContext = xAccessible.getAccessibleContext();
+ if (xContext != null)
+ xParent = xContext.getAccessibleParent();
+ if (xParent != null)
+ xAccessible = xParent;
+ }
+ while (xParent != null);
+ }
+ catch (Exception e)
+ {
+ MessageArea.println (
+ "caught exception while getting accessible root" + e);
+ e.printStackTrace();
+ }
+ return xAccessible;
+ }
+
+
+
+
+ /** @descr Return the current window associated with the given
+ model.
+ */
+ public XWindow getCurrentWindow ()
+ {
+ return getCurrentWindow ((XModel) UnoRuntime.queryInterface(
+ XModel.class, getDesktop()));
+ }
+
+
+
+
+
+ public XWindow getCurrentWindow (XModel xModel)
+ {
+ XWindow xWindow = null;
+ try
+ {
+ if (xModel == null)
+ MessageArea.println ("invalid model (==null)");
+ XController xController = xModel.getCurrentController();
+ if (xController == null)
+ MessageArea.println ("can't get controller from model");
+ XFrame xFrame = xController.getFrame();
+ if (xFrame == null)
+ MessageArea.println ("can't get frame from controller");
+ xWindow = xFrame.getComponentWindow ();
+ if (xWindow == null)
+ MessageArea.println ("can't get window from frame");
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while getting current window" + e);
+ }
+
+ return xWindow;
+ }
+
+
+ /** @descr Return the current draw page of the given desktop.
+ */
+ public XDrawPage getCurrentDrawPage ()
+ {
+ return getCurrentDrawPage ((XDrawView) UnoRuntime.queryInterface(
+ XDrawView.class, getCurrentView()));
+ }
+
+
+
+
+ public XDrawPage getCurrentDrawPage (XDrawView xView)
+ {
+ XDrawPage xPage = null;
+ try
+ {
+ if (xView == null)
+ MessageArea.println ("can't get current draw page from null view");
+ else
+ xPage = xView.getCurrentPage();
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while getting current draw page : " + e);
+ }
+
+ return xPage;
+ }
+
+
+
+
+ /** @descr Return the current view of the given desktop.
+ */
+ public XDrawView getCurrentView ()
+ {
+ return getCurrentView (getDesktop());
+ }
+
+ public XDrawView getCurrentView (XDesktop xDesktop)
+ {
+ if (xDesktop == null)
+ MessageArea.println ("can't get desktop to retrieve current view");
+
+ XDrawView xView = null;
+ try
+ {
+ XComponent xComponent = xDesktop.getCurrentComponent();
+ if (xComponent == null)
+ MessageArea.println ("can't get component to retrieve current view");
+
+ XFrame xFrame = xDesktop.getCurrentFrame();
+ if (xFrame == null)
+ MessageArea.println ("can't get frame to retrieve current view");
+
+ XController xController = xFrame.getController();
+ if (xController == null)
+ MessageArea.println ("can't get controller to retrieve current view");
+
+ xView = (XDrawView) UnoRuntime.queryInterface(
+ XDrawView.class, xController);
+ if (xView == null)
+ MessageArea.println ("could not cast controller into view");
+ }
+ catch (Exception e)
+ {
+ MessageArea.println ("caught exception while getting current view : " + e);
+ }
+
+ return xView;
+ }
+
+
+
+
+ // Return the accessible object of the document window.
+ public static XAccessible getAccessibleDocumentWindow (XDrawPage xPage)
+ {
+ XIndexAccess xShapeList = (XIndexAccess) UnoRuntime.queryInterface(
+ XIndexAccess.class, xPage);
+ if (xShapeList.getCount() > 0)
+ {
+ // All shapes return as accessible object the document window's
+ // accessible object. This is, of course, a hack and will be
+ // removed as soon as the missing infrastructure for obtaining
+ // the object directly is implemented.
+ XShape xShape = null;
+ try{
+ xShape = (XShape) UnoRuntime.queryInterface(
+ XShape.class, xShapeList.getByIndex (0));
+ } catch (Exception e)
+ {}
+ XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface (
+ XAccessible.class, xShape);
+ return xAccessible;
+ }
+ else
+ return null;
+ }
+}
diff --git a/toolkit/test/accessibility/StringNode.java b/toolkit/test/accessibility/StringNode.java
new file mode 100644
index 000000000000..11a7286c60f1
--- /dev/null
+++ b/toolkit/test/accessibility/StringNode.java
@@ -0,0 +1,13 @@
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+/**
+ Base class for all tree nodes.
+ */
+class StringNode
+ extends AccessibleTreeNode
+{
+ public StringNode (String aDisplayObject, AccessibleTreeNode aParent)
+ {
+ super (aDisplayObject, aParent);
+ }
+}
diff --git a/toolkit/test/accessibility/TableEventHandler.java b/toolkit/test/accessibility/TableEventHandler.java
new file mode 100644
index 000000000000..7655d3a13599
--- /dev/null
+++ b/toolkit/test/accessibility/TableEventHandler.java
@@ -0,0 +1,43 @@
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleTableModelChange;
+import com.sun.star.uno.UnoRuntime;
+
+import java.io.PrintStream;
+
+class TableEventHandler
+ extends EventHandler
+{
+ public TableEventHandler (AccessibleEventObject aEvent, AccessibilityTreeModel aTreeModel)
+ {
+ super (aEvent, aTreeModel);
+ }
+
+ public void PrintOldAndNew (PrintStream out)
+ {
+ switch (mnEventId)
+ {
+ case AccessibleEventId.TABLE_MODEL_CHANGED:
+ AccessibleTableModelChange aModelChange =
+ (AccessibleTableModelChange)maEvent.NewValue;
+ out.println( "Range: StartRow " + aModelChange.FirstRow +
+ " StartColumn " + aModelChange.FirstColumn +
+ " EndRow " + aModelChange.LastRow +
+ " EndColumn " + aModelChange.LastColumn +
+ " Id " + aModelChange.Type);
+ break;
+ default:
+ super.PrintOldAndNew (out);
+ }
+ }
+
+ public void Process ()
+ {
+ maTreeModel.updateNode (mxEventSource, AccessibleTableHandler.class);
+ }
+
+
+ private XAccessible mxOldChild;
+ private XAccessible mxNewChild;
+}
diff --git a/toolkit/test/accessibility/TextLogger.java b/toolkit/test/accessibility/TextLogger.java
new file mode 100644
index 000000000000..e0ee56fd691d
--- /dev/null
+++ b/toolkit/test/accessibility/TextLogger.java
@@ -0,0 +1,52 @@
+import javax.swing.JEditorPane;
+import javax.swing.event.HyperlinkListener;
+import javax.swing.event.HyperlinkEvent;
+import javax.swing.text.Document;
+import java.net.URL;
+
+class TextLogger
+ extends JEditorPane
+{
+ public TextLogger ()
+ throws java.io.IOException
+ {
+// maDocument = getEditorKit().createDefaultDocument();
+ super ("http://localhost");
+ try
+ {
+ // setPage (new URL ("http://www.spiegel.de"));
+ }
+ catch (Exception e)
+ {}
+
+ setEditable (false);
+ final JEditorPane finalPane = this;
+ addHyperlinkListener (new HyperlinkListener()
+ {
+ public void hyperlinkUpdate (HyperlinkEvent e)
+ {
+ try
+ {
+ if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED)
+ finalPane.setPage (e.getURL());
+ }
+ catch (java.io.IOException ex)
+ {
+ ex.printStackTrace(System.err);
+ }
+ }
+ });
+ }
+
+ public void appendText (String sText)
+ {
+ try
+ {
+ maDocument.insertString (maDocument.getLength(), sText, null);
+ }
+ catch (javax.swing.text.BadLocationException e)
+ {}
+ }
+
+ private Document maDocument;
+}
diff --git a/toolkit/test/accessibility/TextUpdateListener.java b/toolkit/test/accessibility/TextUpdateListener.java
new file mode 100644
index 000000000000..0ce990144c67
--- /dev/null
+++ b/toolkit/test/accessibility/TextUpdateListener.java
@@ -0,0 +1,170 @@
+import com.sun.star.accessibility.*;
+import com.sun.star.uno.UnoRuntime;
+
+import javax.swing.tree.*;
+import javax.swing.event.*;
+
+
+
+/** listen to tree model changes in order to update XAccessibleText objects
+*/
+class TextUpdateListener implements TreeModelListener
+{
+ public void treeNodesChanged(TreeModelEvent e)
+ {
+ try {
+ // if the change is to the first child of a DefaultMutableTreeNode
+ // with an XAccessibleText child, then we call updateText
+ int[] aIndices = e.getChildIndices();
+ if( (aIndices != null) &&
+ (aIndices.length > 0) )
+ {
+ // we have a parent... lets check for XAccessibleText then
+ DefaultMutableTreeNode aParent = (DefaultMutableTreeNode)
+ (e.getTreePath().getLastPathComponent());
+ DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)
+ (aParent.getChildAt(aIndices[0]));
+ if( aParent.getUserObject() instanceof XAccessibleText)
+ {
+ // aha! we have an xText. So we can now check for
+ // the various cases we support
+ XAccessibleText xText =
+ (XAccessibleText)aParent.getUserObject();
+
+ if( aIndices[0] == 0 )
+ {
+ // first child! Then we call updateText
+ updateText( xText, aNode.toString() );
+ }
+ else
+ {
+ // JDK 1.4:
+ // // check for pattern "Selection:"
+ // Matcher m = Pattern.compile(
+ // "selection: \\[(-?[0-9]+),(-?[0-9]+)\\] \".*" ).
+ // matcher( aNode.toString() );
+ // if( m.matches() )
+ // {
+ // try
+ // {
+ // // aha! Selection:
+ // setSelection( xText,
+ // Integer.parseInt(m.group(1)),
+ // Integer.parseInt(m.group(2)) );
+ // }
+ // catch( NumberFormatException f )
+ // {
+ // // ignore
+ // }
+ // }
+ }
+ }
+ }
+ }
+ catch (com.sun.star.lang.IndexOutOfBoundsException aException)
+ {}
+ }
+
+ // don't care:
+ public void treeNodesInserted(TreeModelEvent e) { ; }
+ public void treeNodesRemoved(TreeModelEvent e) { ; }
+ public void treeStructureChanged(TreeModelEvent e) { ; }
+
+ /** update the text */
+ boolean updateText( XAccessibleText xText, String sNew )
+ throws com.sun.star.lang.IndexOutOfBoundsException
+ {
+ // is this text editable? if not, fudge you and return
+ XAccessibleEditableText xEdit =
+ (XAccessibleEditableText) UnoRuntime.queryInterface (
+ XAccessibleEditableText.class, xText);
+ if (xEdit == null)
+ return false;
+
+ String sOld = xText.getText();
+
+ // false alarm? Early out if no change was done!
+ if( sOld.equals( sNew ) )
+ return false;
+
+ // get the minimum length of both strings
+ int nMinLength = sOld.length();
+ if( sNew.length() < nMinLength )
+ nMinLength = sNew.length();
+
+ // count equal characters from front and end
+ int nFront = 0;
+ while( (nFront < nMinLength) &&
+ (sNew.charAt(nFront) == sOld.charAt(nFront)) )
+ nFront++;
+ int nBack = 0;
+ while( (nBack < nMinLength) &&
+ ( sNew.charAt(sNew.length()-nBack-1) ==
+ sOld.charAt(sOld.length()-nBack-1) ) )
+ nBack++;
+ if( nFront + nBack > nMinLength )
+ nBack = nMinLength - nFront;
+
+ // so... the first nFront and the last nBack characters
+ // are the same. Change the others!
+ String sDel = sOld.substring( nFront, sOld.length() - nBack );
+ String sIns = sNew.substring( nFront, sNew.length() - nBack );
+
+ System.out.println("edit text: " +
+ sOld.substring(0, nFront) +
+ " [ " + sDel + " -> " + sIns + " ] " +
+ sOld.substring(sOld.length() - nBack) );
+
+ boolean bRet = false;
+ try
+ {
+ // edit the text, and use
+ // (set|insert|delete|replace)Text as needed
+ if( nFront+nBack == 0 )
+ bRet = xEdit.setText( sIns );
+ else if( sDel.length() == 0 )
+ bRet = xEdit.insertText( sIns, nFront );
+ else if( sIns.length() == 0 )
+ bRet = xEdit.deleteText( nFront, sOld.length()-nBack );
+ else
+ bRet = xEdit.replaceText(nFront, sOld.length()-nBack,sIns);
+ }
+ catch( IndexOutOfBoundsException e )
+ {
+ bRet = false;
+ }
+
+ return bRet;
+ }
+
+ boolean setSelection( XAccessibleText xText, int p1, int p2 )
+ {
+ try
+ {
+ return xText.setSelection( p1, p2 );
+ }
+ catch( com.sun.star.lang.IndexOutOfBoundsException f )
+ {
+ return false;
+ }
+ }
+
+ // /** replace the given node with a new xText node */
+ // void updateNode( XAccessibleText xText,
+ // DefaultMutableTreeNode aNode )
+ // {
+ // // create a new node
+ // DefaultMutableTreeNode aNew = newTextTreeNode( xText );
+ //
+ // // get parent (must be DefaultMutableTreeNode)
+ // DefaultMutableTreeNode aParent =
+ // (DefaultMutableTreeNode)aNode.getParent();
+ // if( aParent != null )
+ // {
+ // // remove old sub-tree, and insert new one
+ // int nIndex = aParent.getIndex( aNode );
+ // aParent.remove( nIndex );
+ // aParent.insert( aNew, nIndex );
+ // }
+ // }
+}
diff --git a/toolkit/test/accessibility/TopWindowListener.java b/toolkit/test/accessibility/TopWindowListener.java
new file mode 100644
index 000000000000..c0aea933ece7
--- /dev/null
+++ b/toolkit/test/accessibility/TopWindowListener.java
@@ -0,0 +1,205 @@
+import com.sun.star.awt.XWindow;
+import com.sun.star.awt.XExtendedToolkit;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.uno.XInterface;
+import com.sun.star.uno.UnoRuntime;
+import javax.swing.event.TreeModelEvent;
+
+/** Listen for top window events and create or delete children of the tree
+ model accordingly.
+*/
+class TopWindowListener
+{
+ TopWindowListener (AccessibilityTreeModel aModel, SimpleOffice aOffice)
+ {
+ maModel = aModel;
+ maOffice = aOffice;
+ }
+
+
+
+
+ /** Use this function to initially fill the accessibility object tree
+ view with nodes for top level windows.
+ */
+ public void Initialize ()
+ {
+ XExtendedToolkit xToolkit = maOffice.getExtendedToolkit();
+ if (xToolkit != null)
+ {
+ maModel.lock ();
+ int nTopWindowCount = xToolkit.getTopWindowCount();
+ MessageArea.println ("There are " + nTopWindowCount + " top windows.");
+ for (int i=0; i<nTopWindowCount; i++)
+ {
+ try
+ {
+ XAccessible xAccessible = maOffice.getAccessibleObject(
+ xToolkit.getTopWindow (i));
+ // Uncomment the following line to get the real root of
+ // the accessible tree that xAccessible belongs to.
+ // xAccessible = maOffice.getAccessibleRoot(xAccessible);
+ AddTopLevelNode (xAccessible);
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception: " + e);
+ e.printStackTrace();
+ }
+ }
+ maModel.unlock ((AccessibleTreeNode)maModel.getRoot());
+ }
+ }
+
+
+
+ /** Add a new top level node which, to be exact, will be placed on the
+ second layer of the tree.
+ @param xNewTopLevelObject
+ The accessible object of the new top level window.
+ */
+ private void AddTopLevelNode (XAccessible xNewTopLevelObject)
+ {
+ System.out.println ("adding top level window");
+ if (xNewTopLevelObject != null)
+ {
+ XAccessibleContext xContext = xNewTopLevelObject.getAccessibleContext();
+ if (xContext == null)
+ System.out.println ("top level window not accessible");
+ else
+ {
+ if ( ! FilterTopLevelNode (xContext))
+ {
+ Object aRootObject = maModel.getRoot();
+ if (aRootObject instanceof VectorNode)
+ {
+ VectorNode aRoot = (VectorNode) aRootObject;
+ AccessibleTreeNode aNode =
+ NodeFactory.Instance().createDefaultNode (xNewTopLevelObject, aRoot);
+ aRoot.addChild (aNode);
+ maModel.fireTreeNodesInserted (maModel.createEvent (aRoot, aNode));
+ }
+ }
+ }
+ }
+ }
+
+ /** Ignore windows that have no accessible name, i.e. do not represent
+ document windows.
+ @return
+ Returns <true/> when the given object should not be displayed,
+ i.e. filtered out.
+ */
+ private boolean FilterTopLevelNode (XAccessibleContext xContext)
+ {
+ // No filtering at the moment.
+ return false;
+ // return xContext.getAccessibleName().length() == 0;
+ }
+
+
+
+
+ /** Remove an existing top level node from the tree.
+ @param xNewTopLevelObject
+ The accessible object to remove.
+ */
+ private void RemoveTopLevelNode (XAccessible xTopLevelObject)
+ {
+ Object aObject = maModel.getRoot();
+ if (aObject instanceof VectorNode && xTopLevelObject != null)
+ {
+ System.out.println ("removing node " + xTopLevelObject);
+ VectorNode aRoot = (VectorNode) aObject;
+ maModel.removeNode (xTopLevelObject.getAccessibleContext());
+ }
+ }
+
+
+
+
+
+ /** This method exists for debugging. It prints a list of all top
+ level windows.
+ */
+ private void ShowAllTopLevelWindows ()
+ {
+ XExtendedToolkit xToolkit = maOffice.getExtendedToolkit();
+ if (xToolkit != null)
+ {
+ int nTopWindowCount = xToolkit.getTopWindowCount();
+ for (int i=0; i<nTopWindowCount; i++)
+ {
+ try
+ {
+ System.out.println (i + " : " + xToolkit.getTopWindow (i));
+ }
+ catch (Exception e)
+ {
+ System.out.println ("caught exception; " + e);
+ }
+ }
+ }
+ }
+
+
+
+
+ // XTopWindowListener
+ public void windowOpened (final com.sun.star.lang.EventObject aEvent)
+ throws RuntimeException
+ {
+ if (maModel != null)
+ {
+ XWindow xWindow = (XWindow) UnoRuntime.queryInterface(
+ XWindow.class, aEvent.Source);
+ if (xWindow == null)
+ System.out.println ("event source is no XWindow");
+ else
+ {
+ XAccessible xAccessible = maOffice.getAccessibleObject(xWindow);
+ if (xAccessible == null)
+ System.out.println ("event source is no XAccessible");
+ else
+ AddTopLevelNode (xAccessible);
+ }
+ }
+ }
+
+
+
+
+ public void windowClosed (final com.sun.star.lang.EventObject aEvent)
+ throws RuntimeException
+ {
+ if (maModel != null)
+ {
+ XWindow xWindow = (XWindow) UnoRuntime.queryInterface(
+ XWindow.class, aEvent.Source);
+ if (xWindow == null)
+ System.out.println ("event source is no XWindow");
+ else
+ {
+ XAccessible xAccessible = maOffice.getAccessibleObject(xWindow);
+ if (xAccessible == null)
+ System.out.println ("event source is no XAccessible");
+ else
+ RemoveTopLevelNode (xAccessible);
+ }
+ }
+ }
+
+ public void disposing (final com.sun.star.lang.EventObject aEvent)
+ {
+ System.out.println ("Top window disposed: " + aEvent);
+ }
+
+
+
+
+ private AccessibilityTreeModel
+ maModel;
+ private SimpleOffice
+ maOffice;
+}
diff --git a/toolkit/test/accessibility/VectorNode.java b/toolkit/test/accessibility/VectorNode.java
new file mode 100644
index 000000000000..282abb595620
--- /dev/null
+++ b/toolkit/test/accessibility/VectorNode.java
@@ -0,0 +1,50 @@
+import com.sun.star.lang.IndexOutOfBoundsException;
+import java.util.Vector;
+
+/** The VectorNode class is a simple container whose list of children is
+ managed entirely by its owner.
+*/
+class VectorNode
+ extends StringNode
+{
+ private Vector maChildren;
+
+ public VectorNode (String sDisplayObject, AccessibleTreeNode aParent)
+ {
+ super (sDisplayObject, aParent);
+
+ maChildren = new Vector ();
+ }
+
+ public void addChild (AccessibleTreeNode aChild)
+ {
+ maChildren.add (aChild);
+ }
+
+ public int getChildCount ()
+ {
+ return maChildren.size();
+ }
+
+ public AccessibleTreeNode getChild (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ return (AccessibleTreeNode)maChildren.elementAt (nIndex);
+ }
+
+ public boolean removeChild (int nIndex)
+ throws IndexOutOfBoundsException
+ {
+ return maChildren.remove (nIndex) != null;
+ }
+
+ public int indexOf (AccessibleTreeNode aNode)
+ {
+ return maChildren.indexOf (aNode);
+ }
+
+ public boolean isLeaf()
+ {
+ return maChildren.isEmpty();
+ }
+}
diff --git a/toolkit/test/accessibility/about.html b/toolkit/test/accessibility/about.html
new file mode 100644
index 000000000000..ff24ed058663
--- /dev/null
+++ b/toolkit/test/accessibility/about.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<center><h1>About AWB</h1>
+<p>AWB, the <em>A</em>ccessibility <em>W</em>ork <em>B</em>ench.</p>
+<p>Version 1.7</p>
+</center>
+</body>
+</html> \ No newline at end of file
diff --git a/toolkit/test/accessibility/help.html b/toolkit/test/accessibility/help.html
new file mode 100644
index 000000000000..2660013b6733
--- /dev/null
+++ b/toolkit/test/accessibility/help.html
@@ -0,0 +1,91 @@
+<html><body bgcolor="#fffaf0">
+<h1>Help for the AWB v1.7</h1>
+
+<p>The AWB, or <em>A</em>ccessibility <em>W</em>ork <em>B</em>ench, is a tool
+for testing the implementation UNO Accessibility API.</p>
+
+<p>The main window is roughly divided into three areas:
+<ul>
+<li>The <a href="#treeview">tree view</a> on the left shows a part of the
+accessibility tree of one or more StarOffice/OpenOffice applications.</li>
+<li>The <a href="#graphicalview">graphical view</a> on the right side shows
+a graphical representation of the accessibility objects in the tree. To
+make objects missing in the graphical view visible expand the corresponding
+nodes in the tree view.</li>
+
+<li>The text window at the bottom logs important messages.</li>
+</ul>
+</p>
+
+<h2><a name="treeview">Tree View</a></h2>
+<p>The tree view has a top-level node for every open
+ document window of StarOffice/OpenOffice. Expand those nodes to make them
+ visible in the <a href="#graphicalview">graphical view</a>.</p>
+
+<h3>Nodes</h3>
+<p>The nodes in the tree view belong to different classes, some of which
+ have children others do not:
+<ul>
+<li><b>Accessible Object</b><br>
+ The node represents an accessible object and has corresponding shape in
+ the graphical view. Only this kind of node gets highlighted by clicking
+ on those shapes.</li>
+<li><b>Simple Property</b><br>
+ These leaves represent simple properties of their parent nodes. Examples
+ are the position, size, and color of an accessible object.</li>
+<li><b>Complex Properties</b><br>
+ These nodes have children that are not accessible objects. Examples are
+ the lists of interfaces or services supported by an accessible object.</li>
+</ul>
+</p>
+
+<h3>Actions</h3>
+<p>The tree view supports the following actions:
+<ul><li>Left double click expands the node under the mouse pointer.</li>
+<li>Right click shows a context menu. Entries, when supported, are:
+<ul>
+<li><b>Expand Shapes</b><br>
+Expands all nodes in the sub-tree that lie on a path from the root to a shape.</li>
+<li><b>Expand Subtree</b><br>
+Expands all nodes in the sub-tree.</li>
+<li><b>Select...</b><br>
+Show a dialog that gives access to the XAccessibleSelection interface.</li>
+<li><b>select...</b>, <b>copy...</b>, <b>cut...</b>, <b>paste...</b>,
+ <b>edit...</b>, <b>format...</b><br>
+Show dialogs that give access to the XAccessibleText and
+XAccessibleEditableText interfaces.
+</ul></li>
+</ul>
+</p>
+
+
+
+<h2><a name="graphicalview">Graphical View</a></h2>
+<p>The graphical view shows several properties of accessibility objects:
+<ul>
+<li>The bounding box is represented as a rectangle.</li>
+<li>The background color of the accessible object is taken to draw the
+ bounding box rectangle.</li>
+<li>The foreground color is used to fill the bounding box.</li>
+<li>The accessible name is shown when the menu checkbox Options->Show Name
+ is check.</li>
+<li>The accessible description is shown when the menu checkbox Options->Show
+ Descriptons is checked.</li>
+<li>If the XAccessibleText interface is supported and the menu checkbox
+ Options->Show Text is checked then the text of the accessible object is
+ shown.</li>
+</ul>
+</p>
+
+<h3>Actions</h3>
+<p>The graphical view supports three the following actions:
+<ul>
+<li>Left click (no modifiers) highlights the object under the mouse as well
+ as the corresponding node in the tree view.</li>
+<li>Left click with Control modifier expands the object under the
+ mouse.</li>
+<li>Mouse motion with Shift modifier highlights the object under the mouse
+ as well as the corresponding node in the tree view.</li>
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/toolkit/test/accessibility/jawb.mf b/toolkit/test/accessibility/jawb.mf
new file mode 100644
index 000000000000..939cbdad22ab
--- /dev/null
+++ b/toolkit/test/accessibility/jawb.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: AccessibilityWorkBench
+Class-Path: classes.jar ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar xt.jar xml-apis.jar
diff --git a/toolkit/test/accessibility/makefile.mk b/toolkit/test/accessibility/makefile.mk
new file mode 100644
index 000000000000..cc6f410f7404
--- /dev/null
+++ b/toolkit/test/accessibility/makefile.mk
@@ -0,0 +1,127 @@
+# This is the dmake version.
+
+# copied from settings.mk
+SOLARBINDIR=$(SOLARVERSION)$/$(INPATH)$/bin$(UPDMINOREXT)
+
+# Please modify the following lines to match your environment:
+# If you use the run: target at the end of the file, then adapt port number.
+PORT_NUMBER = 5678
+
+# The following variables probably don't need to be changed.
+JAVAC = javac
+JAVA = java
+# The JAR_PATH points to the jar files of your local office installation.
+JAR_PATH = $(SOLARBINDIR)$/
+
+
+# The rest of this makefile should not need to be touched.
+
+all : AccessibilityWorkBench
+
+JAR_FILES = \
+ unoil.jar \
+ ridl.jar \
+ jurt.jar \
+ juh.jar \
+ java_uno.jar
+
+JAVA_FILES = \
+ AccTreeNode.java \
+ AccessibilityTree.java \
+ AccessibilityTreeModel.java \
+ AccessibilityTreeModelBase.java \
+ AccessibilityWorkBench.java \
+ AccessibleActionHandler.java \
+ AccessibleActionNode.java \
+ AccessibleCellHandler.java \
+ AccessibleComponentHandler.java \
+ AccessibleContextHandler.java \
+ AccessibleEditableTextHandler.java \
+ AccessibleExtendedComponentHandler.java \
+ AccessibleHyperlinkHandler.java \
+ AccessibleHypertextHandler.java \
+ AccessibleImageHandler.java \
+ AccessibleRelationHandler.java \
+ AccessibleSelectionHandler.java \
+ AccessibleTableHandler.java \
+ AccessibleTextHandler.java \
+ AccessibleTreeCellRenderer.java \
+ AccessibleTreeHandler.java \
+ AccessibleTreeNode.java \
+ AccessibleUNOHandler.java \
+ Canvas.java \
+ CanvasShape.java \
+ ChildEventHandler.java \
+ ContextEventHandler.java \
+ EventHandler.java \
+ EventListener.java \
+ EventLogger.java \
+ EventQueue.java \
+ FrameActionListener.java \
+ GeometryEventHandler.java \
+ HelpWindow.java \
+ InformationWriter.java \
+ MessageArea.java \
+ NodeFactory.java \
+ NodeHandler.java \
+ NodeMap.java \
+ OfficeConnection.java \
+ Options.java \
+ QueuedListener.java \
+ QueuedTopWindowListener.java \
+ SelectionDialog.java \
+ SimpleOffice.java \
+ StringNode.java \
+ TableEventHandler.java \
+ TextLogger.java \
+ TextUpdateListener.java \
+ TopWindowListener.java \
+ VectorNode.java
+
+JAVA_CLASSPATHS := \
+ . \
+ $(foreach,i,$(JAR_FILES) $(JAR_PATH)$i) \
+ $(CLASSPATH)
+
+CLASSPATH !:=$(JAVA_CLASSPATHS:t$(PATH_SEPERATOR))
+
+JFLAGS = -deprecation -classpath $(CLASSPATH)
+
+%.class : %.java
+ $(JAVAC) $(JFLAGS) $<
+
+%.class : %.java
+ $(JAVAC) $(JFLAGS) $<
+
+AccessibilityWorkBench : ObjectView Tools $(JAVA_FILES:b:+".class")
+
+ObjectView .SETDIR=ov :
+ @echo "making package ObjectView"
+ dmake
+
+Tools .SETDIR=tools :
+ @echo "making package Tools"
+ dmake
+
+# Remove all class files.
+clean : ObjectView.clean Tools.clean
+ rm *.class
+ rm AccessibilityWorkBench.jar
+ObjectView.clean .SETDIR=ov :
+ rm *.class
+Tools.clean .SETDIR=tools :
+ rm *.class
+
+# Create a jar file of all files neccessary to build and run the work bench.
+dist: AccessibilityWorkBench.jar
+
+AccessibilityWorkBench.jar: $(JAVA_FILES:b:+".class") jawb.mf
+ jar -cfm AccessibilityWorkBench.jar jawb.mf *.class ov\*.class tools\*.class
+
+# Example of how to run the work bench.
+run: all
+ $(JAVA) -classpath $(CLASSPATH) AccessibilityWorkBench -p $(PORT_NUMBER)
+
+runjar: all dist
+ $(JAVA) -classpath $(CLASSPATH) -jar AccessibilityWorkBench.jar -p $(PORT_NUMBER)
+
diff --git a/toolkit/test/accessibility/news.html b/toolkit/test/accessibility/news.html
new file mode 100644
index 000000000000..9e801723f06a
--- /dev/null
+++ b/toolkit/test/accessibility/news.html
@@ -0,0 +1,36 @@
+<html><body bgcolor="#fffaf0">
+<h1>News for AWB v1.7.2</h1>
+<p>Adaption to recent UAA changes:
+<ul>
+<li>Introduction of
+com.sun.star.accessibility.TextSegment structure that is returned by some
+functions of the XAccessibleText interface.</li>
+<li>Removal of the COLLAPSED state.</li>
+<li>Renaming of XAccessibleSelectioni::selectAllAccessible to
+selectAllAccessibleChildren.</li>
+</ul>
+
+<h1>News for AWB v1.7</h1>
+
+<ul>
+
+<li>This help window.</li>
+
+<li>Integrated relocation of UAA files from drafts to final.</li>
+<li>Control left click in the graphical view expands the object that has
+ been clicked at.</li>
+
+<li>Introduction of split panes for easily changing the size of the three
+main widgets.</li>
+
+<li>The graphical view visualizes the screen size.</li>
+
+<li>Removed the "Load" button.</li>
+<li>Removed the status line.</li>
+<li>The tree view shows top level nodes only for document windows.</li>
+<li>New "views" menu that allows you to select the zoom scale of the
+ graphical view.</li>
+
+</ul>
+
+</body></html> \ No newline at end of file
diff --git a/toolkit/test/accessibility/ov/ContextView.java b/toolkit/test/accessibility/ov/ContextView.java
new file mode 100644
index 000000000000..4204c5de7bac
--- /dev/null
+++ b/toolkit/test/accessibility/ov/ContextView.java
@@ -0,0 +1,125 @@
+package ov;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.XAccessibleContext;
+
+import tools.NameProvider;
+
+public class ContextView
+ extends ListeningObjectView
+ implements ActionListener
+{
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ System.out.println ("ContextView.CreateView");
+ if (xContext != null)
+ return new ContextView (aContainer);
+ else
+ return null;
+ }
+
+ public ContextView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+ maNameLabel = new JLabel ("Name: ");
+ maName = new JLabel ("");
+ maDescriptionLabel = new JLabel ("Description: ");
+ maDescription = new JLabel ("");
+ maRoleLabel = new JLabel ("Role: ");
+ maRole = new JLabel ("");
+
+ // Make the background of name and description white and opaque so
+ // that leading and trailing spaces become visible.
+ maName.setOpaque (true);
+ maName.setBackground (Color.WHITE);
+ maDescription.setOpaque (true);
+ maDescription.setBackground (Color.WHITE);
+ maRole.setOpaque (true);
+ maRole.setBackground (Color.WHITE);
+
+ GridBagLayout aLayout = new GridBagLayout();
+ setLayout (aLayout);
+ GridBagConstraints constraints = new GridBagConstraints ();
+ constraints.gridx = 0;
+ constraints.gridy = 0;
+ constraints.gridwidth = 1;
+ constraints.gridheight = 1;
+ constraints.weightx = 0;
+ constraints.weighty = 1;
+ constraints.anchor = GridBagConstraints.WEST;
+ constraints.fill = GridBagConstraints.NONE;
+ add (maNameLabel, constraints);
+ constraints.gridy = 1;
+ add (maDescriptionLabel, constraints);
+ constraints.gridy = 2;
+ add (maRoleLabel, constraints);
+ constraints.gridy = 0;
+ constraints.gridx = 1;
+ constraints.weightx = 2;
+ add (maName, constraints);
+ constraints.gridy = 1;
+ add (maDescription, constraints);
+ constraints.gridy = 2;
+ add (maRole, constraints);
+ }
+
+ public void Update ()
+ {
+ if (mxContext == null)
+ {
+ maName.setText ("<null object>");
+ maDescription.setText ("<null object>");
+ maRole.setText ("<null object>");
+ }
+ else
+ {
+ maName.setText (mxContext.getAccessibleName());
+ maDescription.setText (mxContext.getAccessibleDescription());
+ maRole.setText (NameProvider.getRoleName (mxContext.getAccessibleRole()));
+ }
+ }
+
+ public String GetTitle ()
+ {
+ return ("Context");
+ }
+
+ /** Listen for changes regarding displayed values.
+ */
+ public void notifyEvent (AccessibleEventObject aEvent)
+ {
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId.NAME_CHANGED :
+ case AccessibleEventId.DESCRIPTION_CHANGED :
+ Update ();
+ }
+ }
+
+ public void actionPerformed (ActionEvent aEvent)
+ {
+ }
+
+
+ private JLabel
+ maNameLabel,
+ maName,
+ maDescriptionLabel,
+ maDescription,
+ maRoleLabel,
+ maRole;
+}
diff --git a/toolkit/test/accessibility/ov/FocusView.java b/toolkit/test/accessibility/ov/FocusView.java
new file mode 100644
index 000000000000..665fa260e288
--- /dev/null
+++ b/toolkit/test/accessibility/ov/FocusView.java
@@ -0,0 +1,119 @@
+package ov;
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.AccessibleStateType;
+import com.sun.star.accessibility.XAccessibleComponent;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleStateSet;
+import com.sun.star.uno.UnoRuntime;
+
+public class FocusView
+ extends ListeningObjectView
+ implements ActionListener
+{
+ /** Create a FocusView when the given object supports the
+ XAccessibleComponent interface.
+ */
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ XAccessibleComponent xComponent = (XAccessibleComponent)UnoRuntime.queryInterface(
+ XAccessibleComponent.class, xContext);
+ if (xComponent != null)
+ return new FocusView (aContainer);
+ else
+ return null;
+ }
+
+ public FocusView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+
+ setLayout (new GridBagLayout());
+ GridBagConstraints aConstraints = new GridBagConstraints ();
+
+ maFocused = new JLabel ();
+ aConstraints.gridy = 0;
+ aConstraints.weightx = 1;
+ aConstraints.fill = GridBagConstraints.HORIZONTAL;
+ add (maFocused, aConstraints);
+
+ maGrabFocus = new JButton ("grabFocus");
+ aConstraints.gridy = 1;
+ aConstraints.fill = GridBagConstraints.NONE;
+ aConstraints.anchor = GridBagConstraints.WEST;
+ add (maGrabFocus, aConstraints);
+
+ maGrabFocus.addActionListener (this);
+ }
+
+ /** Additionally to the context store a reference to the
+ XAccessibleComponent interface.
+ */
+ public void SetObject (XAccessibleContext xObject)
+ {
+ mxComponent = (XAccessibleComponent)UnoRuntime.queryInterface(
+ XAccessibleComponent.class, xObject);
+ super.SetObject (xObject);
+ }
+
+ synchronized public void Destroy ()
+ {
+ super.Destroy();
+ maGrabFocus.removeActionListener (this);
+ }
+
+ synchronized public void Update ()
+ {
+ if (mxContext == null)
+ {
+ maFocused.setText ("<null object>");
+ maGrabFocus.setEnabled (false);
+ }
+ else
+ {
+ XAccessibleStateSet aStateSet = mxContext.getAccessibleStateSet();
+ if (aStateSet.contains(AccessibleStateType.FOCUSED))
+ maFocused.setText ("focused");
+ else
+ maFocused.setText ("not focused");
+ if (maGrabFocus != null)
+ maGrabFocus.setEnabled (true);
+ }
+ }
+
+ public String GetTitle ()
+ {
+ return ("Focus");
+ }
+
+ synchronized public void actionPerformed (ActionEvent aEvent)
+ {
+ if (aEvent.getActionCommand().equals("grabFocus"))
+ {
+ mxComponent.grabFocus();
+ }
+ }
+
+ public void notifyEvent (AccessibleEventObject aEvent)
+ {
+ System.out.println (aEvent);
+ if (aEvent.EventId == AccessibleEventId.STATE_CHANGED)
+ Update ();
+ }
+
+ private JLabel maFocused;
+ private JButton maGrabFocus;
+ private XAccessibleComponent mxComponent;
+}
diff --git a/toolkit/test/accessibility/ov/ListeningObjectView.java b/toolkit/test/accessibility/ov/ListeningObjectView.java
new file mode 100644
index 000000000000..574fa989b20f
--- /dev/null
+++ b/toolkit/test/accessibility/ov/ListeningObjectView.java
@@ -0,0 +1,60 @@
+package ov;
+
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleEventBroadcaster;
+import com.sun.star.accessibility.XAccessibleEventListener;
+import com.sun.star.lang.EventObject;
+import com.sun.star.uno.UnoRuntime;
+
+/** Base class for object views that regsiters as accessibility event
+ listener.
+*/
+abstract class ListeningObjectView
+ extends ObjectView
+ implements XAccessibleEventListener
+{
+ public ListeningObjectView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+ }
+
+ /** Add this object as event listener at the broadcasting
+ accessible object.
+ */
+ public void SetObject (XAccessibleContext xContext)
+ {
+ super.SetObject (xContext);
+ XAccessibleEventBroadcaster xBroadcaster =
+ (XAccessibleEventBroadcaster)UnoRuntime.queryInterface(
+ XAccessibleEventBroadcaster.class, xContext);
+ if (xBroadcaster != null)
+ xBroadcaster.addEventListener (this);
+ }
+
+
+ /** Remove this object as event listener from the broadcasting
+ accessible object.
+ */
+ public void Destroy ()
+ {
+ super.Destroy ();
+ XAccessibleEventBroadcaster xBroadcaster =
+ (XAccessibleEventBroadcaster)UnoRuntime.queryInterface(
+ XAccessibleEventBroadcaster.class, mxContext);
+ if (xBroadcaster != null)
+ xBroadcaster.removeEventListener (this);
+ }
+
+ /** Derived classes have to implement this method to handle incoming
+ events.
+ */
+ abstract public void notifyEvent (AccessibleEventObject aEvent);
+
+ /** The disposing event is ignored per default. If a derived class is
+ interested it can overwrite this method.
+ */
+ public void disposing (EventObject aEvent)
+ {
+ }
+}
diff --git a/toolkit/test/accessibility/ov/ObjectView.java b/toolkit/test/accessibility/ov/ObjectView.java
new file mode 100644
index 000000000000..0c96969e733b
--- /dev/null
+++ b/toolkit/test/accessibility/ov/ObjectView.java
@@ -0,0 +1,77 @@
+package ov;
+
+import javax.swing.JPanel;
+
+import com.sun.star.accessibility.XAccessibleContext;
+
+/** This is the base class for all object views that can be placed inside an
+ object view container.
+
+ <p>When provided with a new accessible object the container will call
+ the Create method to create a new instance when certain conditions are
+ met. It then calls SetObject to pass the object to the instance.
+ Finally it calls Update.</p>
+
+ <p>The SetObject and Update methods may be called for a new object
+ without calling Create first. In this way an existing instance is
+ recycled.</p>
+*/
+abstract public class ObjectView
+ extends JPanel
+{
+ /** This factory method creates a new instance of the (derived) class
+ when the given accessible object supports all necessary features.
+ In the ususal case this will be the support of a specific
+ accessibility interface.
+ */
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ return null;
+ }
+
+ public ObjectView (ObjectViewContainer aContainer)
+ {
+ maContainer = aContainer;
+ mxContext = null;
+ }
+
+ /** Call this when you want the object to be destroyed. Release all
+ resources when called.
+ */
+ public void Destroy ()
+ {
+ }
+
+ /** Tell the view to display information for a new accessible object.
+ @param xObject
+ The given object may be null. A typical behaviour in this case
+ would be to display a blank area. But is also possible to show
+ information about the last object.
+ */
+ public void SetObject (XAccessibleContext xContext)
+ {
+ mxContext = xContext;
+ Update ();
+ }
+
+
+ /** This is a request of a repaint with the current state of the current
+ object. The current object may or may not be the same as the one
+ when Update() was called the last time.
+ */
+ public void Update ()
+ {
+ }
+
+
+ /** Return a string that is used as a title of an enclosing frame.
+ */
+ abstract public String GetTitle ();
+
+ /// Reference to the current object to display information about.
+ protected XAccessibleContext mxContext;
+
+ protected ObjectViewContainer maContainer;
+}
diff --git a/toolkit/test/accessibility/ov/ObjectViewContainer.java b/toolkit/test/accessibility/ov/ObjectViewContainer.java
new file mode 100644
index 000000000000..c0bf6a86736b
--- /dev/null
+++ b/toolkit/test/accessibility/ov/ObjectViewContainer.java
@@ -0,0 +1,166 @@
+package ov;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+
+import java.util.Vector;
+
+import java.lang.reflect.Method;
+import java.lang.NoSuchMethodException;
+import java.lang.IllegalAccessException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JPanel;
+import javax.swing.JTree;
+import javax.swing.BorderFactory;
+import javax.swing.border.Border;
+import javax.swing.border.BevelBorder;
+
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleComponent;
+import com.sun.star.accessibility.XAccessibleSelection;
+import com.sun.star.uno.UnoRuntime;
+
+
+public class ObjectViewContainer
+ extends JPanel
+{
+ public ObjectViewContainer ()
+ {
+ maViewTemplates = new Vector ();
+ maViewBorder = BorderFactory.createBevelBorder (BevelBorder.RAISED);
+ setLayout (new GridBagLayout ());
+
+ System.out.println ("ObjectViewContainer");
+ RegisterView (ContextView.class);
+ // RegisterView (StateSetView.class);
+ RegisterView (FocusView.class);
+ RegisterView (TextView.class);
+ }
+
+
+
+ /** Remove all existing views and create new ones according to the
+ interfaces supported by the given object.
+ */
+ public void SetObject (XAccessibleContext xContext)
+ {
+ // Call Destroy at all views to give them a chance to release their
+ // resources.
+ int n = getComponentCount();
+ for (int i=0; i<n; i++)
+ ((ObjectView)getComponent(i)).Destroy();
+ // Remove existing views.
+ removeAll ();
+
+ // Add new views.
+ for (int i=0; i<maViewTemplates.size(); i++)
+ {
+ try
+ {
+ Class aViewClass = (Class)maViewTemplates.elementAt (i);
+ Method aCreateMethod = aViewClass.getDeclaredMethod (
+ "Create", new Class[] {
+ ObjectViewContainer.class,
+ XAccessibleContext.class});
+ if (aCreateMethod != null)
+ {
+ ObjectView aView = (ObjectView)
+ aCreateMethod.invoke (null, new Object[] {this, xContext});
+ Add (aView);
+ }
+ }
+ catch (NoSuchMethodException e)
+ {System.err.println ("Caught exception while creating view " + i + " : " + e);}
+ catch (IllegalAccessException e)
+ {System.err.println ("Caught exception while creating view " + i + " : " + e);}
+ catch (InvocationTargetException e)
+ {System.err.println ("Caught exception while creating view " + i + " : " + e);}
+ }
+
+ UpdateLayoutManager ();
+
+ // Now set the object at all views.
+ n = getComponentCount();
+ for (int i=0; i<n; i++)
+ ((ObjectView)getComponent(i)).SetObject (xContext);
+
+ setPreferredSize (getLayout().preferredLayoutSize (this));
+ }
+
+
+ /** Add the given class to the list of classes which will be
+ instantiated the next time an accessible object is set.
+ */
+ public void RegisterView (Class aObjectViewClass)
+ {
+ System.out.println ("registering " + aObjectViewClass);
+ maViewTemplates.addElement (aObjectViewClass);
+ }
+
+ /** Replace one view class with another.
+ */
+ public void ReplaceView (Class aObjectViewClass, Class aSubstitution)
+ {
+ int nIndex = maViewTemplates.indexOf (aObjectViewClass);
+ if (nIndex >= 0)
+ maViewTemplates.setElementAt (aSubstitution, nIndex);
+ }
+
+ /** Add an object view and place it below all previously added views.
+ @param aView
+ This argument may be null. In this case nothing happens.
+ */
+ private void Add (ObjectView aView)
+ {
+ if (aView != null)
+ {
+ GridBagConstraints constraints = new GridBagConstraints ();
+ constraints.gridx = 0;
+ constraints.gridy = getComponentCount();
+ constraints.gridwidth = 1;
+ constraints.gridheight = 1;
+ constraints.weightx = 1;
+ constraints.weighty = 0;
+ constraints.ipadx = 2;
+ constraints.ipady = 5;
+ constraints.insets = new Insets (5,5,5,5);
+ constraints.anchor = GridBagConstraints.NORTH;
+ constraints.fill = GridBagConstraints.HORIZONTAL;
+
+ aView.setBorder (
+ BorderFactory.createTitledBorder (
+ maViewBorder, aView.GetTitle()));
+
+ add (aView, constraints);
+ }
+ }
+
+ /** Update the layout manager by setting the vertical weight of the
+ bottom entry to 1 and so make it strech to over the available
+ space.
+
+ */
+ private void UpdateLayoutManager ()
+ {
+ // Adapt the layout manager.
+ if (getComponentCount() > 0)
+ {
+ Component aComponent = getComponent (getComponentCount()-1);
+ GridBagLayout aLayout = (GridBagLayout)getLayout();
+ GridBagConstraints aConstraints = aLayout.getConstraints (aComponent);
+ aConstraints.weighty = 1;
+ aLayout.setConstraints (aComponent, aConstraints);
+ }
+ }
+
+ /// Observe this tree for selection changes and notify them to all
+ /// children.
+ private JTree maTree;
+ private Border maViewBorder;
+ /// List of view templates which are instantiated when new object is set.
+ private Vector maViewTemplates;
+}
diff --git a/toolkit/test/accessibility/ov/SelectionView.java b/toolkit/test/accessibility/ov/SelectionView.java
new file mode 100644
index 000000000000..a71f242420ba
--- /dev/null
+++ b/toolkit/test/accessibility/ov/SelectionView.java
@@ -0,0 +1,230 @@
+package ov;
+
+import java.util.Vector;
+
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JOptionPane;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JToggleButton;
+import javax.swing.ListSelectionModel;
+
+
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.AccessibleStateType;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleSelection;
+import com.sun.star.accessibility.XAccessibleStateSet;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+
+/** Display a list of children and select/deselect buttons
+*/
+class SelectionView
+ extends ListeningObjectView
+ implements ActionListener
+{
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ XAccessibleSelection xSelection = (XAccessibleSelection)UnoRuntime.queryInterface(
+ XAccessibleSelection.class, xContext);
+ if (xSelection != null)
+ return new SelectionView(aContainer);
+ else
+ return null;
+ }
+
+ public SelectionView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+ Layout();
+ }
+
+ public String GetTitle ()
+ {
+ return "Selection";
+ }
+
+ /** Create and arrange the widgets for this view.
+ */
+ private void Layout ()
+ {
+ setLayout (new GridBagLayout());
+
+ GridBagConstraints aConstraints = new GridBagConstraints();
+
+ // Label that shows wheter the selection is multi selectable.
+ aConstraints.gridx = 0;
+ aConstraints.gridy = 0;
+ aConstraints.anchor = GridBagConstraints.WEST;
+ maTypeLabel = new JLabel ();
+ add (maTypeLabel, aConstraints);
+
+ // the JListBox
+ maChildrenSelector = new JPanel ();
+ maChildrenSelector.setPreferredSize (new Dimension (100,100));
+ maChildrenSelector.setLayout (new BoxLayout (maChildrenSelector, BoxLayout.Y_AXIS));
+
+ aConstraints.gridx = 0;
+ aConstraints.gridwidth = 4;
+ aConstraints.gridy = 1;
+ aConstraints.fill = GridBagConstraints.HORIZONTAL;
+ add (new JScrollPane (maChildrenSelector,
+ JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
+ JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
+ aConstraints);
+
+ JButton aButton;
+ aButton = new JButton( "Select all" );
+ aButton.setActionCommand( "Select all" );
+ aButton.addActionListener( this );
+ aConstraints.gridx = 0;
+ aConstraints.gridwidth = 1;
+ aConstraints.gridy = 2;
+ aConstraints.fill = GridBagConstraints.NONE;
+ aConstraints.anchor = GridBagConstraints.WEST;
+ add (aButton, aConstraints);
+
+ aButton = new JButton( "Clear Selection" );
+ aButton.setActionCommand( "Clear Selection" );
+ aButton.addActionListener( this );
+ aConstraints.gridx = 1;
+ aConstraints.gridy = 2;
+ aConstraints.weightx = 1;
+ add (aButton, aConstraints);
+
+ setSize (getPreferredSize());
+ }
+
+
+ public void SetObject (XAccessibleContext xContext)
+ {
+ mxSelection = (XAccessibleSelection)UnoRuntime.queryInterface(
+ XAccessibleSelection.class, xContext);
+ super.SetObject (xContext);
+ }
+
+
+ public void Update ()
+ {
+ maChildrenSelector.removeAll ();
+
+ // Determine whether multi selection is possible.
+ XAccessibleStateSet aStateSet = mxContext.getAccessibleStateSet();
+ boolean bMultiSelectable = false;
+ ButtonGroup aButtonGroup = null;
+ if (aStateSet!=null && aStateSet.contains(AccessibleStateType.MULTI_SELECTABLE))
+ {
+ bMultiSelectable = true;
+ maTypeLabel.setText ("multi selectable");
+ }
+ else
+ {
+ maTypeLabel.setText ("single selectable");
+ aButtonGroup = new ButtonGroup ();
+ }
+
+ int nCount = mxContext.getAccessibleChildCount();
+ for (int i=0; i<nCount; i++)
+ {
+ try
+ {
+ XAccessible xChild = mxContext.getAccessibleChild(i);
+ XAccessibleContext xChildContext = xChild.getAccessibleContext();
+
+ String sName = i + " " + xChildContext.getAccessibleName();
+ JToggleButton aChild;
+ if (bMultiSelectable)
+ aChild = new JCheckBox (sName);
+ else
+ {
+ aChild = new JRadioButton (sName);
+ aButtonGroup.add (aChild);
+ }
+
+ XAccessibleStateSet aChildStateSet = mxContext.getAccessibleStateSet();
+ aChild.setSelected (aChildStateSet!=null
+ && aChildStateSet.contains(AccessibleStateType.SELECTED));
+
+ aChild.addActionListener (this);
+ maChildrenSelector.add (aChild);
+
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ }
+ }
+ }
+
+
+ void SelectAll()
+ {
+ mxSelection.selectAllAccessibleChildren();
+ }
+
+ void ClearSelection()
+ {
+ mxSelection.clearAccessibleSelection();
+ }
+
+
+ /** Call the function associated with the pressed button.
+ */
+ public void actionPerformed (ActionEvent aEvent)
+ {
+ String sCommand = aEvent.getActionCommand();
+
+ if (sCommand.equals ("Clear Selection"))
+ ClearSelection();
+ else if (sCommand.equals ("Select all"))
+ SelectAll();
+ else
+ {
+ // Extract the child index from the widget text.
+ String[] aWords = sCommand.split (" ");
+ int nIndex = Integer.parseInt(aWords[0]);
+ try
+ {
+ if (((JToggleButton)aEvent.getSource()).isSelected())
+ mxSelection.selectAccessibleChild (nIndex);
+ else
+ mxSelection.deselectAccessibleChild (nIndex);
+ }
+ catch (IndexOutOfBoundsException e)
+ {
+ System.err.println ("caught exception while changing selection: " + e);
+ }
+ }
+ }
+
+
+ public void notifyEvent (AccessibleEventObject aEvent)
+ {
+ if (aEvent.EventId == AccessibleEventId.SELECTION_CHANGED)
+ Update ();
+ }
+
+ private JPanel maChildrenSelector;
+ private XAccessibleSelection mxSelection;
+ private JLabel maTypeLabel;
+}
diff --git a/toolkit/test/accessibility/ov/StateSetView.java b/toolkit/test/accessibility/ov/StateSetView.java
new file mode 100644
index 000000000000..e8997ac0c5a0
--- /dev/null
+++ b/toolkit/test/accessibility/ov/StateSetView.java
@@ -0,0 +1,249 @@
+package ov;
+
+import java.awt.Color;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+
+import java.awt.event.MouseListener;
+import java.awt.event.MouseEvent;
+
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.AffineTransform;
+
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.Border;
+
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleStateType;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleStateSet;
+
+import tools.NameProvider;
+
+public class StateSetView
+ extends ListeningObjectView
+ implements MouseListener
+{
+ /** Create a FocusView when the given object supports the
+ XAccessibleComponent interface.
+ */
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ ObjectView aView = null;
+ if (xContext != null)
+ if (mnViewMode == SHOW_ALL_STATES)
+ aView = StateSetAllView.Create (aContainer, xContext);
+ else
+ aView = StateSetSetView.Create (aContainer, xContext);
+ return aView;
+ }
+
+ public StateSetView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+
+ addMouseListener (this);
+ }
+
+ private void SetViewMode (int nViewMode)
+ {
+ mnViewMode = nViewMode;
+ switch (mnViewMode)
+ {
+ case SHOW_SET_STATES :
+ maContainer.ReplaceView (
+ getClass(),
+ StateSetSetView.class);
+ break;
+ case SHOW_ALL_STATES :
+ maContainer.ReplaceView (
+ getClass(),
+ StateSetAllView.class);
+ break;
+ }
+ aContainer.SetObject (mxContext);
+ }
+
+
+
+ public String GetTitle ()
+ {
+ return ("StateSet");
+ }
+
+ public void notifyEvent (AccessibleEventObject aEvent)
+ {
+ if (aEvent.EventId == AccessibleEventId.STATE_CHANGED)
+ Update();
+ }
+
+ public void mouseClicked(MouseEvent e)
+ {
+ switch (mnViewMode)
+ {
+ case SHOW_SET_STATES :
+ SetViewMode (SHOW_ALL_STATES);
+ break;
+ case SHOW_ALL_STATES :
+ SetViewMode (SHOW_SET_STATES);
+ break;
+ }
+ }
+ public void mouseEntered (MouseEvent e) {}
+ public void mouseExited (MouseEvent e) {}
+ public void mousePressed (MouseEvent e) {}
+ public void mouseReleased(MouseEvent e) {}
+
+ private static int mnViewMode = SHOW_ALL_STATES;
+ private final static int SHOW_SET_STATES = 0;
+ private final static int SHOW_ALL_STATES = 1;
+
+
+
+public class StateSetAllView
+ extends StateSetView
+{
+ /** Create a FocusView when the given object supports the
+ XAccessibleComponent interface.
+ */
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ if (xContext != null)
+ return new StateSetAllView (aContainer);
+ else
+ return null;
+ }
+
+ public StateSetAllView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+
+ setPreferredSize (new Dimension(300,90));
+ setMinimumSize (new Dimension(200,80));
+ }
+
+ public void paintChildren (Graphics g)
+ {
+ synchronized (g)
+ {
+ super.paintChildren (g);
+
+ // Calculcate the are inside the border.
+ Insets aInsets = getInsets ();
+ Dimension aSize = getSize();
+ Rectangle aWidgetArea = new Rectangle (
+ aInsets.left,
+ aInsets.top,
+ aSize.width-aInsets.left-aInsets.right,
+ aSize.height-aInsets.top-aInsets.bottom);
+
+ PaintAllStates ((Graphics2D)g, aWidgetArea);
+ }
+ }
+
+ private void PaintAllStates (Graphics2D g, Rectangle aWidgetArea)
+ {
+ Color aTextColor = g.getColor();
+
+ g.setRenderingHint (
+ RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ XAccessibleStateSet xStateSet = mxContext.getAccessibleStateSet();
+ if (xStateSet != null)
+ {
+ short aStates[] = xStateSet.getStates ();
+ final int nMaxStateIndex = AccessibleStateType.MANAGES_DESCENDANTS;
+ int nStateWidth = (aWidgetArea.width-12) / (nMaxStateIndex+1);
+ AffineTransform aTransform = g.getTransform ();
+ g.setColor (aTextColor);
+ int y = aWidgetArea.y+aWidgetArea.height - 12;
+ double nTextRotation = -0.9;//-java.lang.Math.PI/2;
+ double nScale = 0.6;
+
+ // Create a shape for the boxes.
+ int nBoxWidth = nStateWidth-2;
+ if (nBoxWidth > 8)
+ nBoxWidth = 8;
+ Rectangle aCheckBox = new Rectangle (-nBoxWidth/2,0,nBoxWidth,nBoxWidth);
+
+ for (short i=0; i<=nMaxStateIndex; i++)
+ {
+ int x = nStateWidth + i * nStateWidth;
+ String sStateName = NameProvider.getStateName (i);
+ boolean bStateSet = xStateSet.contains (i);
+ g.setTransform (aTransform);
+ g.translate (x,y);
+ if (bStateSet)
+ {
+ g.setColor (Color.GREEN);
+ g.fill (aCheckBox);
+ g.setColor (aTextColor);
+ }
+ g.draw (aCheckBox);
+ g.rotate (nTextRotation);
+ g.scale (nScale, nScale);
+ g.translate (2,-2);
+ g.drawString (sStateName, 0,0);
+ }
+ }
+ }
+}
+
+
+public class StateSetSetView
+ extends StateSetView
+{
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ if (xContext != null)
+ return new StateSetSetView (aContainer);
+ else
+ return null;
+ }
+
+ public StateSetSetView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+
+ maStates = null;
+ setPreferredSize (new Dimension(300,90));
+ }
+
+
+ synchronized public void Update ()
+ {
+ XAccessibleStateSet xStateSet = mxContext.getAccessibleStateSet();
+ if (xStateSet != null)
+ {
+ String sStates = new String ();
+ short aStates[] = xStateSet.getStates();
+ for (int i=0; i<aStates.length; i++)
+ {
+ if (i > 0)
+ sStates = sStates + ", ";
+ sStates = sStates + NameProvider.getStateName(aStates[i]);
+ }
+ maStates.setText (sStates);
+ }
+ }
+
+ private JLabel maStates;
+}
+
+}
diff --git a/toolkit/test/accessibility/ov/TextView.java b/toolkit/test/accessibility/ov/TextView.java
new file mode 100644
index 000000000000..094647986e4f
--- /dev/null
+++ b/toolkit/test/accessibility/ov/TextView.java
@@ -0,0 +1,123 @@
+package ov;
+
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.AccessibleStateType;
+import com.sun.star.accessibility.XAccessibleText;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleStateSet;
+import com.sun.star.uno.UnoRuntime;
+
+public class TextView
+ extends ListeningObjectView
+{
+ /** Create a TextView when the given object supports the
+ XAccessibleText interface.
+ */
+ static public ObjectView Create (
+ ObjectViewContainer aContainer,
+ XAccessibleContext xContext)
+ {
+ XAccessibleText xText = (XAccessibleText)UnoRuntime.queryInterface(
+ XAccessibleText.class, xContext);
+ if (xText != null)
+ return new TextView (aContainer);
+ else
+ return null;
+ }
+
+
+ public TextView (ObjectViewContainer aContainer)
+ {
+ super (aContainer);
+
+ setLayout (new GridBagLayout());
+ GridBagConstraints aConstraints = new GridBagConstraints ();
+
+ JLabel aLabel = new JLabel ("Text:");
+ aConstraints.gridy = 0;
+ aConstraints.weightx = 1;
+ aConstraints.fill = GridBagConstraints.HORIZONTAL;
+ add (aLabel, aConstraints);
+
+ maTextLabel = new JLabel ("");
+ aConstraints.gridx = 1;
+ aConstraints.fill = GridBagConstraints.NONE;
+ aConstraints.anchor = GridBagConstraints.WEST;
+ add (maTextLabel, aConstraints);
+
+ aLabel = new JLabel ("Caret position:");
+ aConstraints.gridx = 0;
+ aConstraints.gridy = 1;
+ aConstraints.weightx = 1;
+ aConstraints.fill = GridBagConstraints.HORIZONTAL;
+ add (aLabel, aConstraints);
+
+ maCaretPositionLabel = new JLabel ("");
+ aConstraints.gridx = 1;
+ aConstraints.fill = GridBagConstraints.NONE;
+ aConstraints.anchor = GridBagConstraints.WEST;
+ add (maCaretPositionLabel, aConstraints);
+ }
+
+
+ /** Additionally to the context store a reference to the
+ XAccessibleText interface.
+ */
+ public void SetObject (XAccessibleContext xObject)
+ {
+ mxText = (XAccessibleText)UnoRuntime.queryInterface(
+ XAccessibleText.class, xObject);
+ super.SetObject (xObject);
+ }
+
+ synchronized public void Destroy ()
+ {
+ super.Destroy();
+ }
+
+ synchronized public void Update ()
+ {
+ if (mxText == null)
+ {
+ maTextLabel.setText ("<null object>");
+ maCaretPositionLabel.setText ("<null object>");
+ }
+ else
+ {
+ maTextLabel.setText (mxText.getText());
+ maCaretPositionLabel.setText (Integer.toString(mxText.getCaretPosition()));
+ }
+ }
+
+ public String GetTitle ()
+ {
+ return ("Text");
+ }
+
+ public void notifyEvent (AccessibleEventObject aEvent)
+ {
+ System.out.println (aEvent);
+ switch (aEvent.EventId)
+ {
+ case AccessibleEventId.TEXT_CHANGED :
+ case AccessibleEventId.CARET_CHANGED :
+ Update ();
+ break;
+ }
+ }
+
+ private JLabel
+ maTextLabel,
+ maCaretPositionLabel;
+ private XAccessibleText mxText;
+}
diff --git a/toolkit/test/accessibility/ov/makefile.mk b/toolkit/test/accessibility/ov/makefile.mk
new file mode 100644
index 000000000000..56fb563eeee0
--- /dev/null
+++ b/toolkit/test/accessibility/ov/makefile.mk
@@ -0,0 +1,51 @@
+# This is the dmake version.
+
+# copied from settings.mk
+SOLARBINDIR=$(SOLARVERSION)$/$(INPATH)$/bin$(UPDMINOREXT)
+
+# Please modify the following lines to match your environment:
+# If you use the run: target at the end of the file, then adapt port number.
+PORT_NUMBER = 5678
+
+# The following variables probably don't need to be changed.
+JAVAC = javac
+JAVA = java
+# The JAR_PATH points to the jar files of your local office installation.
+JAR_PATH = $(SOLARBINDIR)$/
+
+
+# The rest of this makefile should not need to be touched.
+
+all : ov
+
+JAR_FILES = \
+ unoil.jar \
+ ridl.jar \
+ jurt.jar \
+ juh.jar \
+ java_uno.jar
+
+JAVA_FILES = \
+ ov/ObjectViewContainer.java \
+ ov/ObjectView.java \
+ ov/ListeningObjectView.java \
+ ov/ContextView.java \
+ ov/FocusView.java \
+ ov/SelectionView.java \
+ ov/TextView.java
+# ov/StateSetView.java \
+
+
+JAVA_CLASSPATHS := \
+ . .. \
+ $(foreach,i,$(JAR_FILES) $(JAR_PATH)$i) \
+ $(CLASSPATH)
+
+CLASSPATH !:=$(JAVA_CLASSPATHS:t$(PATH_SEPERATOR))
+
+JFLAGS = -deprecation -classpath $(CLASSPATH)
+
+%.class : %.java
+ $(JAVAC) $(JFLAGS) $<
+
+ov : $(JAVA_FILES:b:+".class")
diff --git a/toolkit/test/accessibility/tools/NameProvider.java b/toolkit/test/accessibility/tools/NameProvider.java
new file mode 100644
index 000000000000..d9bcab802cbf
--- /dev/null
+++ b/toolkit/test/accessibility/tools/NameProvider.java
@@ -0,0 +1,259 @@
+package tools;
+
+import java.util.HashMap;
+import com.sun.star.accessibility.AccessibleStateType;
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleRole;
+import com.sun.star.accessibility.AccessibleRelationType;
+
+
+/** Provide names for several accessibility constants groups.
+*/
+public class NameProvider
+{
+ /** Return the name of the specified state.
+ @param nStateId
+ Id of the state for which to return its name. This is one of
+ the ids listed in the <type>AccessibleStateType</const>
+ constants group.
+ @return
+ Returns the name of the specified state or an empty string if an
+ invalid / unknown state id was given.
+ */
+ public static String getStateName (int nStateId)
+ {
+ return (String)maStateMap.get (new Integer(nStateId));
+ }
+
+
+ /** Return the name of the specified event.
+ @param nEventId
+ Id of the event type for which to return its name. This is one
+ of the ids listed in the <type>AccessibleEventId</const>
+ constants group.
+ @return
+ Returns the name of the specified event type or an empty string
+ if an invalid / unknown event id was given.
+ */
+ public static String getEventName (int nEventId)
+ {
+ return (String)maEventMap.get (new Integer(nEventId));
+ }
+
+
+ /** Return the name of the specified role.
+ @param nRole
+ Id of the role for which to return its name. This is one of
+ the ids listed in the <type>AccessibleRole</const>
+ constants group.
+ @return
+ Returns the name of the specified role or an empty string if an
+ invalid / unknown role id was given.
+ */
+ public static String getRoleName (int nRole)
+ {
+ return (String)maRoleMap.get (new Integer(nRole));
+ }
+
+
+ /** Return the name of the specified relation.
+ @param nRelation
+ Id of the relation for which to return its name. This is one of
+ the ids listed in the <type>AccessibleRelationType</const>
+ constants group.
+ @return
+ Returns the name of the specified relation type or an empty
+ string if an invalid / unknown role id was given.
+ */
+ public static String getRelationName (int nRelation)
+ {
+ return (String)maRelationMap.get (new Integer(nRelation));
+ }
+
+
+ private static HashMap maStateMap = new HashMap();
+ private static HashMap maEventMap = new HashMap();
+ private static HashMap maRoleMap = new HashMap();
+ private static HashMap maRelationMap = new HashMap();
+
+ static {
+ maStateMap.put (new Integer (AccessibleStateType.INVALID), "INVALID");
+ maStateMap.put (new Integer (AccessibleStateType.ACTIVE), "ACTIVE");
+ maStateMap.put (new Integer (AccessibleStateType.ARMED), "ARMED");
+ maStateMap.put (new Integer (AccessibleStateType.BUSY), "BUSY");
+ maStateMap.put (new Integer (AccessibleStateType.CHECKED), "CHECKED");
+ // maStateMap.put (new Integer (AccessibleStateType.COLLAPSED), "COLLAPSED");
+ maStateMap.put (new Integer (AccessibleStateType.DEFUNC), "DEFUNC");
+ maStateMap.put (new Integer (AccessibleStateType.EDITABLE), "EDITABLE");
+ maStateMap.put (new Integer (AccessibleStateType.ENABLED), "ENABLED");
+ maStateMap.put (new Integer (AccessibleStateType.EXPANDABLE), "EXPANDABLE");
+ maStateMap.put (new Integer (AccessibleStateType.EXPANDED), "EXPANDED");
+ maStateMap.put (new Integer (AccessibleStateType.FOCUSABLE), "FOCUSABLE");
+ maStateMap.put (new Integer (AccessibleStateType.FOCUSED), "FOCUSED");
+ maStateMap.put (new Integer (AccessibleStateType.HORIZONTAL), "HORIZONTAL");
+ maStateMap.put (new Integer (AccessibleStateType.ICONIFIED), "ICONIFIED");
+ maStateMap.put (new Integer (AccessibleStateType.MODAL), "MODAL");
+ maStateMap.put (new Integer (AccessibleStateType.MULTI_LINE), "MULTI_LINE");
+ maStateMap.put (new Integer (AccessibleStateType.MULTI_SELECTABLE), "MULTI_SELECTABLE");
+ maStateMap.put (new Integer (AccessibleStateType.OPAQUE), "OPAQUE");
+ maStateMap.put (new Integer (AccessibleStateType.PRESSED), "PRESSED");
+ maStateMap.put (new Integer (AccessibleStateType.RESIZABLE), "RESIZABLE");
+ maStateMap.put (new Integer (AccessibleStateType.SELECTABLE), "SELECTABLE");
+ maStateMap.put (new Integer (AccessibleStateType.SELECTED), "SELECTED");
+ maStateMap.put (new Integer (AccessibleStateType.SENSITIVE), "SENSITIVE");
+ maStateMap.put (new Integer (AccessibleStateType.SHOWING), "SHOWING");
+ maStateMap.put (new Integer (AccessibleStateType.SINGLE_LINE), "SINGLE_LINE");
+ maStateMap.put (new Integer (AccessibleStateType.STALE), "STALE");
+ maStateMap.put (new Integer (AccessibleStateType.TRANSIENT), "TRANSIENT");
+ maStateMap.put (new Integer (AccessibleStateType.VERTICAL), "VERTICAL");
+ maStateMap.put (new Integer (AccessibleStateType.VISIBLE), "VISIBLE");
+ maStateMap.put (new Integer (AccessibleStateType.MANAGES_DESCENDANTS),
+ "MANAGES_DESCENDANTS");
+ // maStateMap.put (new Integer (AccessibleStateType.INCONSISTENT),"INCONSISTENT");
+
+
+ maEventMap.put (new Integer (0),
+ "[UNKNOWN]");
+ maEventMap.put (new Integer (AccessibleEventId.NAME_CHANGED),
+ "NAME_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.DESCRIPTION_CHANGED),
+ "DESCRIPTION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.ACTION_CHANGED),
+ "ACTION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.STATE_CHANGED),
+ "STATE_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.ACTIVE_DESCENDANT_CHANGED),
+ "ACTIVE_DESCENDANT_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.BOUNDRECT_CHANGED),
+ "BOUNDRECT_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.CHILD),
+ "CHILD");
+ maEventMap.put (new Integer (AccessibleEventId.INVALIDATE_ALL_CHILDREN),
+ "INVALIDATE_ALL_CHILDREN");
+ maEventMap.put (new Integer (AccessibleEventId.SELECTION_CHANGED),
+ "SELECTION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.VISIBLE_DATA_CHANGED),
+ "VISIBLE_DATA_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.VALUE_CHANGED),
+ "VALUE_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.CONTENT_FLOWS_FROM_RELATION_CHANGED),
+ "CONTENT_FLOWS_FROM_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.CONTENT_FLOWS_TO_RELATION_CHANGED),
+ "CONTENT_FLOWS_TO_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.CONTROLLED_BY_RELATION_CHANGED),
+ "CONTROLLED_BY_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.CONTROLLER_FOR_RELATION_CHANGED),
+ "CONTROLLER_FOR_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.LABEL_FOR_RELATION_CHANGED),
+ "LABEL_FOR_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.LABELED_BY_RELATION_CHANGED),
+ "LABELED_BY_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.MEMBER_OF_RELATION_CHANGED),
+ "MEMBER_OF_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.SUB_WINDOW_OF_RELATION_CHANGED),
+ "SUB_WINDOW_OF_RELATION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.CARET_CHANGED),
+ "CARET_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TEXT_SELECTION_CHANGED),
+ "TEXT_SELECTION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TEXT_CHANGED),
+ "TEXT_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TEXT_ATTRIBUTE_CHANGED),
+ "TEXT_ATTRIBUTE_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.HYPERTEXT_CHANGED),
+ "HYPERTEXT_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TABLE_CAPTION_CHANGED),
+ "TABLE_CAPTION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TABLE_COLUMN_DESCRIPTION_CHANGED),
+ "TABLE_COLUMN_DESCRIPTION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TABLE_COLUMN_HEADER_CHANGED),
+ "TABLE_COLUMN_HEADER_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TABLE_MODEL_CHANGED),
+ "TABLE_MODEL_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TABLE_ROW_DESCRIPTION_CHANGED),
+ "TABLE_ROW_DESCRIPTION_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TABLE_ROW_HEADER_CHANGED),
+ "TABLE_ROW_HEADER_CHANGED");
+ maEventMap.put (new Integer (AccessibleEventId.TABLE_SUMMARY_CHANGED),
+ "TABLE_SUMMARY_CHANGED");
+
+ maRoleMap.put (new Integer(AccessibleRole.UNKNOWN), "UNKNOWN");
+ maRoleMap.put (new Integer (AccessibleRole.UNKNOWN), "UNKNOWN");
+ maRoleMap.put (new Integer (AccessibleRole.ALERT), "ALERT");
+ maRoleMap.put (new Integer (AccessibleRole.COLUMN_HEADER), "COLUMN_HEADER");
+ maRoleMap.put (new Integer (AccessibleRole.CANVAS), "CANVAS");
+ maRoleMap.put (new Integer (AccessibleRole.CHECK_BOX), "CHECK_BOX");
+ maRoleMap.put (new Integer (AccessibleRole.CHECK_MENU_ITEM), "CHECK_MENU_ITEM");
+ maRoleMap.put (new Integer (AccessibleRole.COLOR_CHOOSER), "COLOR_CHOOSER");
+ maRoleMap.put (new Integer (AccessibleRole.COMBO_BOX), "COMBO_BOX");
+ maRoleMap.put (new Integer (AccessibleRole.DESKTOP_ICON), "DESKTOP_ICON");
+ maRoleMap.put (new Integer (AccessibleRole.DESKTOP_PANE), "DESKTOP_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.DIRECTORY_PANE), "DIRECTORY_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.DIALOG), "DIALOG");
+ maRoleMap.put (new Integer (AccessibleRole.DOCUMENT), "DOCUMENT");
+ maRoleMap.put (new Integer (AccessibleRole.EMBEDDED_OBJECT), "EMBEDDED_OBJECT");
+ maRoleMap.put (new Integer (AccessibleRole.END_NOTE), "END_NOTE");
+ maRoleMap.put (new Integer (AccessibleRole.FILE_CHOOSER), "FILE_CHOOSER");
+ maRoleMap.put (new Integer (AccessibleRole.FILLER), "FILLER");
+ maRoleMap.put (new Integer (AccessibleRole.FONT_CHOOSER), "FONT_CHOOSER");
+ maRoleMap.put (new Integer (AccessibleRole.FOOTER), "FOOTER");
+ maRoleMap.put (new Integer (AccessibleRole.FOOTNOTE), "FOOTNOTE");
+ maRoleMap.put (new Integer (AccessibleRole.FRAME), "FRAME");
+ maRoleMap.put (new Integer (AccessibleRole.GLASS_PANE), "GLASS_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.GRAPHIC), "GRAPHIC");
+ maRoleMap.put (new Integer (AccessibleRole.GROUP_BOX), "GROUP_BOX");
+ maRoleMap.put (new Integer (AccessibleRole.HEADER), "HEADER");
+ maRoleMap.put (new Integer (AccessibleRole.HEADING), "HEADING");
+ maRoleMap.put (new Integer (AccessibleRole.HYPER_LINK), "HYPER_LINK");
+ maRoleMap.put (new Integer (AccessibleRole.ICON), "ICON");
+ maRoleMap.put (new Integer (AccessibleRole.INTERNAL_FRAME), "INTERNAL_FRAME");
+ maRoleMap.put (new Integer (AccessibleRole.LABEL), "LABEL");
+ maRoleMap.put (new Integer (AccessibleRole.LAYERED_PANE), "LAYERED_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.LIST), "LIST");
+ maRoleMap.put (new Integer (AccessibleRole.LIST_ITEM), "LIST_ITEM");
+ maRoleMap.put (new Integer (AccessibleRole.MENU), "MENU");
+ maRoleMap.put (new Integer (AccessibleRole.MENU_BAR), "MENU_BAR");
+ maRoleMap.put (new Integer (AccessibleRole.MENU_ITEM), "MENU_ITEM");
+ maRoleMap.put (new Integer (AccessibleRole.OPTION_PANE), "OPTION_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.PAGE_TAB), "PAGE_TAB");
+ maRoleMap.put (new Integer (AccessibleRole.PAGE_TAB_LIST), "PAGE_TAB_LIST");
+ maRoleMap.put (new Integer (AccessibleRole.PANEL), "PANEL");
+ maRoleMap.put (new Integer (AccessibleRole.PARAGRAPH), "PARAGRAPH");
+ maRoleMap.put (new Integer (AccessibleRole.PASSWORD_TEXT), "PASSWORD_TEXT");
+ maRoleMap.put (new Integer (AccessibleRole.POPUP_MENU), "POPUP_MENU");
+ maRoleMap.put (new Integer (AccessibleRole.PUSH_BUTTON), "PUSH_BUTTON");
+ maRoleMap.put (new Integer (AccessibleRole.PROGRESS_BAR), "PROGRESS_BAR");
+ maRoleMap.put (new Integer (AccessibleRole.RADIO_BUTTON), "RADIO_BUTTON");
+ maRoleMap.put (new Integer (AccessibleRole.RADIO_MENU_ITEM), "RADIO_MENU_ITEM");
+ maRoleMap.put (new Integer (AccessibleRole.ROW_HEADER), "ROW_HEADER");
+ maRoleMap.put (new Integer (AccessibleRole.ROOT_PANE), "ROOT_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.SCROLL_BAR), "SCROLL_BAR");
+ maRoleMap.put (new Integer (AccessibleRole.SCROLL_PANE), "SCROLL_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.SHAPE), "SHAPE");
+ maRoleMap.put (new Integer (AccessibleRole.SEPARATOR), "SEPARATOR");
+ maRoleMap.put (new Integer (AccessibleRole.SLIDER), "SLIDER");
+ maRoleMap.put (new Integer (AccessibleRole.SPIN_BOX), "SPIN_BOX");
+ maRoleMap.put (new Integer (AccessibleRole.SPLIT_PANE), "SPLIT_PANE");
+ maRoleMap.put (new Integer (AccessibleRole.STATUS_BAR), "STATUS_BAR");
+ maRoleMap.put (new Integer (AccessibleRole.TABLE), "TABLE");
+ maRoleMap.put (new Integer (AccessibleRole.TABLE_CELL), "TABLE_CELL");
+ maRoleMap.put (new Integer (AccessibleRole.TEXT), "TEXT");
+ maRoleMap.put (new Integer (AccessibleRole.TEXT_FRAME), "TEXT_FRAME");
+ maRoleMap.put (new Integer (AccessibleRole.TOGGLE_BUTTON), "TOGGLE_BUTTON");
+ maRoleMap.put (new Integer (AccessibleRole.TOOL_BAR), "TOOL_BAR");
+ maRoleMap.put (new Integer (AccessibleRole.TOOL_TIP), "TOOL_TIP");
+ maRoleMap.put (new Integer (AccessibleRole.TREE), "TREE");
+ maRoleMap.put (new Integer (AccessibleRole.VIEW_PORT), "VIEW_PORT");
+ maRoleMap.put (new Integer (AccessibleRole.WINDOW), "WINDOW");
+
+ maRelationMap.put (new Integer (AccessibleRelationType.INVALID), "INVALID");
+ maRelationMap.put (new Integer (AccessibleRelationType.CONTENT_FLOWS_FROM), "CONTENT_FLOWS_FROM");
+ maRelationMap.put (new Integer (AccessibleRelationType.CONTENT_FLOWS_TO), "CONTENT_FLOWS_TO");
+ maRelationMap.put (new Integer (AccessibleRelationType.CONTROLLED_BY), "CONTROLLED_BY");
+ maRelationMap.put (new Integer (AccessibleRelationType.CONTROLLER_FOR), "CONTROLLER_FOR");
+ maRelationMap.put (new Integer (AccessibleRelationType.LABEL_FOR), "LABEL_FOR");
+ maRelationMap.put (new Integer (AccessibleRelationType.LABELED_BY), "LABELED_BY");
+ maRelationMap.put (new Integer (AccessibleRelationType.MEMBER_OF), "MEMBER_OF");
+ maRelationMap.put (new Integer (AccessibleRelationType.SUB_WINDOW_OF), "SUB_WINDOW_OF");
+ }
+}
diff --git a/toolkit/test/accessibility/tools/makefile.mk b/toolkit/test/accessibility/tools/makefile.mk
new file mode 100644
index 000000000000..045ba6f65b49
--- /dev/null
+++ b/toolkit/test/accessibility/tools/makefile.mk
@@ -0,0 +1,42 @@
+# copied from settings.mk
+SOLARBINDIR=$(SOLARVERSION)$/$(INPATH)$/bin$(UPDMINOREXT)
+
+# Please modify the following lines to match your environment:
+# If you use the run: target at the end of the file, then adapt port number.
+PORT_NUMBER = 5678
+
+# The following variables probably don't need to be changed.
+JAVAC = javac
+JAVA = java
+# The JAR_PATH points to the jar files of your local office installation.
+JAR_PATH = $(SOLARBINDIR)$/
+
+
+# The rest of this makefile should not need to be touched.
+
+all : tools
+
+JAR_FILES = \
+ unoil.jar \
+ ridl.jar \
+ jurt.jar \
+ juh.jar \
+ java_uno.jar
+
+JAVA_FILES = \
+ tools/NameProvider.java
+
+
+JAVA_CLASSPATHS := \
+ . .. \
+ $(foreach,i,$(JAR_FILES) $(JAR_PATH)$i) \
+ $(CLASSPATH)
+
+CLASSPATH !:=$(JAVA_CLASSPATHS:t$(PATH_SEPERATOR))
+
+JFLAGS = -deprecation -classpath $(CLASSPATH)
+
+%.class : %.java
+ $(JAVAC) $(JFLAGS) $<
+
+tools : $(JAVA_FILES:b:+".class")