summaryrefslogtreecommitdiff
path: root/accessibility/workben/org/openoffice/accessibility/awb/tree
diff options
context:
space:
mode:
Diffstat (limited to 'accessibility/workben/org/openoffice/accessibility/awb/tree')
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityModel.java154
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityNode.java163
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTree.java89
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTreeModel.java217
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityModel.java123
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityNode.java92
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/Makefile40
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/ToolkitNode.java215
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.common35
-rw-r--r--accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.mk51
10 files changed, 1179 insertions, 0 deletions
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityModel.java b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityModel.java
new file mode 100644
index 000000000000..159467778554
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityModel.java
@@ -0,0 +1,154 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.accessibility.awb.tree;
+
+import javax.swing.SwingUtilities;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.awt.XExtendedToolkit;
+import com.sun.star.awt.XTopWindow;
+import com.sun.star.awt.XTopWindowListener;
+import com.sun.star.accessibility.AccessibleRole;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleEventBroadcaster;
+import com.sun.star.accessibility.XAccessibleEventListener;
+
+/**
+ *
+ */
+public abstract class AccessibilityModel extends javax.swing.tree.DefaultTreeModel {
+
+ protected java.util.Hashtable nodeList;
+ protected static DefaultMutableTreeNode disconnectedRootNode =
+ new DefaultMutableTreeNode("<not connected>");
+
+ /** Creates a new instance of AccessibilityModel */
+ public AccessibilityModel() {
+ super(disconnectedRootNode, false);
+ nodeList = new java.util.Hashtable();
+ }
+
+ /* Convenience method that creates a new Toolkit node from xToolkit
+ * and sets as the new root object of the tree.
+ */
+ public synchronized void setRoot(XExtendedToolkit xToolkit) {
+ if (xToolkit != null) {
+ try {
+ // remove old root node as topwindow listener
+ if (getRoot() instanceof ToolkitNode) {
+ ToolkitNode tn = (ToolkitNode) getRoot();
+ if (tn.xToolkit != null) {
+ tn.xToolkit.removeTopWindowListener(tn);
+ }
+ }
+ nodeList.clear();
+ setRoot(new ToolkitNode(xToolkit, this));
+ xToolkit.addTopWindowListener((ToolkitNode) getRoot());
+ } catch (com.sun.star.uno.RuntimeException e) {
+ // FIXME: error message !
+ }
+ }
+ }
+
+ /* Appends the new child to parent's child list */
+ public void addNodeInto(MutableTreeNode newChild, MutableTreeNode parent) {
+ int index = parent.getChildCount();
+ if (newChild != null && newChild.getParent() == parent) {
+ index -= 1;
+ }
+ insertNodeInto(newChild, parent, index);
+ }
+
+ /** Adds listener to the listener chain of node */
+ public static void addEventListener(TreeNode node, XAccessibleEventListener listener) {
+ if (node instanceof AccessibilityNode) {
+ ((AccessibilityNode) node).addEventListener(listener);
+ }
+ }
+
+ /** Removes listener from the listener chain of node */
+ public static void removeEventListener(TreeNode node, XAccessibleEventListener listener) {
+ if (node instanceof AccessibilityNode) {
+ ((AccessibilityNode) node).removeEventListener(listener);
+ }
+ }
+
+ protected abstract AccessibilityNode createWindowNode(XAccessible xAccessible,
+ XAccessibleContext xAccessibleContext);
+ protected abstract AccessibilityNode createNode(XAccessible xAccessible);
+
+ /** Adds xAccessible,node to the internal hashtable */
+ public AccessibilityNode putNode(XAccessible xAccessible, AccessibilityNode node) {
+ if (xAccessible != null) {
+ String oid = UnoRuntime.generateOid(xAccessible);
+ java.lang.ref.WeakReference ref = (java.lang.ref.WeakReference)
+ nodeList.put(oid, new java.lang.ref.WeakReference(node));
+ if (ref != null) {
+ return (AccessibilityNode) ref.get();
+ }
+ }
+ return null;
+ }
+
+ /** Returns the AccessibilityNode for xAccessible */
+ public AccessibilityNode findNode(XAccessible xAccessible) {
+ if (xAccessible != null) {
+ String oid = UnoRuntime.generateOid(xAccessible);
+ java.lang.ref.WeakReference ref =
+ (java.lang.ref.WeakReference) nodeList.get(oid);
+ if (ref != null) {
+ return (AccessibilityNode) ref.get();
+ }
+ }
+ return null;
+ }
+
+ /** Removes the AccessibilityNode for xAccessible from the internal hashtable */
+ public AccessibilityNode removeNode(XAccessible xAccessible) {
+ if (xAccessible != null) {
+ String oid = UnoRuntime.generateOid(xAccessible);
+ java.lang.ref.WeakReference ref =
+ (java.lang.ref.WeakReference) nodeList.remove(oid);
+ if (ref != null) {
+ return (AccessibilityNode) ref.get();
+ }
+ }
+ return null;
+ }
+
+ public AccessibilityNode removeNode(Object o) {
+ if (o instanceof XAccessible) {
+ return removeNode((XAccessible) o);
+ }
+ return null;
+ }
+}
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityNode.java b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityNode.java
new file mode 100644
index 000000000000..81a499aabf0d
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityNode.java
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.accessibility.awb.tree;
+
+import org.openoffice.accessibility.misc.AccessibleEventMulticaster;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.SwingUtilities;
+
+import com.sun.star.accessibility.AccessibleEventId;
+import com.sun.star.accessibility.AccessibleEventObject;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+import com.sun.star.accessibility.XAccessibleEventBroadcaster;
+import com.sun.star.accessibility.XAccessibleEventListener;
+
+import com.sun.star.uno.UnoRuntime;
+
+class AccessibilityNode extends DefaultMutableTreeNode implements XAccessible,
+ XAccessibleEventListener, XAccessibleEventBroadcaster {
+
+ protected AccessibilityModel treeModel;
+ protected XAccessibleContext unoAccessibleContext;
+
+ private XAccessibleEventListener listener;
+
+ public AccessibilityNode(AccessibilityModel treeModel) {
+ this.treeModel = treeModel;
+ }
+
+ protected void finalize() throws java.lang.Throwable {
+ if (userObject != null) {
+ treeModel.removeNode(userObject);
+ }
+ }
+
+ /** Sets the XAccessibleContext object of this node */
+ public void setAccessibleContext(XAccessibleContext xAccessibleContext) {
+ unoAccessibleContext = xAccessibleContext;
+ }
+
+ /** Returns the XAccessibleContext object of this node */
+ public XAccessibleContext getAccessibleContext() {
+ return unoAccessibleContext;
+ }
+
+ /** Attaches or Detaches the itself as listener to unoAccessibleContext */
+ protected void setAttached(boolean attach) {
+ XAccessibleContext xAccessibleContext = unoAccessibleContext;
+ if (xAccessibleContext != null) {
+ try {
+ XAccessibleEventBroadcaster xAccessibleEventBroadcaster =
+ UnoRuntime.queryInterface( XAccessibleEventBroadcaster.class, xAccessibleContext );
+ if (xAccessibleEventBroadcaster != null) {
+ if (attach) {
+ xAccessibleEventBroadcaster.addEventListener(this);
+ } else {
+ xAccessibleEventBroadcaster.removeEventListener(this);
+ }
+ }
+ } catch (com.sun.star.uno.RuntimeException e) {
+ // FIXME: error message !
+ }
+ }
+ }
+
+ public void disposing(com.sun.star.lang.EventObject eventObject) {
+ XAccessibleEventListener localListener = this.listener;
+ if (localListener != null) {
+ localListener.disposing(eventObject);
+ }
+
+ treeModel.removeNode(userObject);
+ userObject = null;
+ unoAccessibleContext = null;
+ // FIXME: mark the object as being disposed in the tree view !
+ }
+
+ protected void handleChildRemoved(XAccessible xAccessible) {
+ final AccessibilityNode node = treeModel.findNode(xAccessible);
+ if (node != null) {
+ SwingUtilities.invokeLater(new java.lang.Runnable() {
+ public void run() {
+ treeModel.removeNodeFromParent(node);
+ }
+ });
+ }
+ }
+
+ protected void handleChildAdded(XAccessible xAccessible) {
+ final AccessibilityNode parent = this;
+ final AccessibilityNode node = treeModel.createNode(xAccessible);
+ if (node != null) {
+ SwingUtilities.invokeLater(new java.lang.Runnable() {
+ public void run() {
+ try {
+ XAccessibleContext xAC = node.getAccessibleContext();
+ if (xAC != null) {
+ treeModel.insertNodeInto(node, parent,
+ xAC.getAccessibleIndexInParent());
+ }
+ } catch (com.sun.star.uno.RuntimeException e) {
+ // FIXME: output
+ }
+ }
+ });
+ }
+ }
+
+ public void notifyEvent(AccessibleEventObject accessibleEventObject) {
+ if (accessibleEventObject.EventId == AccessibleEventId.CHILD) {
+ XAccessible xAccessible = UnoRuntime.queryInterface( XAccessible.class, accessibleEventObject.OldValue );
+ if (xAccessible != null) {
+ handleChildRemoved(xAccessible);
+ }
+
+ xAccessible = UnoRuntime.queryInterface( XAccessible.class, accessibleEventObject.NewValue );
+ if (xAccessible != null) {
+ handleChildAdded(xAccessible);
+ }
+ }
+
+ XAccessibleEventListener localListener = this.listener;
+ if (localListener != null) {
+ localListener.notifyEvent(accessibleEventObject);
+ }
+ }
+
+ public synchronized void addEventListener(com.sun.star.accessibility.XAccessibleEventListener xAccessibleEventListener) {
+ listener = AccessibleEventMulticaster.add(listener, xAccessibleEventListener);
+ }
+
+ public synchronized void removeEventListener(com.sun.star.accessibility.XAccessibleEventListener xAccessibleEventListener) {
+ listener = AccessibleEventMulticaster.remove(listener, xAccessibleEventListener);
+ }
+}
+
+
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTree.java b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTree.java
new file mode 100644
index 000000000000..e485c993706a
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTree.java
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.accessibility.awb.tree;
+
+import org.openoffice.accessibility.misc.NameProvider;
+
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import com.sun.star.awt.XExtendedToolkit;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+
+/**
+ *
+ */
+public class AccessibilityTree extends javax.swing.JTree {
+
+ /** Creates a new instance of AccessibilityTree */
+ public AccessibilityTree(javax.swing.tree.TreeModel model) {
+ super(model);
+ // always show handles to indicate expandable / collapsable
+ showsRootHandles = true;
+ }
+
+ public void setToolkit(XExtendedToolkit xToolkit) {
+ AccessibilityModel model = (AccessibilityModel) getModel();
+ if (model != null) {
+ // hide the root node when connected
+ setRootVisible(xToolkit == null);
+ // update the root node
+ model.setRoot(xToolkit);
+ model.reload();
+ }
+ }
+
+ public String convertValueToText(Object value, boolean selected,
+ boolean expanded, boolean leaf, int row, boolean hasFocus) {
+
+ if (value instanceof DefaultMutableTreeNode) {
+ DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
+
+ Object userObject = node.getUserObject();
+ if (userObject != null && userObject instanceof XAccessible) {
+ XAccessible xAccessible = (XAccessible) userObject;
+ try {
+ XAccessibleContext xAC = xAccessible.getAccessibleContext();
+ if (xAC != null) {
+ String name = xAC.getAccessibleName();
+ if (name.length() == 0) {
+ name = new String ("<no name>");
+ }
+ value = name + " / " + NameProvider.getRoleName(xAC.getAccessibleRole());
+ }
+ } catch (com.sun.star.uno.RuntimeException e) {
+ value = "???";
+ }
+ }
+ }
+
+ return super.convertValueToText(value, selected, expanded, leaf, row, hasFocus);
+ }
+
+}
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTreeModel.java b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTreeModel.java
new file mode 100644
index 000000000000..6069c8f5f5ee
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/AccessibilityTreeModel.java
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.accessibility.awb.tree;
+
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.awt.XExtendedToolkit;
+import com.sun.star.lang.DisposedException;
+import com.sun.star.lang.IndexOutOfBoundsException;
+
+import org.openoffice.accessibility.misc.OfficeConnection;
+import org.openoffice.accessibility.awb.event.EventQueue;
+
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+
+
+public class AccessibilityTreeModel
+ extends DefaultTreeModel
+{
+ public AccessibilityTreeModel ()
+ {
+ super (null);
+ setAsksAllowsChildren (false);
+
+ SetRootNode();
+ }
+
+
+
+ /** Release all resources.
+ */
+ synchronized public void Dispose ()
+ {
+ Clear ();
+ }
+
+
+
+ /** Calls to this method are dispatched to the given node but are
+ observed for exceptions.
+ */
+ synchronized public boolean isLeaf (Object aObject)
+ {
+ boolean bIsLeaf = true;
+
+ if (aObject != null)
+ {
+ AccessibilityNode aNode = (AccessibilityNode)aObject;
+ try
+ {
+ bIsLeaf = aNode.isLeaf();
+ }
+ catch (DisposedException aException)
+ {
+ System.out.println ("node is disposed. removing it");
+ /* TreeNode aParent = aNode.GetParent();
+ int nIndexInParent = aParent.getIndex (aNode);
+ aNode.removeFromParent ();
+ System.out.println ("" + aParent + " # " + aNode + " # "+ nIndexInParent);
+ nodesWereRemoved (
+ aParent, new int[]{nIndexInParent}, new
+ Object[]{aNode});
+ */
+ }
+ catch (Exception aException)
+ {
+ System.err.println ("caught exception in AccessibilityTreeModel.isLeaf():"
+ + aException);
+ aException.printStackTrace (System.err);
+ }
+ }
+
+ return bIsLeaf;
+ }
+
+
+
+
+ synchronized public int getChildCount (Object aObject)
+ {
+ AccessibilityNode aNode = (AccessibilityNode)aObject;
+ return aNode.getChildCount();
+ }
+
+
+
+
+ /** Return the requested child of aParent. If that child is not yet
+ known to the parent then try to create it.
+ */
+ synchronized public Object getChild (Object aParent, final int nIndex)
+ {
+ AccessibilityNode aChild = null;
+
+ final AccessibilityNode aParentNode = (AccessibilityNode)aParent;
+
+ // Try to get an existing child from the super class object.
+ aChild = aParentNode.GetChildNoCreate (nIndex);
+
+ // When the requested child does not yet exist and this node is not a
+ // special node then create a new node.
+ if (aChild == null)
+ {
+ aChild = aParentNode.CreateChild (nIndex);
+ aParentNode.SetChild ((AccessibilityNode)aChild, nIndex);
+ /* EventQueue.Instance().AddEvent (new Runnable() { public void run() {
+ AccessibilityTreeModel.this.nodeWasInserted (
+ aParentNode, nIndex);
+ }});
+ */ }
+
+ return aChild;
+ }
+
+
+ synchronized public void nodeWasInserted (AccessibilityNode aParent, int nIndex)
+ {
+ nodesWereInserted (aParent, new int[]{nIndex});
+ nodeStructureChanged (aParent);
+
+ }
+
+
+
+
+ /** Clear the tree so that afterwards it has only the root node.
+ */
+ public void Clear ()
+ {
+ AccessibilityNode aRoot = (AccessibilityNode)getRoot();
+ aRoot.RemoveAllChildren();
+ SetRootNode();
+ nodeStructureChanged (aRoot);
+ }
+
+
+
+
+ private void SetRootNode ()
+ {
+ OfficeConnection aConnection = OfficeConnection.Instance();
+ AccessibilityNode aRoot;
+ if (aConnection!=null && aConnection.IsValid())
+ aRoot = new AccessibilityNode ("<connected>");
+ else
+ aRoot = new AccessibilityNode ("<not connected>");
+ setRoot (aRoot);
+ }
+
+
+
+
+ /** Add a new child to the root node.
+ */
+ public synchronized void AddTopLevelNode (AccessibilityNode aNode)
+ {
+ if (aNode != null)
+ {
+ if ( ! OfficeConnection.Instance().IsValid())
+ {
+ setRoot (null);
+ }
+
+ AccessibilityNode aRoot = (AccessibilityNode)getRoot();
+ if (aRoot == null)
+ {
+ aRoot = new AccessibilityNode ("<connected>");
+ setRoot (aRoot);
+ }
+
+ aNode.SetParent (aRoot);
+ aRoot.Append (aNode);
+ nodesWereInserted (aRoot, new int[]{aRoot.getIndex (aNode)});
+ }
+ }
+
+
+
+
+ /** Remove a node that is a direct child of the root.
+ */
+ public synchronized void RemoveTopLevelNode (AccessibilityNode aNode)
+ {
+ AccessibilityNode aRoot = (AccessibilityNode)getRoot();
+ if (aRoot != null)
+ {
+ int nIndex = aRoot.getIndex (aNode);
+ aRoot.Remove (aNode);
+ nodesWereRemoved (aRoot, new int[]{nIndex}, new Object[]{aNode});
+ }
+ }
+}
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityModel.java b/accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityModel.java
new file mode 100644
index 000000000000..f2b4c6f0e97f
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityModel.java
@@ -0,0 +1,123 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.accessibility.awb.tree;
+
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.MutableTreeNode;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.event.TreeExpansionListener;
+import javax.swing.event.TreeWillExpandListener;
+
+import com.sun.star.accessibility.AccessibleRole;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+
+/**
+ *
+ */
+public class DynamicAccessibilityModel extends AccessibilityModel implements TreeExpansionListener, TreeWillExpandListener {
+
+ /* Creates a AccessibilityNode object for a window */
+ protected AccessibilityNode createWindowNode(XAccessible xAccessible,
+ XAccessibleContext xAccessibleContext) {
+ if (xAccessible != null) {
+ // Some objects inherit XAccessible, but should not appear in
+ // the hierarchy as toplevels (like sub-menus), so they don't
+ // return an accessible context.
+ if (xAccessibleContext != null) {
+ AccessibilityNode node = new AccessibilityNode(this);
+ node.setUserObject(xAccessible);
+ node.setAccessibleContext(xAccessibleContext);
+ putNode(xAccessible, node);
+ return node;
+ }
+ }
+ return null;
+ }
+
+ /* Creates a DynamicAccessibilityNode object */
+ protected AccessibilityNode createNode(XAccessible xAccessible) {
+ if (xAccessible != null) {
+ try {
+ // Some objects inherit XAccessible, but should not appear in
+ // the hierarchy as toplevels (like sub-menus), so they don't
+ // return an accessible context.
+ XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext();
+ if (xAccessibleContext != null) {
+ AccessibilityNode node = new DynamicAccessibilityNode(this);
+ node.setUserObject(xAccessible);
+ node.setAccessibleContext(xAccessibleContext);
+ putNode(xAccessible, node);
+ return node;
+ }
+ } catch (com.sun.star.uno.RuntimeException e) {
+ }
+ }
+ return null;
+ }
+
+ public void treeCollapsed(javax.swing.event.TreeExpansionEvent treeExpansionEvent) {
+ TreeNode node = (TreeNode) treeExpansionEvent.getPath().getLastPathComponent();
+ if (node instanceof DynamicAccessibilityNode) {
+ DynamicAccessibilityNode dynode = (DynamicAccessibilityNode) node;
+ dynode.clear();
+ }
+ }
+
+ public void treeExpanded(javax.swing.event.TreeExpansionEvent treeExpansionEvent) {
+ TreeNode node = (TreeNode) treeExpansionEvent.getPath().getLastPathComponent();
+ if (node instanceof AccessibilityNode) {
+ // Calling oneway methods from an UNO thread may cause
+ // deadlocks, so adding the listeners here.
+ for (java.util.Enumeration e = node.children(); e.hasMoreElements(); ) {
+ ((AccessibilityNode) e.nextElement()).setAttached(true);
+ }
+ }
+ }
+
+ public void treeWillCollapse(javax.swing.event.TreeExpansionEvent treeExpansionEvent)
+ throws javax.swing.tree.ExpandVetoException {
+ TreeNode node = (TreeNode) treeExpansionEvent.getPath().getLastPathComponent();
+ if (node instanceof AccessibilityNode) {
+ // Calling oneway methods from an UNO thread may cause
+ // deadlocks, so adding the listeners here.
+ for (java.util.Enumeration e = node.children(); e.hasMoreElements(); ) {
+ ((AccessibilityNode) e.nextElement()).setAttached(false);
+ }
+ }
+ }
+
+ public void treeWillExpand(javax.swing.event.TreeExpansionEvent treeExpansionEvent)
+ throws javax.swing.tree.ExpandVetoException {
+ TreeNode node = (TreeNode) treeExpansionEvent.getPath().getLastPathComponent();
+ if (node instanceof DynamicAccessibilityNode) {
+ DynamicAccessibilityNode dynode = (DynamicAccessibilityNode) node;
+ dynode.populate();
+ }
+ }
+}
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityNode.java b/accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityNode.java
new file mode 100644
index 000000000000..a982ad71c4d5
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/DynamicAccessibilityNode.java
@@ -0,0 +1,92 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.accessibility.awb.tree;
+
+import com.sun.star.uno.UnoRuntime;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+
+/*
+ * This class is dynamic in the way that it does not contain any children
+ * until the node is going to be expanded. It also releases all children
+ * as soon as the node is collapsed again.
+ */
+class DynamicAccessibilityNode extends AccessibilityNode {
+
+ public DynamicAccessibilityNode(AccessibilityModel treeModel) {
+ super(treeModel);
+ }
+
+ // Populates the child list. Called by AccessibilityMode.treeWillExpand().
+ protected void populate() {
+ try {
+ XAccessibleContext xAC = getAccessibleContext();
+ if (xAC != null) {
+ int n = xAC.getAccessibleChildCount();
+ for (int i=0; i<n; i++) {
+ XAccessible xAccessible = xAC.getAccessibleChild(i);
+ AccessibilityNode node = treeModel.findNode(xAccessible);
+ if (node == null) {
+ node = treeModel.createNode(xAccessible);
+ }
+ if (node != null) {
+ // NOTE: do not send any tree notifications here !
+ add(node);
+ }
+ }
+ }
+ } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
+ // This should never happen since we previously checked the child
+ // count.
+ // FIXME: error message
+ } catch (com.sun.star.uno.RuntimeException e) {
+ // FIXME: error message
+ }
+ }
+
+ // Clears the child list. Called by AccessibilityModel.treeCollapsed().
+ protected void clear() {
+ removeAllChildren();
+ }
+
+ /* This is called whenever the node is painted, no matter if collapsed
+ * or expanded. Making this a "life" value seems to be appropriate.
+ */
+ public boolean isLeaf() {
+ try {
+ XAccessibleContext xAC = getAccessibleContext();
+ if (xAC != null) {
+ return xAC.getAccessibleChildCount() == 0;
+ }
+ return true;
+ } catch (com.sun.star.uno.RuntimeException e) {
+ return true;
+ }
+ }
+
+}
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/Makefile b/accessibility/workben/org/openoffice/accessibility/awb/tree/Makefile
new file mode 100644
index 000000000000..579b8822ce76
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/Makefile
@@ -0,0 +1,40 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+all : package
+
+ROOT=../../../../..
+PACKAGE = org.openoffice.accessibility.awb.tree
+SUBDIRS =
+include makefile.common
+
+include $(ROOT)/makefile.in
+
+
+package : $(CLASS_FILES)
+
+
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/ToolkitNode.java b/accessibility/workben/org/openoffice/accessibility/awb/tree/ToolkitNode.java
new file mode 100644
index 000000000000..8eaa9dab6c02
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/ToolkitNode.java
@@ -0,0 +1,215 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+package org.openoffice.accessibility.awb.tree;
+
+import com.sun.star.accessibility.AccessibleRole;
+import com.sun.star.accessibility.XAccessible;
+import com.sun.star.accessibility.XAccessibleContext;
+
+import com.sun.star.awt.XExtendedToolkit;
+import com.sun.star.awt.XTopWindow;
+
+import com.sun.star.uno.UnoRuntime;
+
+import javax.swing.SwingUtilities;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+/**
+ *
+ */
+public class ToolkitNode extends DefaultMutableTreeNode
+ implements com.sun.star.awt.XTopWindowListener {
+
+ protected XExtendedToolkit xToolkit;
+
+ private AccessibilityModel treeModel;
+
+ /** Creates a new instance of TopWindowListener */
+ public ToolkitNode(XExtendedToolkit xToolkit, AccessibilityModel treeModel) {
+ super("<connected>");
+ this.xToolkit = xToolkit;
+ this.treeModel = treeModel;
+
+ // Initially fill the child list
+ try {
+ for (int i=0,j=xToolkit.getTopWindowCount(); i<j; i++) {
+ XTopWindow xTopWindow = xToolkit.getTopWindow(i);
+ if (xTopWindow != null) {
+ AccessibilityNode an = getTopWindowNode(xTopWindow);
+ if (an != null) {
+ add(an);
+ // Calling oneway methods from an UNO thread may cause
+ // deadlocks, so adding the listeners here.
+ an.setAttached(true);
+ }
+ }
+ }
+ } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
+ // This should never happen since we properly check the count
+ // before - anyway returning what we got so far.
+ }
+ }
+
+ /** Returns an AccessibilityNode if xAccessible has a valid toplevel */
+ private AccessibilityNode getTopWindowNode(XAccessible xAccessible) {
+ XAccessibleContext xAC = xAccessible.getAccessibleContext();
+ if (xAC != null) {
+ short role = xAC.getAccessibleRole();
+ if ((role == AccessibleRole.FRAME) || (role == AccessibleRole.DIALOG) || (role == AccessibleRole.WINDOW)) {
+ return treeModel.createWindowNode(xAccessible, xAC);
+ }
+ }
+ return null;
+ }
+
+ /** Returns an AccessibilityNode if xAccessible has a valid toplevel */
+ private AccessibilityNode getTopWindowNode(XAccessible xAccessible, XAccessibleContext xAC) {
+ if (xAC != null) {
+ short role = xAC.getAccessibleRole();
+ if ((role == AccessibleRole.FRAME) || (role == AccessibleRole.DIALOG) || (role == AccessibleRole.WINDOW)) {
+ AccessibilityNode parent = treeModel.createWindowNode(xAccessible, xAC);
+ if (parent != null) {
+ try {
+ int n = xAC.getAccessibleChildCount();
+ for (int i=0; i<n; i++) {
+ AccessibilityNode child = treeModel.createNode(xAC.getAccessibleChild(i));
+ if (child != null) {
+ parent.add(child);
+ }
+ }
+ } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
+
+ }
+ }
+ return parent;
+ }
+ }
+ return null;
+ }
+
+ /** Returns the XAccessible interface corresponding to the toplevel window */
+ private AccessibilityNode getTopWindowNode(XTopWindow w) {
+ XAccessible xAccessible = (XAccessible)
+ UnoRuntime.queryInterface(XAccessible.class, w);
+ if (xAccessible != null) {
+ // XTopWindows usually have an accessible parent, which is the
+ // native container window ..
+ XAccessibleContext xAC = xAccessible.getAccessibleContext();
+ if (xAC != null) {
+ XAccessible xParent = xAC.getAccessibleParent();
+ if (xParent != null) {
+ AccessibilityNode parent = getTopWindowNode(xParent);
+ AccessibilityNode child = treeModel.createNode(xAccessible);
+ if (parent != null && child != null) {
+ parent.add(child);
+ }
+ return parent;
+ } else {
+ return getTopWindowNode(xAccessible, xAC);
+ }
+ }
+ }
+ return null;
+ }
+
+ public void disposing(com.sun.star.lang.EventObject eventObject) {
+ // FIXME : message
+ // prevent setRoot from removing this as event listener
+ xToolkit = null;
+ treeModel.setRoot(treeModel.disconnectedRootNode);
+ }
+
+ public void windowActivated(com.sun.star.lang.EventObject eventObject) {
+ }
+
+ public void windowClosed(com.sun.star.lang.EventObject eventObject) {
+ XAccessible xAccessible = (XAccessible) UnoRuntime.queryInterface(
+ XAccessible.class, eventObject.Source);
+ if (xAccessible != null) {
+ AccessibilityNode node = treeModel.findNode(xAccessible);
+
+ // The object implementing XTopWindow is often not the toplevel
+ // accessible object.
+ if (node != null && node.getParent() != this) {
+ node = (AccessibilityNode) node.getParent();
+ }
+
+ if (node != null) {
+ final AccessibilityNode an = node;
+ Runnable removeRun = new Runnable() {
+ public void run() {
+ try {
+ treeModel.removeNodeFromParent(an);
+ // Calling oneway methods from an UNO thread may cause
+ // deadlocks, so removing the listeners here.
+ an.setAttached(false);
+ } catch (IllegalArgumentException e) {
+ // for some toplevel we get more than one event -
+ // ignoring
+ }
+ }
+ };
+ SwingUtilities.invokeLater(removeRun);
+ }
+ }
+ }
+
+ public void windowClosing(com.sun.star.lang.EventObject eventObject) {
+ }
+
+ public void windowDeactivated(com.sun.star.lang.EventObject eventObject) {
+ }
+
+ public void windowMinimized(com.sun.star.lang.EventObject eventObject) {
+ }
+
+ public void windowNormalized(com.sun.star.lang.EventObject eventObject) {
+ }
+
+ public void windowOpened(com.sun.star.lang.EventObject eventObject) {
+ final XTopWindow xTopWindow = (XTopWindow) UnoRuntime.queryInterface(
+ XTopWindow.class, eventObject.Source);
+ if (xTopWindow != null) {
+ final ToolkitNode tn = this;
+ Runnable addNodeRun = new Runnable() {
+ public void run() {
+ // Note: UNO does not allow to make synchronous callbacks
+ // to oneway calls, so we have to fetch the node here.
+ AccessibilityNode an = getTopWindowNode(xTopWindow);
+ if (an != null) {
+ treeModel.addNodeInto(an, tn);
+ // Calling oneway methods from an UNO thread may cause
+ // deadlocks, so adding the listeners here.
+ an.setAttached(true);
+ }
+ }
+ };
+ SwingUtilities.invokeLater(addNodeRun);
+ }
+ }
+}
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.common b/accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.common
new file mode 100644
index 000000000000..e44be51360e7
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.common
@@ -0,0 +1,35 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+JARFILES = jurt.jar unoil.jar ridl.jar
+JAVAFILES = \
+ AccessibilityModel.java \
+ AccessibilityNode.java \
+ AccessibilityTree.java \
+ DynamicAccessibilityModel.java \
+ DynamicAccessibilityNode.java \
+ ToolkitNode.java
diff --git a/accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.mk b/accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.mk
new file mode 100644
index 000000000000..0135ca9d6422
--- /dev/null
+++ b/accessibility/workben/org/openoffice/accessibility/awb/tree/makefile.mk
@@ -0,0 +1,51 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJNAME = awb
+PRJ = ..$/..$/..$/..$/..$/..
+TARGET = java_tree
+PACKAGE = org$/openoffice$/accessibility$/awb$/tree
+
+USE_JAVAVER:=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+.IF "$(JAVAVER:s/.//)" >= "140"
+
+.INCLUDE : makefile.common
+
+JAVACLASSFILES= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+