summaryrefslogtreecommitdiff
path: root/accessibility/bridge/org/openoffice/java/accessibility/AccessibleObjectFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'accessibility/bridge/org/openoffice/java/accessibility/AccessibleObjectFactory.java')
-rw-r--r--accessibility/bridge/org/openoffice/java/accessibility/AccessibleObjectFactory.java545
1 files changed, 545 insertions, 0 deletions
diff --git a/accessibility/bridge/org/openoffice/java/accessibility/AccessibleObjectFactory.java b/accessibility/bridge/org/openoffice/java/accessibility/AccessibleObjectFactory.java
new file mode 100644
index 000000000000..129a3b820993
--- /dev/null
+++ b/accessibility/bridge/org/openoffice/java/accessibility/AccessibleObjectFactory.java
@@ -0,0 +1,545 @@
+/*************************************************************************
+ *
+ * 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.java.accessibility;
+
+import java.lang.ref.WeakReference;
+import javax.accessibility.Accessible;
+import javax.accessibility.AccessibleStateSet;
+
+import com.sun.star.uno.*;
+import com.sun.star.accessibility.*;
+import org.openoffice.java.accessibility.logging.XAccessibleEventLog;
+
+/**
+*/
+public class AccessibleObjectFactory {
+ // This type is needed for conversions from/to uno Any
+ public static final Type XAccessibleType = new Type(XAccessible.class);
+
+ private static java.util.Hashtable objectList = new java.util.Hashtable();
+ private static java.awt.FocusTraversalPolicy focusTraversalPolicy = new FocusTraversalPolicy();
+
+ private static java.awt.EventQueue theEventQueue = java.awt.Toolkit.getDefaultToolkit().
+ getSystemEventQueue();
+
+ public static java.awt.EventQueue getEventQueue() {
+ return theEventQueue;
+ }
+
+ public static void postFocusGained(java.awt.Component c) {
+ getEventQueue().postEvent(new java.awt.event.FocusEvent(c, java.awt.event.FocusEvent.FOCUS_GAINED));
+ }
+
+ public static void postWindowGainedFocus(java.awt.Window w) {
+ postWindowEvent(w, java.awt.event.WindowEvent.WINDOW_GAINED_FOCUS);
+ }
+
+ public static void postWindowLostFocus(java.awt.Window w) {
+ postWindowEvent(w, java.awt.event.WindowEvent.WINDOW_LOST_FOCUS);
+ }
+
+ public static void postWindowActivated(java.awt.Window w) {
+ postWindowEvent(w, java.awt.event.WindowEvent.WINDOW_ACTIVATED);
+ }
+
+ public static void postWindowDeactivated(java.awt.Window w) {
+ postWindowEvent(w, java.awt.event.WindowEvent.WINDOW_DEACTIVATED);
+ }
+
+ public static void postWindowOpened(java.awt.Window w) {
+ postWindowEvent(w, java.awt.event.WindowEvent.WINDOW_OPENED);
+ }
+
+ public static void postWindowClosed(java.awt.Window w) {
+ postWindowEvent(w, java.awt.event.WindowEvent.WINDOW_CLOSED);
+ }
+
+ public static void invokeAndWait() {
+ try {
+ theEventQueue.invokeAndWait( new java.lang.Runnable () {
+ public void run() {
+ }
+ });
+ } catch (java.lang.reflect.InvocationTargetException e) {
+ } catch (java.lang.InterruptedException e) {
+ }
+ }
+
+ private static void postWindowEvent(java.awt.Window w, int i) {
+ theEventQueue.postEvent(new java.awt.event.WindowEvent(w, i));
+ }
+
+ public static java.awt.Component getAccessibleComponent(XAccessible xAccessible) {
+ java.awt.Component c = null;
+ if (xAccessible != null) {
+ // Retrieve unique id for the original UNO object to be used as a hash key
+ String oid = UnoRuntime.generateOid(xAccessible);
+
+ // Check if we already have a wrapper object for this context
+ synchronized (objectList) {
+ WeakReference r = (WeakReference) objectList.get(oid);
+ if(r != null) {
+ c = (java.awt.Component) r.get();
+ }
+ }
+ }
+ return c;
+ }
+
+ public static void addChild(java.awt.Container parent, Object any) {
+ try {
+ addChild(parent, (XAccessible) AnyConverter.toObject(XAccessibleType, any));
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ System.err.println(e.getClass().getName() + " caught: " + e.getMessage());
+ }
+ }
+
+ public static void addChild(java.awt.Container parent, XAccessible child) {
+ try {
+ if (child != null) {
+ XAccessibleContext childAC = child.getAccessibleContext();
+ if (childAC != null) {
+ XAccessibleStateSet stateSet = childAC.getAccessibleStateSet();
+ if (stateSet != null) {
+ java.awt.Component c = getAccessibleComponent(child);
+
+ // Re-use existing wrapper if possible, create a new one otherwise
+ if (c != null) {
+ // Seems to be already in child list
+ if (parent.equals(c.getParent()))
+ return;
+ // Update general component states
+ c.setEnabled(stateSet.contains(AccessibleStateType.ENABLED));
+ c.setVisible(stateSet.contains(AccessibleStateType.VISIBLE));
+ } else {
+ c = createAccessibleComponentImpl(child, childAC, stateSet);
+ }
+
+ if (c != null) {
+ if (c instanceof java.awt.Container) {
+ populateContainer((java.awt.Container) c, childAC);
+ }
+ parent.add(c);
+ // Simulate focus gained event for new child
+ if (stateSet.contains(AccessibleStateType.FOCUSED)) {
+ postFocusGained(c);
+ }
+ }
+ }
+ }
+ }
+ } catch (com.sun.star.uno.RuntimeException e) {
+ System.err.println(e.getClass().getName() + " caught: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ protected static void removeChild(java.awt.Container parent, Object any) {
+ try {
+ XAccessible xAccessible = (XAccessible) AnyConverter.toObject(XAccessibleType, any);
+ java.awt.Component c = getAccessibleComponent(xAccessible);
+
+ if (c != null) {
+ parent.remove(c);
+
+ if (c instanceof java.awt.Container) {
+ clearContainer((java.awt.Container) c);
+ }
+ }
+ } catch (com.sun.star.lang.IllegalArgumentException e) {
+ System.err.println(e.getClass().getName() + " caught: " + e.getMessage());
+ }
+ }
+
+
+ /**
+ * Removes all children from the container parent
+ */
+
+ protected static void clearContainer(java.awt.Container parent) {
+ // Purge all children from this container
+ int count = parent.getComponentCount();
+ for (int i = 0; i < count; i++) {
+ java.awt.Component c = parent.getComponent(i);
+ if (c instanceof java.awt.Container) {
+ clearContainer((java.awt.Container) c);
+ }
+ }
+ parent.removeAll();
+ }
+
+
+ /**
+ * Populates the given Container parent with wrapper objects for all children of parentAC. This method is
+ * intended to be called when a container is added using a CHILDREN_CHANGED event.
+ */
+
+ protected static void populateContainer(java.awt.Container parent, XAccessibleContext parentAC) {
+ if (parentAC != null) {
+ try {
+ int childCount = parentAC.getAccessibleChildCount();
+ for (int i=0; i<childCount; i++) {
+ addChild(parent, parentAC.getAccessibleChild(i));
+ }
+ } catch (java.lang.Exception e) {
+ System.err.println(e.getClass().getName() + " caught: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Populates the given Container parent with wrapper objects for all children of parentAC. This method is
+ * intended to be called when a new window has been opened.
+ */
+ protected static void populateContainer(java.awt.Container parent, XAccessibleContext parentAC, java.awt.Window frame) {
+ if (parentAC != null) {
+ try {
+ int childCount = parentAC.getAccessibleChildCount();
+ for (int i=0; i<childCount; i++) {
+ XAccessible child = parentAC.getAccessibleChild(i);
+ if (child != null) {
+ XAccessibleContext childAC = child.getAccessibleContext();
+ java.awt.Component c = createAccessibleComponent(child, childAC, frame);
+ if (c != null) {
+ if (c instanceof java.awt.Container) {
+ populateContainer((java.awt.Container) c, childAC, frame);
+ }
+ parent.add(c);
+ }
+ } else if (Build.DEBUG) {
+ System.err.println("ignoring not accessible child " + i);
+ }
+ }
+ }
+
+ catch (java.lang.Exception e) {
+ System.err.println(e.getClass().getName() + " caught: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ }
+
+ protected static java.awt.Component createAccessibleComponent(XAccessible xAccessible) {
+ try {
+ XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext();
+ if (xAccessibleContext != null) {
+ return createAccessibleComponentImpl(xAccessible, xAccessibleContext, xAccessibleContext.getAccessibleStateSet());
+ }
+ } catch (com.sun.star.uno.RuntimeException e) {
+ System.err.println(e.getClass().getName() + " caught: " + e.getMessage());
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ protected static java.awt.Component createAccessibleComponent(XAccessible xAccessible, XAccessibleContext xAccessibleContext,
+ java.awt.Window frame) {
+ if (xAccessibleContext != null) {
+ try {
+ XAccessibleStateSet xAccessibleStateSet = xAccessibleContext.getAccessibleStateSet();
+ java.awt.Component c = createAccessibleComponentImpl(xAccessible, xAccessibleContext, xAccessibleStateSet);
+ if (c != null) {
+ // Set this component as initial component
+ if (xAccessibleStateSet.contains(AccessibleStateType.FOCUSED)) {
+ if (frame instanceof NativeFrame) {
+ ((NativeFrame) frame).setInitialComponent(c);
+ }
+ }
+ return c;
+ }
+ } catch (com.sun.star.uno.RuntimeException e) {
+ System.err.println(e.getClass().getName() + " caught: " + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ protected static java.awt.Component createAccessibleComponentImpl(XAccessible xAccessible, XAccessibleContext xAccessibleContext,
+ XAccessibleStateSet xAccessibleStateSet) {
+ java.awt.Component c = null;
+ short role = xAccessibleContext.getAccessibleRole();
+ switch (role) {
+ case AccessibleRole.CANVAS:
+ c = new Container(javax.accessibility.AccessibleRole.CANVAS,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.CHECK_BOX:
+ c = new CheckBox(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.COMBO_BOX:
+ c = new ComboBox(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.DOCUMENT:
+ c = new Container(javax.accessibility.AccessibleRole.CANVAS,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.EMBEDDED_OBJECT:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.END_NOTE:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.FILLER:
+ c = new Container(javax.accessibility.AccessibleRole.FILLER,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.FOOTNOTE:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.FOOTER:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.GRAPHIC:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.HEADER:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.ICON:
+ c = new Icon(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.LABEL:
+ c = new Label(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.LAYERED_PANE:
+ c = new Container(javax.accessibility.AccessibleRole.LAYERED_PANE,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.LIST:
+ if (xAccessibleStateSet.contains(AccessibleStateType.MANAGES_DESCENDANTS)) {
+ c = new List(xAccessible, xAccessibleContext);
+ } else {
+ c = new Container(javax.accessibility.AccessibleRole.LIST,
+ xAccessible, xAccessibleContext);
+ }
+ break;
+ case AccessibleRole.MENU:
+ c = new Menu(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.MENU_BAR:
+ c = new MenuContainer(javax.accessibility.AccessibleRole.MENU_BAR, xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.MENU_ITEM:
+ c = new MenuItem(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.POPUP_MENU:
+ c = new MenuContainer(javax.accessibility.AccessibleRole.POPUP_MENU, xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.OPTION_PANE:
+ c = new Container(javax.accessibility.AccessibleRole.OPTION_PANE,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.PAGE_TAB:
+ c = new Container(javax.accessibility.AccessibleRole.PAGE_TAB, xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.PAGE_TAB_LIST:
+ c = new Container(javax.accessibility.AccessibleRole.PAGE_TAB_LIST, xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.PARAGRAPH:
+ case AccessibleRole.HEADING:
+ c = new Paragraph(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.PANEL:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.PUSH_BUTTON:
+ c = new Button(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.RADIO_BUTTON:
+ c = new RadioButton(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.ROOT_PANE:
+ c = new Container(javax.accessibility.AccessibleRole.ROOT_PANE,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.SCROLL_BAR:
+ c = new ScrollBar(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.SCROLL_PANE:
+ c = new Container(javax.accessibility.AccessibleRole.SCROLL_PANE,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.SEPARATOR:
+ c = new Separator(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.SHAPE:
+ c = new Container(javax.accessibility.AccessibleRole.CANVAS,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.SPLIT_PANE:
+ c = new Container(javax.accessibility.AccessibleRole.SPLIT_PANE,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.STATUS_BAR:
+ c = new Container(javax.accessibility.AccessibleRole.STATUS_BAR,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.COLUMN_HEADER:
+ case AccessibleRole.TABLE:
+ if (xAccessibleStateSet.contains(AccessibleStateType.MANAGES_DESCENDANTS)) {
+ c = new Table(xAccessible, xAccessibleContext,
+ xAccessibleStateSet.contains(AccessibleStateType.MULTI_SELECTABLE));
+ } else {
+ c = new Container(javax.accessibility.AccessibleRole.TABLE,
+ xAccessible, xAccessibleContext);
+ }
+ break;
+ case AccessibleRole.TABLE_CELL:
+ if( xAccessibleContext.getAccessibleChildCount() > 0 )
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ else
+ c = new Label(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.TEXT:
+ c = new TextComponent(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.TEXT_FRAME:
+ c = new Container(javax.accessibility.AccessibleRole.PANEL,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.TOGGLE_BUTTON:
+ c = new ToggleButton(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.TOOL_BAR:
+ c = new Container(javax.accessibility.AccessibleRole.TOOL_BAR,
+ xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.TOOL_TIP:
+ c = new ToolTip(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.TREE:
+ c = new Tree(xAccessible, xAccessibleContext);
+ break;
+ case AccessibleRole.VIEW_PORT:
+ c = new Container(javax.accessibility.AccessibleRole.VIEWPORT,
+ xAccessible, xAccessibleContext);
+ break;
+ default:
+ System.err.println("Unmapped accessible object " + role);
+ System.err.println("usually mapped to " + AccessibleRoleAdapter.getAccessibleRole(role));
+ c = new Container(AccessibleRoleAdapter.getAccessibleRole(role),
+ xAccessible, xAccessibleContext);
+ break;
+ }
+ if (c != null) {
+ // Add the newly created object to the cache list
+ synchronized (objectList) {
+ objectList.put(c.toString(), new WeakReference(c));
+ if (Build.DEBUG) {
+// System.out.println("Object cache now contains " + objectList.size() + " objects.");
+ }
+ }
+
+ AccessibleStateAdapter.setComponentState(c, xAccessibleStateSet);
+
+ if (! Build.PRODUCT) {
+ String property = System.getProperty("AccessBridgeLogging");
+ if ((property != null) && (property.indexOf("event") != -1)) {
+ XAccessibleEventLog.addEventListener(xAccessibleContext, c);
+ }
+ }
+ }
+
+ return c;
+ }
+
+ protected static void disposing(java.awt.Component c) {
+ if (c != null) {
+ synchronized (objectList) {
+ objectList.remove(c.toString());
+ }
+ }
+ }
+
+ public static java.awt.Window getTopWindow(XAccessible xAccessible) {
+ XAccessibleContext xAccessibleContext = xAccessible.getAccessibleContext();
+
+ if (xAccessibleContext != null) {
+ short role = xAccessibleContext.getAccessibleRole();
+ XAccessibleStateSet xAccessibleStateSet = xAccessibleContext.getAccessibleStateSet();
+ XAccessibleComponent xAccessibleComponent = (XAccessibleComponent)
+ UnoRuntime.queryInterface(XAccessibleComponent.class, xAccessibleContext);
+
+ java.awt.Window w;
+ if (role == AccessibleRole.DIALOG) {
+ w = new Dialog(new Application(),
+ xAccessibleContext.getAccessibleName(),
+ xAccessibleStateSet.contains(AccessibleStateType.MODAL),
+ xAccessibleComponent);
+ } else if (role == AccessibleRole.ALERT) {
+ w = new Alert(new Application(),
+ xAccessibleContext.getAccessibleName(),
+ xAccessibleStateSet.contains(AccessibleStateType.MODAL),
+ xAccessibleComponent);
+ } else if (role == AccessibleRole.FRAME) {
+ w = new Frame(xAccessibleContext.getAccessibleName(),
+ xAccessibleComponent);
+ } else if (role == AccessibleRole.WINDOW) {
+ java.awt.Window activeWindow =
+ java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
+ if (activeWindow != null) {
+ w = new Window(activeWindow, xAccessibleComponent);
+ } else {
+ if (Build.DEBUG) {
+ System.err.println("no active frame found for Window: " + role);
+ }
+ return null;
+ }
+ } else {
+ if (Build.DEBUG) {
+ System.err.println("invalid role for toplevel window: " + role);
+ }
+ return null;
+ }
+ populateContainer(w, xAccessibleContext, w);
+ w.setFocusTraversalPolicy(focusTraversalPolicy);
+ w.setVisible(true);
+
+ // Make the new window the focused one if it has an initialy focused object set.
+ java.awt.Component c = ((NativeFrame) w).getInitialComponent();
+ if (c != null) {
+ postWindowGainedFocus(w);
+ }
+ return w;
+ }
+
+ return null;
+ }
+}
+
+