| /******************************************************************************* |
| * Copyright (c) 2000, 2016 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.accessibility; |
| |
| import java.net.*; |
| import java.util.*; |
| import java.util.List; |
| |
| import org.eclipse.swt.*; |
| import org.eclipse.swt.graphics.*; |
| import org.eclipse.swt.internal.cocoa.*; |
| import org.eclipse.swt.widgets.*; |
| |
| /** |
| * Instances of this class provide a bridge between application |
| * code and assistive technology clients. Many platforms provide |
| * default accessible behavior for most widgets, and this class |
| * allows that default behavior to be overridden. Applications |
| * can get the default Accessible object for a control by sending |
| * it <code>getAccessible</code>, and then add an accessible listener |
| * to override simple items like the name and help string, or they |
| * can add an accessible control listener to override complex items. |
| * As a rule of thumb, an application would only want to use the |
| * accessible control listener to implement accessibility for a |
| * custom control. |
| * |
| * @see Control#getAccessible |
| * @see AccessibleListener |
| * @see AccessibleEvent |
| * @see AccessibleControlListener |
| * @see AccessibleControlEvent |
| * @see <a href="http://www.eclipse.org/swt/snippets/#accessibility">Accessibility snippets</a> |
| * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> |
| * |
| * @since 2.0 |
| */ |
| @SuppressWarnings({"rawtypes", "unchecked"}) |
| public class Accessible { |
| |
| static boolean DEBUG = false; |
| |
| static final int MAX_RELATION_TYPES = 15; |
| |
| static NSString[] baseAttributes = { |
| OS.NSAccessibilityRoleAttribute, |
| OS.NSAccessibilitySubroleAttribute, |
| OS.NSAccessibilityRoleDescriptionAttribute, |
| OS.NSAccessibilityHelpAttribute, |
| OS.NSAccessibilityFocusedAttribute, |
| OS.NSAccessibilityParentAttribute, |
| OS.NSAccessibilityChildrenAttribute, |
| OS.NSAccessibilityPositionAttribute, |
| OS.NSAccessibilitySizeAttribute, |
| OS.NSAccessibilityWindowAttribute, |
| OS.NSAccessibilityTopLevelUIElementAttribute, |
| }; |
| |
| NSMutableArray attributeNames = null; |
| NSMutableArray parameterizedAttributeNames = null; |
| NSMutableArray actionNames = null; |
| |
| List<AccessibleListener> accessibleListeners; |
| List<AccessibleControlListener> accessibleControlListeners; |
| List<AccessibleTextListener> accessibleTextListeners; |
| List<AccessibleActionListener> accessibleActionListeners; |
| List<AccessibleEditableTextListener> accessibleEditableTextListeners; |
| List<AccessibleHyperlinkListener> accessibleHyperlinkListeners; |
| List<AccessibleTableListener> accessibleTableListeners; |
| List<AccessibleTableCellListener> accessibleTableCellListeners; |
| List<AccessibleTextExtendedListener> accessibleTextExtendedListeners; |
| List<AccessibleValueListener> accessibleValueListeners; |
| List<AccessibleAttributeListener> accessibleAttributeListeners; |
| |
| Relation relations[] = new Relation[MAX_RELATION_TYPES]; |
| Accessible parent; |
| Control control; |
| int currentRole = -1; |
| |
| Map /*<Integer, SWTAccessibleDelegate>*/ childToIdMap = new HashMap(); |
| SWTAccessibleDelegate delegate; |
| |
| int index = -1; |
| |
| TableAccessibleDelegate tableDelegate; |
| |
| /** |
| * Constructs a new instance of this class given its parent. |
| * |
| * @param parent the Accessible parent, which must not be null |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> |
| * </ul> |
| * |
| * @see #dispose |
| * @see Control#getAccessible |
| * |
| * @since 3.6 |
| */ |
| public Accessible(Accessible parent) { |
| if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); |
| this.parent = parent; |
| this.control = parent.control; |
| delegate = new SWTAccessibleDelegate(this, ACC.CHILDID_SELF); |
| } |
| |
| /** |
| * @since 3.5 |
| * @deprecated |
| */ |
| @Deprecated |
| protected Accessible() { |
| } |
| |
| Accessible(Control control) { |
| this.control = control; |
| } |
| |
| /** |
| * Invokes platform specific functionality to allocate a new accessible object. |
| * <p> |
| * <b>IMPORTANT:</b> This method is <em>not</em> part of the public |
| * API for <code>Accessible</code>. It is marked public only so that it |
| * can be shared within the packages provided by SWT. It is not |
| * available on all platforms, and should never be called from |
| * application code. |
| * </p> |
| * |
| * @param control the control to get the accessible object for |
| * @return the platform specific accessible object |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public static Accessible internal_new_Accessible(Control control) { |
| return new Accessible(control); |
| } |
| |
| id accessibleHandle(Accessible accessible) { |
| if (accessible.delegate != null) return accessible.delegate; |
| if (accessible.control != null) { |
| NSView view = accessible.control.view; |
| long /*int*/ handle = OS.objc_msgSend(view.id, OS.sel_accessibleHandle); |
| return new id(handle); |
| } |
| return null; |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when an accessible client asks for certain strings, |
| * such as name, description, help, or keyboard shortcut. The |
| * listener is notified by sending it one of the messages defined |
| * in the <code>AccessibleListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for a name, description, help, or keyboard shortcut string |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleListener |
| * @see #removeAccessibleListener |
| */ |
| public void addAccessibleListener(AccessibleListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleListeners == null) accessibleListeners = new ArrayList<>(); |
| accessibleListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when an accessible client asks for custom control |
| * specific information. The listener is notified by sending it |
| * one of the messages defined in the <code>AccessibleControlListener</code> |
| * interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for custom control specific information |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleControlListener |
| * @see #removeAccessibleControlListener |
| */ |
| public void addAccessibleControlListener(AccessibleControlListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleControlListeners == null) accessibleControlListeners = new ArrayList<>(); |
| accessibleControlListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners who will |
| * be notified when an accessible client asks for custom text control |
| * specific information. The listener is notified by sending it |
| * one of the messages defined in the <code>AccessibleTextListener</code> |
| * and <code>AccessibleTextExtendedListener</code> interfaces. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for custom text control specific information |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleTextListener |
| * @see AccessibleTextExtendedListener |
| * @see #removeAccessibleTextListener |
| * |
| * @since 3.0 |
| */ |
| public void addAccessibleTextListener (AccessibleTextListener listener) { |
| checkWidget (); |
| if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); |
| if (listener instanceof AccessibleTextExtendedListener) { |
| if (accessibleTextExtendedListeners == null) accessibleTextExtendedListeners = new ArrayList<>(); |
| accessibleTextExtendedListeners.add ((AccessibleTextExtendedListener) listener); |
| } else { |
| if (accessibleTextListeners == null) accessibleTextListeners = new ArrayList<>(); |
| accessibleTextListeners.add (listener); |
| } |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleActionListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for <code>AccessibleActionListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleActionListener |
| * @see #removeAccessibleActionListener |
| * |
| * @since 3.6 |
| */ |
| public void addAccessibleActionListener(AccessibleActionListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleActionListeners == null) accessibleActionListeners = new ArrayList<>(); |
| accessibleActionListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleEditableTextListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for <code>AccessibleEditableTextListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleEditableTextListener |
| * @see #removeAccessibleEditableTextListener |
| * |
| * @since 3.7 |
| */ |
| public void addAccessibleEditableTextListener(AccessibleEditableTextListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleEditableTextListeners == null) accessibleEditableTextListeners = new ArrayList<>(); |
| accessibleEditableTextListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleHyperlinkListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for <code>AccessibleHyperlinkListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleHyperlinkListener |
| * @see #removeAccessibleHyperlinkListener |
| * |
| * @since 3.6 |
| */ |
| public void addAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleHyperlinkListeners == null) accessibleHyperlinkListeners = new ArrayList<>(); |
| accessibleHyperlinkListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleTableListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for <code>AccessibleTableListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleTableListener |
| * @see #removeAccessibleTableListener |
| * |
| * @since 3.6 |
| */ |
| public void addAccessibleTableListener(AccessibleTableListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleTableListeners == null) accessibleTableListeners = new ArrayList<>(); |
| accessibleTableListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleTableCellListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for <code>AccessibleTableCellListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleTableCellListener |
| * @see #removeAccessibleTableCellListener |
| * |
| * @since 3.6 |
| */ |
| public void addAccessibleTableCellListener(AccessibleTableCellListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleTableCellListeners == null) accessibleTableCellListeners = new ArrayList<>(); |
| accessibleTableCellListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleValueListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for <code>AccessibleValueListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleValueListener |
| * @see #removeAccessibleValueListener |
| * |
| * @since 3.6 |
| */ |
| public void addAccessibleValueListener(AccessibleValueListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleValueListeners == null) accessibleValueListeners = new ArrayList<>(); |
| accessibleValueListeners.add(listener); |
| } |
| |
| /** |
| * Adds the listener to the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleAttributeListener</code> interface. |
| * |
| * @param listener the listener that should be notified when the receiver |
| * is asked for <code>AccessibleAttributeListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleAttributeListener |
| * @see #removeAccessibleAttributeListener |
| * |
| * @since 3.6 |
| */ |
| public void addAccessibleAttributeListener(AccessibleAttributeListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleAttributeListeners == null) accessibleAttributeListeners = new ArrayList<>(); |
| accessibleAttributeListeners.add(listener); |
| } |
| |
| void addCGColor(double /*float*/ [] comps, NSMutableAttributedString inAttribString, NSString inAttribute, NSRange inRange) { |
| long /*int*/ cgColorSpace = OS.CGColorSpaceCreateDeviceRGB(); |
| long /*int*/ cgColor = OS.CGColorCreate(cgColorSpace, comps); |
| OS.CGColorSpaceRelease(cgColorSpace); |
| inAttribString.addAttribute(inAttribute, new id(cgColor), inRange); |
| OS.CGColorRelease(cgColor); |
| } |
| |
| /** |
| * Adds a relation with the specified type and target |
| * to the receiver's set of relations. |
| * |
| * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation |
| * @param target the accessible that is the target for this relation |
| * @exception IllegalArgumentException ERROR_NULL_ARGUMENT - if the Accessible target is null |
| * @since 3.6 |
| */ |
| public void addRelation(int type, Accessible target) { |
| checkWidget(); |
| if (target == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); |
| if (relations[type] == null) { |
| relations[type] = new Relation(this, type); |
| } |
| relations[type].addTarget(target); |
| } |
| |
| int accessibleListenersSize() { |
| return accessibleListeners == null ? 0 : accessibleListeners.size(); |
| } |
| |
| int accessibleControlListenersSize() { |
| return accessibleControlListeners == null ? 0 : accessibleControlListeners.size(); |
| } |
| |
| int accessibleValueListenersSize() { |
| return accessibleValueListeners == null ? 0 : accessibleValueListeners.size(); |
| } |
| |
| int accessibleTextExtendedListenersSize() { |
| return accessibleTextExtendedListeners == null ? 0 : accessibleTextExtendedListeners.size(); |
| } |
| |
| int accessibleTextListenersSize() { |
| return accessibleTextListeners == null ? 0 : accessibleTextListeners.size(); |
| } |
| |
| int accessibleTableCellListenersSize() { |
| return accessibleTableCellListeners == null ? 0 : accessibleTableCellListeners.size(); |
| } |
| |
| int accessibleTableListenersSize() { |
| return accessibleTableListeners == null ? 0 : accessibleTableListeners.size(); |
| } |
| |
| int accessibleHyperlinkListenersSize() { |
| return accessibleHyperlinkListeners == null ? 0 : accessibleHyperlinkListeners.size(); |
| } |
| |
| int accessibleEditableTextListenersSize() { |
| return accessibleEditableTextListeners == null ? 0 : accessibleEditableTextListeners.size(); |
| } |
| |
| int accessibleAttributeListenersSize() { |
| return accessibleAttributeListeners == null ? 0 : accessibleAttributeListeners.size(); |
| } |
| |
| int accessibleActionListenersSize() { |
| return accessibleActionListeners == null ? 0 : accessibleActionListeners.size(); |
| } |
| |
| void checkRole(int role) { |
| // A lightweight control can change its role at any time, so track |
| // the current role for the control. If it changes, reset the attribute list. |
| if (role != currentRole) { |
| currentRole = role; |
| |
| if (attributeNames != null) { |
| attributeNames.release(); |
| attributeNames = null; |
| } |
| |
| if (parameterizedAttributeNames != null) { |
| parameterizedAttributeNames.release(); |
| parameterizedAttributeNames = null; |
| } |
| |
| if (actionNames != null) { |
| actionNames.release(); |
| actionNames = null; |
| } |
| } |
| } |
| |
| void createTableDelegate() { |
| if (tableDelegate == null) { |
| tableDelegate = new TableAccessibleDelegate(this); |
| } |
| } |
| |
| id getColumnIndexRangeAttribute(int childID) { |
| AccessibleTableCellEvent event = new AccessibleTableCellEvent(this); |
| for (int i = 0; i < accessibleTableCellListenersSize(); i++) { |
| AccessibleTableCellListener listener = accessibleTableCellListeners.get(i); |
| listener.getColumnIndex(event); |
| listener.getColumnSpan(event); |
| } |
| NSRange range = new NSRange(); |
| range.location = event.index; |
| range.length = event.count; |
| return NSValue.valueWithRange(range); |
| } |
| |
| id getRowIndexRangeAttribute(int childID) { |
| AccessibleTableCellEvent event = new AccessibleTableCellEvent(this); |
| for (int i = 0; i < accessibleTableCellListenersSize(); i++) { |
| AccessibleTableCellListener listener = accessibleTableCellListeners.get(i); |
| listener.getRowIndex(event); |
| listener.getRowSpan(event); |
| } |
| NSRange range = new NSRange(); |
| range.location = event.index; |
| range.length = event.count; |
| return NSValue.valueWithRange(range); |
| } |
| |
| id getSelectedAttribute(int childID) { |
| if (accessibleTableListenersSize() > 0) { |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| event.row = index; |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| if (currentRole == ACC.ROLE_ROW) |
| listener.isRowSelected(event); |
| else |
| listener.isColumnSelected(event); |
| } |
| return NSNumber.numberWithBool(event.isSelected); |
| } |
| |
| return NSNumber.numberWithBool(false); |
| } |
| |
| id getIndexAttribute(int childID) { |
| return NSNumber.numberWithInt(index); |
| } |
| |
| id getHeaderAttribute(int childID) { |
| id returnValue = null; |
| AccessibleTableEvent tableEvent = new AccessibleTableEvent(this); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getColumnHeader(tableEvent); |
| } |
| if (tableEvent.accessible != null) returnValue = tableEvent.accessible.delegate; |
| |
| return returnValue; |
| } |
| |
| id getVisibleColumnsAttribute(int childID) { |
| if (accessibleTableListenersSize() == 0) return null; |
| id returnValue = null; |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getVisibleColumns(event); |
| } |
| if (event.accessibles != null) { |
| NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length); |
| Accessible[] accessibles = event.accessibles; |
| for (int i = 0; i < accessibles.length; i++) { |
| Accessible acc = accessibles[i]; |
| array.addObject(acc.delegate); |
| } |
| returnValue = array; |
| } |
| return returnValue == null ? NSArray.array() : returnValue; |
| } |
| |
| id getVisibleRowsAttribute(int childID) { |
| if (accessibleTableListenersSize() == 0) return null; |
| id returnValue = null; |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getVisibleRows(event); |
| } |
| if (event.accessibles != null) { |
| NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length); |
| Accessible[] accessibles = event.accessibles; |
| for (int i = 0; i < accessibles.length; i++) { |
| Accessible acc = accessibles[i]; |
| array.addObject(acc.delegate); |
| } |
| returnValue = array; |
| } |
| return returnValue == null ? NSArray.array() : returnValue; |
| } |
| |
| id getSelectedRowsAttribute(int childID) { |
| if (accessibleTableListenersSize() == 0) return null; |
| id returnValue = null; |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getSelectedRows(event); |
| } |
| if (event.selected != null) { |
| int[] selected = event.selected; |
| NSMutableArray array = NSMutableArray.arrayWithCapacity(selected.length); |
| for (int i = 0; i < selected.length; i++) { |
| event.row = selected[i]; |
| for (int j = 0; j < accessibleTableListenersSize(); j++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(j); |
| listener.getRow(event); |
| } |
| if (event.accessible != null) array.addObject(event.accessible.delegate); |
| } |
| returnValue = array; |
| } |
| return returnValue == null ? NSArray.array() : returnValue; |
| } |
| |
| |
| int getRowCount() { |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getRowCount(event); |
| } |
| |
| return event.count; |
| } |
| |
| id getRowsAttribute(int childID) { |
| if (accessibleTableListenersSize() == 0) return null; |
| |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getRowCount(event); |
| listener.getRows(event); |
| } |
| |
| if (event.accessibles == null) event.accessibles = new Accessible[0]; |
| |
| if (event.count != event.accessibles.length) { |
| createTableDelegate(); |
| |
| // Rerun the row query now that our accessible is in place. |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getRowCount(event); |
| listener.getRows(event); |
| } |
| } |
| |
| NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length); |
| Object[] rows = event.accessibles; |
| for (int i = 0; i < rows.length; i++) { |
| Accessible acc = (Accessible) rows[i]; |
| acc.index = i; |
| array.addObject(acc.delegate); |
| } |
| return array; |
| } |
| |
| id getSelectedColumnsAttribute(int childID) { |
| if (accessibleTableListenersSize() == 0) return null; |
| |
| id returnValue = null; |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getSelectedColumns(event); |
| } |
| if (event.selected != null) { |
| int[] selected = event.selected; |
| NSMutableArray array = NSMutableArray.arrayWithCapacity(selected.length); |
| for (int i = 0; i < selected.length; i++) { |
| event.column = selected[i]; |
| for (int j = 0; j < accessibleTableListenersSize(); j++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(j); |
| listener.getColumn(event); |
| } |
| if (event.accessible != null) array.addObject(event.accessible.delegate); |
| } |
| returnValue = array; |
| } |
| return returnValue == null ? NSArray.array() : returnValue; |
| } |
| |
| int getColumnCount() { |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getColumnCount(event); |
| } |
| |
| return event.count; |
| } |
| |
| id getColumnsAttribute(int childID) { |
| if (accessibleTableListenersSize() == 0) return null; |
| |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getColumnCount(event); |
| listener.getColumns(event); |
| } |
| |
| if (event.accessibles == null) event.accessibles = new Accessible[0]; |
| |
| if (event.count != event.accessibles.length) { |
| createTableDelegate(); |
| |
| // Rerun the Column query, now that our adapter is in place. |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getColumnCount(event); |
| listener.getColumns(event); |
| } |
| } |
| |
| NSMutableArray array = NSMutableArray.arrayWithCapacity(event.accessibles.length); |
| Accessible[] accessibles = event.accessibles; |
| for (int i = 0; i < accessibles.length; i++) { |
| Accessible acc = accessibles[i]; |
| acc.index = i; |
| array.addObject(acc.delegate); |
| } |
| return array; |
| } |
| |
| /** |
| * Gets the human-readable description of an action. |
| * <p> |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public id internal_accessibilityActionDescription(NSString action, int childID) { |
| NSString returnValue = NSString.string(); |
| String actionName = action.getString(); |
| if (accessibleActionListenersSize() > 0) { |
| AccessibleActionEvent event = new AccessibleActionEvent(this); |
| for (int i = 0; i < accessibleActionListenersSize(); i++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(i); |
| listener.getActionCount(event); |
| } |
| int index = -1; |
| for (int i = 0; i < event.count; i++) { |
| event.index = i; |
| for (int j = 0; j < accessibleActionListenersSize(); j++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(j); |
| listener.getName(event); |
| } |
| if (actionName.equals(event.result)) { |
| index = i; |
| break; |
| } |
| } |
| if (index != -1) { |
| event.index = index; |
| event.result = null; |
| for (int i = 0; i < accessibleActionListenersSize(); i++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(i); |
| listener.getDescription(event); |
| } |
| if (event.result != null) returnValue = NSString.stringWith(event.result); |
| } |
| } |
| return returnValue; |
| } |
| |
| /** |
| * Gets the array of action names that this object can perform. |
| * <p> |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public NSArray internal_accessibilityActionNames(int childID) { |
| if (accessibleActionListenersSize() > 0) { |
| AccessibleActionEvent event = new AccessibleActionEvent(this); |
| for (int i = 0; i < accessibleActionListenersSize(); i++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(i); |
| listener.getActionCount(event); |
| } |
| NSMutableArray array = NSMutableArray.arrayWithCapacity(event.count); |
| for (int i = 0; i < event.count; i++) { |
| event.index = i; |
| for (int j = 0; j < accessibleActionListenersSize(); j++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(j); |
| listener.getName(event); |
| } |
| array.addObject(NSString.stringWith(event.result)); |
| } |
| return array; |
| } else { |
| // The supported action list depends on the role played by the control. |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| } |
| |
| // No accessible listener is overriding the role of the control, so let Cocoa return the default set for the control. |
| if (event.detail == -1) { |
| return null; |
| } |
| |
| checkRole(event.detail); |
| |
| if ((childID == ACC.CHILDID_SELF) && (actionNames != null)) { |
| return retainedAutoreleased(actionNames); |
| } |
| |
| NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(5); |
| |
| switch (event.detail) { |
| case ACC.ROLE_PUSHBUTTON: |
| case ACC.ROLE_RADIOBUTTON: |
| case ACC.ROLE_CHECKBUTTON: |
| case ACC.ROLE_TABITEM: |
| case ACC.ROLE_LINK: |
| case ACC.ROLE_CHECKMENUITEM: |
| case ACC.ROLE_RADIOMENUITEM: |
| case ACC.ROLE_SPLITBUTTON: |
| returnValue.addObject(OS.NSAccessibilityPressAction); |
| break; |
| case ACC.ROLE_COMBOBOX: |
| returnValue.addObject(OS.NSAccessibilityConfirmAction); |
| break; |
| case ACC.ROLE_WINDOW: |
| case ACC.ROLE_DIALOG: |
| // TODO |
| // returnValue.addObject(OS.NSAccessibilityRaiseAction); |
| break; |
| } |
| |
| |
| if (childID == ACC.CHILDID_SELF) { |
| actionNames = returnValue; |
| actionNames.retain(); |
| return retainedAutoreleased(actionNames); |
| } else { |
| // Caller must retain if they want to hold on to it. |
| return returnValue; |
| } |
| } |
| } |
| |
| /** |
| * Checks to see if the specified attribute can be set by a screen reader or other |
| * assistive service. |
| * <p> |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public boolean internal_accessibilityIsAttributeSettable(NSString attribute, int childID) { |
| if (accessibleTextExtendedListenersSize() > 0) { |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangeAttribute)) return true; |
| if (attribute.isEqualToString(OS.NSAccessibilityVisibleCharacterRangeAttribute)) return true; |
| } |
| if (accessibleEditableTextListenersSize() > 0) { |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextAttribute)) return true; |
| } |
| if (accessibleValueListenersSize() > 0) { |
| if (attribute.isEqualToString(OS.NSAccessibilityValueAttribute)) return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Gets the array of attributes this object supports. |
| * <p> |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public NSArray internal_accessibilityAttributeNames(int childID) { |
| // The supported attribute set depends on the role played by the control. |
| // We may need to add or remove from the base set as needed. |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| } |
| |
| // No accessible listener is overriding the role of the control, so let Cocoa |
| // return the default set for the control. |
| if (event.detail == -1) |
| return null; |
| |
| checkRole(event.detail); |
| |
| // If the attributes haven't changed return the cached list. |
| if (attributeNames != null) return retainedAutoreleased(attributeNames); |
| |
| // Set up the base set of attributes. |
| NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(baseAttributes.length); |
| |
| for (int i = 0; i < baseAttributes.length; i++) { |
| returnValue.addObject(baseAttributes[i]); |
| } |
| |
| switch(event.detail) { |
| case ACC.ROLE_CLIENT_AREA: |
| break; |
| case ACC.ROLE_WINDOW: |
| returnValue.addObject(OS.NSAccessibilityTitleAttribute); |
| // TODO |
| // returnValue.addObject(OS.NSAccessibilityMainAttribute); |
| // returnValue.addObject(OS.NSAccessibilityMinimizedAttribute); |
| break; |
| case ACC.ROLE_MENUBAR: |
| returnValue.addObject(OS.NSAccessibilitySelectedChildrenAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute); |
| break; |
| case ACC.ROLE_MENU: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedChildrenAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute); |
| break; |
| case ACC.ROLE_MENUITEM: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| break; |
| case ACC.ROLE_SEPARATOR: |
| returnValue.addObject(OS.NSAccessibilityMaxValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityMinValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| //TODO |
| // returnValue.addObject(OS.NSAccessibilityOrientationAttribute); |
| // returnValue.addObject(OS.NSAccessibilityPreviousContentsAttribute); |
| // returnValue.addObject(OS.NSAccessibilityNextContentsAttribute); |
| break; |
| case ACC.ROLE_TOOLTIP: |
| returnValue.addObject(OS.NSAccessibilityTitleAttribute); |
| break; |
| case ACC.ROLE_SCROLLBAR: |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| //TODO |
| // returnValue.addObject(OS.NSAccessibilityOrientationAttribute); |
| break; |
| case ACC.ROLE_DIALOG: |
| returnValue.addObject(OS.NSAccessibilityTitleAttribute); |
| // TODO |
| // returnValue.addObject(OS.NSAccessibilityMainAttribute); |
| // returnValue.addObject(OS.NSAccessibilityMinimizedAttribute); |
| break; |
| case ACC.ROLE_LABEL: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| break; |
| case ACC.ROLE_PUSHBUTTON: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityTitleAttribute); |
| break; |
| case ACC.ROLE_CHECKBUTTON: |
| case ACC.ROLE_RADIOBUTTON: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityTitleAttribute); |
| break; |
| case ACC.ROLE_SPLITBUTTON: |
| break; |
| case ACC.ROLE_COMBOBOX: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityExpandedAttribute); |
| returnValue.addObject(OS.NSAccessibilityNumberOfCharactersAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedTextAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedTextRangeAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleCharacterRangeAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| break; |
| case ACC.ROLE_TEXT: |
| case ACC.ROLE_PARAGRAPH: |
| case ACC.ROLE_HEADING: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityNumberOfCharactersAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedTextAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedTextRangeAttribute); |
| returnValue.addObject(OS.NSAccessibilityInsertionPointLineNumberAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedTextRangesAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleCharacterRangeAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| break; |
| case ACC.ROLE_TOOLBAR: |
| break; |
| case ACC.ROLE_LIST: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilityRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityHeaderAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute); |
| break; |
| case ACC.ROLE_LISTITEM: |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| break; |
| case ACC.ROLE_TABLE: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilityRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityHeaderAttribute); |
| break; |
| case ACC.ROLE_TABLECELL: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| break; |
| case ACC.ROLE_TREE: |
| returnValue.addObject(OS.NSAccessibilityColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilityRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityHeaderAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute); |
| break; |
| case ACC.ROLE_TREEITEM: |
| returnValue.addObject(OS.NSAccessibilityColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedColumnsAttribute); |
| returnValue.addObject(OS.NSAccessibilityRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityHeaderAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleColumnsAttribute); |
| case ACC.ROLE_TABFOLDER: |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityContentsAttribute); |
| returnValue.addObject(OS.NSAccessibilityTabsAttribute); |
| break; |
| case ACC.ROLE_TABITEM: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityTitleAttribute); |
| break; |
| case ACC.ROLE_PROGRESSBAR: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityMaxValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityMinValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| break; |
| case ACC.ROLE_SLIDER: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityMaxValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityMinValueAttribute); |
| returnValue.addObject(OS.NSAccessibilityValueAttribute); |
| //TODO |
| // returnValue.addObject(OS.NSAccessibilityOrientationAttribute); |
| // increment |
| // decrement |
| break; |
| case ACC.ROLE_LINK: |
| //TODO |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| // returnValue.addObject(OS.NSAccessibilityURLAttribute); |
| // visited |
| break; |
| case ACC.ROLE_ALERT: |
| break; |
| case ACC.ROLE_ANIMATION: |
| break; |
| case ACC.ROLE_CANVAS: |
| break; |
| case ACC.ROLE_COLUMN: |
| returnValue.removeObject(OS.NSAccessibilityChildrenAttribute); |
| returnValue.removeObject(OS.NSAccessibilityFocusedAttribute); |
| returnValue.addObject(OS.NSAccessibilityIndexAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedAttribute); |
| returnValue.addObject(OS.NSAccessibilityRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityVisibleRowsAttribute); |
| returnValue.addObject(OS.NSAccessibilityHeaderAttribute); |
| break; |
| case ACC.ROLE_DOCUMENT: |
| break; |
| case ACC.ROLE_GRAPHIC: |
| returnValue.addObject(OS.NSAccessibilityEnabledAttribute); |
| returnValue.addObject(OS.NSAccessibilityTitleAttribute); |
| returnValue.addObject(OS.NSAccessibilityDescriptionAttribute); |
| break; |
| case ACC.ROLE_GROUP: |
| break; |
| case ACC.ROLE_ROW: |
| returnValue.addObject(OS.NSAccessibilityVisibleChildrenAttribute); |
| returnValue.addObject(OS.NSAccessibilityIndexAttribute); |
| returnValue.addObject(OS.NSAccessibilitySelectedAttribute); |
| break; |
| case ACC.ROLE_SPINBUTTON: |
| break; |
| case ACC.ROLE_STATUSBAR: |
| break; |
| case ACC.ROLE_CHECKMENUITEM: |
| break; |
| case ACC.ROLE_RADIOMENUITEM: |
| break; |
| case ACC.ROLE_CLOCK: |
| break; |
| case ACC.ROLE_DATETIME: |
| break; |
| case ACC.ROLE_CALENDAR: |
| break; |
| case ACC.ROLE_FOOTER: |
| break; |
| case ACC.ROLE_HEADER: |
| break; |
| case ACC.ROLE_FORM: |
| break; |
| case ACC.ROLE_PAGE: |
| break; |
| case ACC.ROLE_SECTION: |
| break; |
| } |
| |
| |
| /* |
| * Only report back sub-roles when the SWT role maps to a sub-role. |
| */ |
| if (event.detail != -1) { |
| String osRole = roleToOs(event.detail); |
| if (osRole.indexOf(':') == -1) |
| returnValue.removeObject(OS.NSAccessibilitySubroleAttribute); |
| } |
| |
| /* |
| * Children never return their own children, so remove that attribute. |
| */ |
| if (childID != ACC.CHILDID_SELF) { |
| returnValue.removeObject(OS.NSAccessibilityChildrenAttribute); |
| } |
| |
| if (childID == ACC.CHILDID_SELF) { |
| attributeNames = returnValue; |
| attributeNames.retain(); |
| return retainedAutoreleased(attributeNames); |
| } else { |
| // Caller must retain if necessary. |
| return returnValue; |
| } |
| } |
| |
| /** |
| * Returns the value for the specified attribute. Return type depends on the attribute |
| * being queried; see the implementations of the accessor methods for details. |
| * <p> |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public id internal_accessibilityAttributeValue(NSString attribute, int childID) { |
| if (attribute.isEqualToString(OS.NSAccessibilityRoleAttribute)) return getRoleAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySubroleAttribute)) return getSubroleAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityRoleDescriptionAttribute)) return getRoleDescriptionAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityExpandedAttribute)) return getExpandedAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityHelpAttribute)) return getHelpAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityTitleAttribute)) return getTitleAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityValueAttribute)) return getValueAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityMaxValueAttribute)) return getMaxValueAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityMinValueAttribute)) return getMinValueAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityEnabledAttribute)) return getEnabledAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityFocusedAttribute)) return getFocusedAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityParentAttribute)) return getParentAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityChildrenAttribute)) return getChildrenAttribute(childID, false); |
| if (attribute.isEqualToString(OS.NSAccessibilityVisibleChildrenAttribute)) return getChildrenAttribute(childID, true); |
| if (attribute.isEqualToString(OS.NSAccessibilityContentsAttribute)) return getChildrenAttribute(childID, false); |
| // FIXME: There's no specific API just for tabs, which won't include the buttons (if any.) |
| if (attribute.isEqualToString(OS.NSAccessibilityTabsAttribute)) return getTabsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityWindowAttribute)) return getWindowAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityTopLevelUIElementAttribute)) return getTopLevelUIElementAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityPositionAttribute)) return getPositionAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySizeAttribute)) return getSizeAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityDescriptionAttribute)) return getDescriptionAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityNumberOfCharactersAttribute)) return getNumberOfCharactersAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextAttribute)) return getSelectedTextAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangeAttribute)) return getSelectedTextRangeAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityInsertionPointLineNumberAttribute)) return getInsertionPointLineNumberAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangesAttribute)) return getSelectedTextRangesAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityVisibleCharacterRangeAttribute)) return getVisibleCharacterRangeAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityServesAsTitleForUIElementsAttribute)) return getServesAsTitleForUIElementsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityTitleUIElementAttribute)) return getTitleUIElementAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityColumnsAttribute)) return getColumnsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedColumnsAttribute)) return getSelectedColumnsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityRowsAttribute)) return getRowsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedRowsAttribute)) return getSelectedRowsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityVisibleRowsAttribute)) return getVisibleRowsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityVisibleColumnsAttribute)) return getVisibleColumnsAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityHeaderAttribute)) return getHeaderAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityIndexAttribute)) return getIndexAttribute(childID); |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedAttribute)) return getSelectedAttribute(childID); |
| if (OS.VERSION >= 0x1060 && attribute.isEqualToString(OS.NSAccessibilityRowIndexRangeAttribute)) return getRowIndexRangeAttribute(childID); |
| if (OS.VERSION >= 0x1060 && attribute.isEqualToString(OS.NSAccessibilityColumnIndexRangeAttribute)) return getColumnIndexRangeAttribute(childID); |
| |
| // If this object don't know how to get the value it's up to the control itself to return an attribute value. |
| return null; |
| } |
| |
| /** |
| * Returns the value of the specified attribute, using the supplied parameter. Return |
| * and parameter types vary depending on the attribute being queried. |
| * <p> |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public id internal_accessibilityAttributeValue_forParameter(NSString attribute, id parameter, int childID) { |
| if (attribute.isEqualToString(OS.NSAccessibilityStringForRangeParameterizedAttribute)) return getStringForRangeParameterizedAttribute(parameter, childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityRangeForLineParameterizedAttribute)) return getRangeForLineParameterizedAttribute(parameter, childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityRangeForIndexParameterizedAttribute)) return getRangeForIndexParameterizedAttribute(parameter, childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityLineForIndexParameterizedAttribute)) return getLineForIndexParameterizedAttribute(parameter, childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityBoundsForRangeParameterizedAttribute)) return getBoundsForRangeParameterizedAttribute(parameter, childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityRangeForPositionParameterizedAttribute)) return getRangeForPositionParameterizedAttribute(parameter, childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityAttributedStringForRangeParameterizedAttribute)) return getAttributedStringForRangeParameterizedAttribute(parameter, childID); |
| if (attribute.isEqualToString(OS.NSAccessibilityStyleRangeForIndexParameterizedAttribute)) return getStyleRangeForIndexAttribute(parameter, childID); |
| if (OS.VERSION >= 0x1060 && attribute.isEqualToString(OS.NSAccessibilityCellForColumnAndRowParameterizedAttribute)) return getCellForColumnAndRowParameter(parameter, childID); |
| return null; |
| } |
| |
| /** |
| * Returns the UI Element that has the focus. You can assume that the search |
| * for the focus has already been narrowed down to the receiver. |
| * Override this method to do a deeper search with a UIElement - |
| * e.g. a NSMatrix would determine if one of its cells has the focus. |
| * <p> |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public id internal_accessibilityFocusedUIElement(int childID) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = ACC.CHILDID_MULTIPLE; // set to invalid value, to test if the application sets it in getFocus() |
| event.accessible = null; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getFocus(event); |
| } |
| |
| // The listener did not respond, so let Cocoa figure it out. |
| if (event.childID == ACC.CHILDID_MULTIPLE) |
| return null; |
| |
| /* The application can optionally answer an accessible. */ |
| if (event.accessible != null) { |
| return new id(OS.NSAccessibilityUnignoredAncestor(event.accessible.control.view.id)); |
| } |
| |
| /* Or the application can answer a valid child ID, including CHILDID_SELF and CHILDID_NONE. */ |
| if (event.childID == ACC.CHILDID_SELF || event.childID == ACC.CHILDID_NONE) { |
| return new id(OS.NSAccessibilityUnignoredAncestor(control.view.id)); |
| } |
| |
| return new id(OS.NSAccessibilityUnignoredAncestor(childIDToOs(event.childID).id)); |
| } |
| |
| /** |
| * Returns the deepest descendant of the UIElement hierarchy that contains the point. |
| * You can assume the point has already been determined to lie within the receiver. |
| * Override this method to do deeper hit testing within a UIElement - e.g. a NSMatrix |
| * would test its cells. The point is bottom-left relative screen coordinates. |
| * |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public id internal_accessibilityHitTest(NSPoint point, int childID) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.x = (int) point.x; |
| Monitor primaryMonitor = Display.getCurrent().getPrimaryMonitor(); |
| event.y = (int) (primaryMonitor.getBounds().height - point.y); |
| |
| // Set an impossible value to determine if anything responded to the event. |
| event.childID = ACC.CHILDID_MULTIPLE; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getChildAtPoint(event); |
| } |
| |
| // The listener did not respond, so let Cocoa figure it out. |
| if (event.childID == ACC.CHILDID_MULTIPLE && event.accessible == null) |
| return null; |
| |
| if (event.accessible != null) { |
| return new id(OS.NSAccessibilityUnignoredAncestor(event.accessible.delegate.id)); |
| } |
| |
| if (event.childID == ACC.CHILDID_SELF || event.childID == ACC.CHILDID_NONE) { |
| return new id(OS.NSAccessibilityUnignoredAncestor(control.view.id)); |
| } |
| |
| return new id(OS.NSAccessibilityUnignoredAncestor(childIDToOs(event.childID).id)); |
| } |
| |
| /** |
| * Return YES if the UIElement doesn't show up to the outside world - |
| * i.e. its parent should return the UIElement's children as its own - |
| * cutting the UIElement out. E.g. NSControls are ignored when they are single-celled. |
| * |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public boolean internal_accessibilityIsIgnored(int childID) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| } |
| |
| boolean shouldIgnore = (event.detail == -1); |
| |
| if (shouldIgnore) { |
| shouldIgnore = getTitleAttribute(childID) == null && getHelpAttribute(childID) == null && getDescriptionAttribute(childID) == null; |
| } |
| |
| return shouldIgnore; |
| } |
| |
| /** |
| * Return the array of supported attributes that take parameters. |
| * |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public NSArray internal_accessibilityParameterizedAttributeNames(int childID) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| } |
| |
| // No accessible listener is overriding the role of the control, so let Cocoa |
| // return the default set for the control. |
| if (event.detail == -1) |
| return null; |
| |
| checkRole(event.detail); |
| |
| if ((childID == ACC.CHILDID_SELF) && (parameterizedAttributeNames != null)) { |
| return retainedAutoreleased(parameterizedAttributeNames); |
| } |
| |
| NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(4); |
| |
| switch(event.detail) { |
| case ACC.ROLE_TEXT: |
| case ACC.ROLE_PARAGRAPH: |
| case ACC.ROLE_HEADING: |
| returnValue.addObject(OS.NSAccessibilityStringForRangeParameterizedAttribute); |
| returnValue.addObject(OS.NSAccessibilityRangeForLineParameterizedAttribute); |
| returnValue.addObject(OS.NSAccessibilityRangeForIndexParameterizedAttribute); |
| returnValue.addObject(OS.NSAccessibilityLineForIndexParameterizedAttribute); |
| returnValue.addObject(OS.NSAccessibilityBoundsForRangeParameterizedAttribute); |
| returnValue.addObject(OS.NSAccessibilityRangeForPositionParameterizedAttribute); |
| returnValue.addObject(OS.NSAccessibilityAttributedStringForRangeParameterizedAttribute); |
| returnValue.addObject(OS.NSAccessibilityStyleRangeForIndexParameterizedAttribute); |
| break; |
| case ACC.ROLE_TABLE: |
| if (OS.VERSION >= 0x1060) returnValue.addObject(OS.NSAccessibilityCellForColumnAndRowParameterizedAttribute); |
| break; |
| } |
| |
| if (childID == ACC.CHILDID_SELF) { |
| parameterizedAttributeNames = returnValue; |
| parameterizedAttributeNames.retain(); |
| return retainedAutoreleased(parameterizedAttributeNames); |
| } else { |
| // Caller must retain if they want to keep it. |
| return returnValue; |
| } |
| } |
| |
| /** |
| * Performs the specified action. |
| * |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public boolean internal_accessibilityPerformAction(NSString action, int childID) { |
| String actionName = action.getString(); |
| if (accessibleActionListenersSize() > 0) { |
| AccessibleActionEvent event = new AccessibleActionEvent(this); |
| for (int i = 0; i < accessibleActionListenersSize(); i++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(i); |
| listener.getActionCount(event); |
| } |
| int index = -1; |
| for (int i = 0; i < event.count; i++) { |
| event.index = i; |
| for (int j = 0; j < accessibleActionListenersSize(); j++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(j); |
| listener.getName(event); |
| } |
| if (actionName.equals(event.result)) { |
| index = i; |
| break; |
| } |
| } |
| if (index != -1) { |
| event.index = index; |
| event.result = null; |
| for (int i = 0; i < accessibleActionListenersSize(); i++) { |
| AccessibleActionListener listener = accessibleActionListeners.get(i); |
| listener.doAction(event); |
| } |
| return ACC.OK.equals(event.result); |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Set the value of the specified attribute to the given value. |
| * Unsupported attributes are ignored. |
| * |
| * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public void internal_accessibilitySetValue_forAttribute(id value, NSString attribute, int childId) { |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextRangeAttribute)) setSelectedTextRangeAttribute(value, childId); |
| if (attribute.isEqualToString(OS.NSAccessibilitySelectedTextAttribute)) setSelectedTextAttribute(value, childId); |
| if (attribute.isEqualToString(OS.NSAccessibilityVisibleCharacterRangeAttribute)) setVisibleCharacterRangeAttribute(value, childId); |
| |
| if (accessibleValueListenersSize() > 0) { |
| AccessibleValueEvent event = new AccessibleValueEvent(this); |
| NSNumber number = new NSNumber(value); |
| event.value = Double.valueOf(number.doubleValue()); |
| for (int i = 0; i < accessibleValueListenersSize(); i++) { |
| AccessibleValueListener listener = accessibleValueListeners.get(i); |
| listener.setCurrentValue(event); |
| } |
| } |
| } |
| |
| /** |
| * Disposes of the operating system resources associated with |
| * the receiver, and removes the receiver from its parent's |
| * list of children. |
| * <p> |
| * This method should be called when an accessible that was created |
| * with the public constructor <code>Accessible(Accessible parent)</code> |
| * is no longer needed. You do not need to call this when the receiver's |
| * control is disposed, because all <code>Accessible</code> instances |
| * associated with a control are released when the control is disposed. |
| * It is also not necessary to call this for instances of <code>Accessible</code> |
| * that were retrieved with <code>Control.getAccessible()</code>. |
| * </p> |
| * |
| * @since 3.6 |
| */ |
| public void dispose () { |
| if (parent == null) return; |
| release(true); |
| parent = null; |
| } |
| |
| /** |
| * Returns the control for this Accessible object. |
| * |
| * @return the receiver's control |
| * @since 3.0 |
| */ |
| public Control getControl() { |
| return control; |
| } |
| |
| /** |
| * Invokes platform specific functionality to dispose an accessible object. |
| * <p> |
| * <b>IMPORTANT:</b> This method is <em>not</em> part of the public |
| * API for <code>Accessible</code>. It is marked public only so that it |
| * can be shared within the packages provided by SWT. It is not |
| * available on all platforms, and should never be called from |
| * application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public void internal_dispose_Accessible() { |
| release(true); |
| } |
| |
| id getAttributedStringForRangeParameterizedAttribute(id parameter, int childID) { |
| if (accessibleAttributeListenersSize() == 0) return null; |
| |
| id stringFragment = getStringForRangeParameterizedAttribute(parameter, childID); |
| NSMutableAttributedString attribString = (NSMutableAttributedString)new NSMutableAttributedString().alloc(); |
| attribString.initWithString(new NSString(stringFragment), null); |
| attribString.autorelease(); |
| |
| // Parameter is an NSRange wrapped in an NSValue. |
| NSValue parameterObject = new NSValue(parameter.id); |
| NSRange range = parameterObject.rangeValue(); |
| |
| AccessibleTextAttributeEvent event = new AccessibleTextAttributeEvent(this); |
| |
| event.offset = (int) /*64*/ range.location; |
| event.start = event.end = -1; |
| |
| NSRange attributeRange = new NSRange(); |
| |
| while (event.offset < range.location + range.length) { |
| for (int i = 0; i < accessibleAttributeListenersSize(); i++) { |
| AccessibleAttributeListener listener = accessibleAttributeListeners.get(i); |
| listener.getTextAttributes(event); |
| } |
| |
| if (event.start == -1 && event.end == -1) return stringFragment; |
| |
| // The returned attributed string must have zero-based attributes. |
| attributeRange.location = event.start - range.location; |
| attributeRange.length = event.end - event.start; |
| |
| // attributeRange.location can be negative if the start of the requested range falls in the middle of a style run. |
| // If that happens, clamp to zero and adjust the length by the amount of adjustment. |
| if (attributeRange.location < 0) { |
| attributeRange.length -= -attributeRange.location; |
| attributeRange.location = 0; |
| } |
| |
| // Likewise, make sure the last attribute set does not run past the end of the requested range. |
| if (attributeRange.location + attributeRange.length > range.length) { |
| attributeRange.length = range.length - attributeRange.location; |
| } |
| |
| // Reset the offset so we pick up the next set of attributes that change. |
| event.offset = event.end; |
| |
| if (event.textStyle != null) { |
| TextStyle ts = event.textStyle; |
| if (ts.font != null) { |
| NSMutableDictionary fontInfoDict = NSMutableDictionary.dictionaryWithCapacity(4); |
| |
| NSFont fontUsed = ts.font.handle; |
| // Get font name and size from NSFont |
| NSString fontName = fontUsed.fontName(); |
| fontInfoDict.setValue(fontName, OS.NSAccessibilityFontNameKey); |
| NSString familyName = fontUsed.familyName(); |
| fontInfoDict.setValue(familyName, OS.NSAccessibilityFontFamilyKey); |
| NSString displayName = fontUsed.displayName(); |
| fontInfoDict.setValue(displayName, OS.NSAccessibilityVisibleNameKey); |
| double /*float*/ fontSize = fontUsed.pointSize(); |
| fontInfoDict.setValue(NSNumber.numberWithDouble(fontSize), OS.NSAccessibilityFontSizeKey); |
| |
| attribString.addAttribute(OS.NSAccessibilityFontTextAttribute, fontInfoDict, attributeRange); |
| } |
| |
| if (ts.foreground != null) { |
| addCGColor(ts.foreground.handle, attribString, OS.NSAccessibilityForegroundColorTextAttribute, attributeRange); |
| } |
| |
| if (ts.background != null) { |
| addCGColor(ts.background.handle, attribString, OS.NSAccessibilityBackgroundColorTextAttribute, attributeRange); |
| } |
| |
| if (ts.underline) { |
| int style = ts.underlineStyle; |
| NSString attribute = OS.NSAccessibilityUnderlineTextAttribute; |
| NSNumber styleObj = null; |
| switch (style) { |
| case SWT.UNDERLINE_SINGLE: |
| styleObj = NSNumber.numberWithInt(OS.kAXUnderlineStyleSingle); |
| break; |
| case SWT.UNDERLINE_DOUBLE: |
| styleObj = NSNumber.numberWithInt(OS.kAXUnderlineStyleDouble); |
| break; |
| case SWT.UNDERLINE_SQUIGGLE: |
| attribute = OS.NSAccessibilityMisspelledTextAttribute; |
| styleObj = NSNumber.numberWithBool(true); |
| break; |
| default: |
| styleObj = NSNumber.numberWithInt(OS.kAXUnderlineStyleNone); |
| } |
| |
| attribString.addAttribute(attribute, styleObj, attributeRange); |
| } |
| |
| if (ts.underlineColor != null) { |
| addCGColor(ts.underlineColor.handle, attribString, OS.NSAccessibilityUnderlineColorTextAttribute, attributeRange); |
| } |
| |
| if (ts.strikeout) { |
| attribString.addAttribute(OS.NSAccessibilityStrikethroughTextAttribute, NSNumber.numberWithBool(true), attributeRange); |
| |
| if (ts.strikeoutColor != null) { |
| addCGColor(ts.strikeoutColor.handle, attribString, OS.NSAccessibilityStrikethroughColorTextAttribute, attributeRange); |
| } |
| } |
| |
| if (ts.data != null) { |
| if (ts.data instanceof URL) { |
| URL dataAsURL = (URL)ts.data; |
| NSURL linkURL = NSURL.URLWithString(NSString.stringWith(dataAsURL.toExternalForm())); |
| attribString.addAttribute(OS.NSAccessibilityLinkTextAttribute, linkURL, attributeRange); |
| } |
| } |
| } |
| } |
| |
| // Now add the alignment, justification, and indent, if available. |
| AccessibleAttributeEvent docAttributes = new AccessibleAttributeEvent(this); |
| docAttributes.indent = Integer.MAX_VALUE; // if unchanged no listener filled it in. |
| for (int i = 0; i < accessibleAttributeListenersSize(); i++) { |
| AccessibleAttributeListener listener = accessibleAttributeListeners.get(i); |
| listener.getAttributes(docAttributes); |
| } |
| |
| if (docAttributes.indent != Integer.MAX_VALUE) { |
| NSMutableDictionary paragraphDict = NSMutableDictionary.dictionaryWithCapacity(3); |
| int osAlignment = 0; |
| // FIXME: Doesn't account for right-to-left text? |
| switch (docAttributes.alignment) { |
| case SWT.CENTER: |
| osAlignment = OS.NSCenterTextAlignment; |
| break; |
| case SWT.RIGHT: |
| osAlignment = OS.NSRightTextAlignment; |
| break; |
| case SWT.LEFT: |
| default: |
| osAlignment = OS.NSLeftTextAlignment; |
| break; |
| } |
| paragraphDict.setValue(NSNumber.numberWithInt(osAlignment), NSString.stringWith("AXTextAlignment")); |
| range.location = 0; |
| attribString.addAttribute(NSString.stringWith("AXParagraphStyle"), paragraphDict, range); |
| } |
| |
| return attribString; |
| } |
| |
| id getBoundsForRangeParameterizedAttribute(id parameter, int childID) { |
| if (accessibleTextExtendedListenersSize() == 0) return null; |
| |
| id returnValue = null; |
| NSValue parameterObject = new NSValue(parameter.id); |
| NSRange range = parameterObject.rangeValue(); |
| NSRect rect = new NSRect(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.start = (int)/*64*/range.location; |
| event.end = (int)/*64*/(range.location + range.length); |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getTextBounds(event); |
| } |
| rect.x = event.x; |
| |
| // Flip y coordinate for Cocoa. |
| NSArray screens = NSScreen.screens(); |
| NSScreen screen = new NSScreen(screens.objectAtIndex(0)); |
| NSRect frame = screen.frame(); |
| rect.y = frame.height - event.y - event.height; |
| |
| rect.width = event.width; |
| rect.height = event.height; |
| returnValue = NSValue.valueWithRect(rect); |
| } else { |
| //FIXME??? |
| //how to implement with old listener |
| } |
| return returnValue; |
| } |
| |
| id getExpandedAttribute(int childID) { |
| // TODO: May need to expand the API so the combo box state can be reported. |
| return NSNumber.numberWithBool(false); |
| } |
| |
| id getHelpAttribute (int childID) { |
| id returnValue = null; |
| AccessibleEvent event = new AccessibleEvent(this); |
| event.childID = childID; |
| for (int i = 0; i < accessibleListenersSize(); i++) { |
| AccessibleListener listener = accessibleListeners.get(i); |
| listener.getHelp(event); |
| } |
| |
| if (event.result != null) { |
| returnValue = NSString.stringWith(event.result); |
| } |
| |
| return returnValue; |
| } |
| |
| id getRangeForPositionParameterizedAttribute(id parameter, int childID) { |
| id returnValue = null; |
| NSValue parameterObject = new NSValue(parameter.id); |
| NSPoint point = parameterObject.pointValue(); |
| NSRange range = new NSRange(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| NSArray screens = NSScreen.screens(); |
| NSScreen screen = new NSScreen(screens.objectAtIndex(0)); |
| NSRect frame = screen.frame(); |
| point.y = frame.height - point.y; |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.x = (int)point.x; |
| event.y = (int)point.y; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getOffsetAtPoint(event); |
| } |
| range.location = event.offset; |
| range.length = 1; |
| } else { |
| //FIXME??? |
| //how to implement with old listener |
| } |
| returnValue = NSValue.valueWithRange(range); |
| return returnValue; |
| } |
| |
| NSString getRoleAttribute(int childID) { |
| NSString returnValue = null; |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| } |
| if (event.detail != -1) { |
| String appRole = roleToOs (event.detail); |
| int index = appRole.indexOf(':'); |
| if (index != -1) appRole = appRole.substring(0, index); |
| returnValue = NSString.stringWith(appRole); |
| } |
| |
| return returnValue; |
| } |
| |
| id getSubroleAttribute (int childID) { |
| id returnValue = null; |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| } |
| if (event.detail != -1) { |
| String appRole = roleToOs (event.detail); |
| int index = appRole.indexOf(':'); |
| if (index != -1) { |
| appRole = appRole.substring(index + 1); |
| returnValue = NSString.stringWith(appRole); |
| } |
| } |
| return returnValue; |
| } |
| |
| id getRoleDescriptionAttribute (int childID) { |
| id returnValue = null; |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| } |
| if (event.detail != -1) { |
| if (event.detail == ACC.ROLE_TABITEM) { |
| returnValue = new NSString(OS.NSAccessibilityRoleDescription (NSString.stringWith("AXTab").id, 0)); |
| } else { |
| String appRole = roleToOs (event.detail); |
| String appSubrole = null; |
| int index = appRole.indexOf(':'); |
| if (index != -1) { |
| appSubrole = appRole.substring(index + 1); |
| appRole = appRole.substring(0, index); |
| } |
| NSString nsAppRole = NSString.stringWith(appRole); |
| NSString nsAppSubrole = null; |
| |
| if (appSubrole != null) nsAppSubrole = NSString.stringWith(appSubrole); |
| returnValue = new NSString(OS.NSAccessibilityRoleDescription (((nsAppRole != null) ? nsAppRole.id : 0), (nsAppSubrole != null) ? nsAppSubrole.id : 0)); |
| } |
| } |
| return returnValue; |
| } |
| |
| id getTitleAttribute (int childID) { |
| |
| id returnValue = null; |
| |
| /* |
| * Feature of the Macintosh. The text of a Label is returned in its value, |
| * not its title, so ensure that the role is not Label before asking for the title. |
| */ |
| AccessibleControlEvent roleEvent = new AccessibleControlEvent(this); |
| roleEvent.childID = childID; |
| roleEvent.detail = -1; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(roleEvent); |
| } |
| if (roleEvent.detail != ACC.ROLE_LABEL) { |
| AccessibleEvent event = new AccessibleEvent(this); |
| event.childID = childID; |
| event.result = null; |
| for (int i = 0; i < accessibleListenersSize(); i++) { |
| AccessibleListener listener = accessibleListeners.get(i); |
| listener.getName(event); |
| } |
| |
| if (event.result != null) |
| returnValue = NSString.stringWith(event.result); |
| } |
| return returnValue; |
| } |
| |
| id getTitleUIElementAttribute(int childID) { |
| id returnValue = null; |
| Relation relation = relations[ACC.RELATION_LABELLED_BY]; |
| if (relation != null) { |
| returnValue = relation.getTitleUIElement(); |
| } |
| return returnValue; |
| } |
| |
| id getValueAttribute (int childID) { |
| id returnValue = null; |
| if (accessibleValueListenersSize() > 0) { |
| AccessibleValueEvent event = new AccessibleValueEvent(this); |
| for (int i = 0; i < accessibleValueListenersSize(); i++) { |
| AccessibleValueListener listener = accessibleValueListeners.get(i); |
| listener.getCurrentValue(event); |
| } |
| returnValue = NSNumber.numberWithDouble(event.value.doubleValue()); |
| } else { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; |
| event.result = null; //TODO: could pass the OS value to the app |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(event); |
| listener.getValue(event); |
| } |
| int role = event.detail; |
| String value = event.result; |
| |
| switch (role) { |
| case ACC.ROLE_RADIOBUTTON: // 1 = on, 0 = off |
| case ACC.ROLE_CHECKBUTTON: // 1 = checked, 0 = unchecked, 2 = mixed |
| case ACC.ROLE_SCROLLBAR: // numeric value representing the position of the scroller |
| case ACC.ROLE_SLIDER: // the value associated with the position of the slider thumb |
| case ACC.ROLE_PROGRESSBAR: // the value associated with the fill level of the progress bar |
| if (value != null) { |
| try { |
| int number = Integer.parseInt(value); |
| returnValue = NSNumber.numberWithBool(number == 0 ? false : true); |
| } catch (NumberFormatException ex) { |
| if (value.equalsIgnoreCase("true")) { |
| returnValue = NSNumber.numberWithBool(true); |
| } else if (value.equalsIgnoreCase("false")) { |
| returnValue = NSNumber.numberWithBool(false); |
| } |
| } |
| } else { |
| returnValue = NSNumber.numberWithBool(false); |
| } |
| break; |
| case ACC.ROLE_TABFOLDER: // the accessibility object representing the currently selected tab item |
| case ACC.ROLE_TABITEM: // 1 = selected, 0 = not selected |
| AccessibleControlEvent ace = new AccessibleControlEvent(this); |
| ace.childID = -4; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getSelection(ace); |
| } |
| if (ace.childID >= ACC.CHILDID_SELF) { |
| if (role == ACC.ROLE_TABITEM) { |
| returnValue = NSNumber.numberWithBool(ace.childID == childID); |
| } else { |
| returnValue = new id(OS.NSAccessibilityUnignoredAncestor(childIDToOs(ace.childID).id)); |
| } |
| } else { |
| returnValue = NSNumber.numberWithBool(false); |
| } |
| break; |
| case ACC.ROLE_COMBOBOX: // text of the currently selected item |
| case ACC.ROLE_TEXT: // text in the text field |
| case ACC.ROLE_PARAGRAPH: // text in the text field |
| case ACC.ROLE_HEADING: // text in the text field |
| if (value != null) returnValue = NSString.stringWith(value); |
| break; |
| case ACC.ROLE_TABLECELL: // text in the cell |
| case ACC.ROLE_LABEL: // text in the label |
| /* On a Mac, the 'value' of a label is the same as the 'name' of the label. */ |
| AccessibleEvent e = new AccessibleEvent(this); |
| e.childID = childID; |
| e.result = null; |
| for (int i = 0; i < accessibleListenersSize(); i++) { |
| AccessibleListener listener = accessibleListeners.get(i); |
| listener.getName(e); |
| } |
| if (e.result != null) { |
| returnValue = NSString.stringWith(e.result); |
| } else { |
| if (value != null) returnValue = NSString.stringWith(value); |
| } |
| returnValue = returnValue == null ? NSString.string() : returnValue; |
| break; |
| } |
| } |
| return returnValue; |
| } |
| |
| id getEnabledAttribute (int childID) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.detail = ACC.STATE_NORMAL; |
| event.childID = childID; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getState(event); |
| } |
| boolean enabled = (event.detail & ACC.STATE_DISABLED) == 0; |
| if (!enabled && delegate == null) enabled = control.isEnabled(); |
| return NSNumber.numberWithBool(enabled); |
| } |
| |
| id getFocusedAttribute (int childID) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = ACC.CHILDID_MULTIPLE; // set to invalid value, to test if the application sets it in getFocus() |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getFocus(event); |
| } |
| |
| /* The application can optionally answer an accessible. */ |
| if (event.accessible != null) { |
| boolean hasFocus = (event.accessible.index == childID) && (event.accessible.control == this.control); |
| return NSNumber.numberWithBool(hasFocus); |
| } |
| |
| /* Or the application can answer a valid child ID, including CHILDID_SELF and CHILDID_NONE. */ |
| if (event.childID == ACC.CHILDID_SELF) { |
| return NSNumber.numberWithBool(true); |
| } |
| if (event.childID == ACC.CHILDID_NONE) { |
| return NSNumber.numberWithBool(false); |
| } |
| if (event.childID != ACC.CHILDID_MULTIPLE) { |
| /* Other valid childID. */ |
| return NSNumber.numberWithBool(event.childID == childID); |
| } |
| |
| // Invalid childID at this point means the application did not implement getFocus, so |
| // let the default handler return the native focus. |
| return null; |
| } |
| |
| id getParentAttribute (int childID) { |
| id returnValue = null; |
| if (childID == ACC.CHILDID_SELF) { |
| if (parent != null) { |
| if (parent.delegate != null) { |
| returnValue = parent.delegate; |
| } else { |
| returnValue = new id(OS.NSAccessibilityUnignoredAncestor(accessibleHandle(parent).id)); |
| } |
| } else { |
| // Returning null here means 'let Cocoa figure it out.' |
| returnValue = null; |
| } |
| } else { |
| returnValue = new id(OS.NSAccessibilityUnignoredAncestor(accessibleHandle(this).id)); |
| } |
| return returnValue; |
| } |
| |
| id getChildrenAttribute (int childID, boolean visibleOnly) { |
| id returnValue = null; |
| if (childID == ACC.CHILDID_SELF) { |
| // Test for a table first. |
| if (currentRole == ACC.ROLE_TABLE) { |
| // If the row count differs from the row elements returned, |
| // we need to create our own adapter to map the cells onto |
| // rows and columns. The rows and columns attributes determine that for us. |
| getRowsAttribute(childID); |
| getColumnsAttribute(childID); |
| } |
| |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; // set to impossible value to test if app resets |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getChildCount(event); |
| } |
| int childCount = event.detail; |
| event.detail = (visibleOnly ? ACC.VISIBLE : 0); |
| if (childCount >= 0) { |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getChildren(event); |
| } |
| Object[] children = event.children; |
| childCount = children != null ? children.length : 0; |
| NSMutableArray childArray = NSMutableArray.arrayWithCapacity(childCount); |
| for (int i = 0; i < childCount; i++) { |
| Object child = children[i]; |
| if (child instanceof Accessible) { |
| Accessible accessible = (Accessible)child; |
| if (accessible.delegate != null) { |
| childArray.addObject(accessible.delegate); |
| } else { |
| childArray.addObject(accessibleHandle(accessible)); |
| } |
| } else { |
| if (child instanceof Integer) { |
| id accChild = childIDToOs(((Integer)child).intValue()); |
| childArray.addObject(accChild); |
| } |
| } |
| } |
| returnValue = new id(OS.NSAccessibilityUnignoredChildren(childArray.id)); |
| } |
| } else { |
| // Lightweight children have no children of their own. |
| // Don't return null if there are no children -- always return an empty array. |
| returnValue = NSArray.array(); |
| } |
| |
| // Returning null here means we want the control itself to determine its children. If the accessible listener |
| // implemented getChildCount/getChildren, references to those objects would have been returned above. |
| return returnValue; |
| } |
| |
| id getTabsAttribute (int childID) { |
| id returnValue = null; |
| if (childID == ACC.CHILDID_SELF) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.detail = -1; // set to impossible value to test if app resets |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getChildCount(event); |
| } |
| if (event.detail > 0) { |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getChildren(event); |
| } |
| Object [] appChildren = event.children; |
| if (appChildren != null && appChildren.length > 0) { |
| /* return an NSArray of NSAccessible objects. */ |
| NSMutableArray childArray = NSMutableArray.arrayWithCapacity(appChildren.length); |
| |
| for (int i = 0; i < appChildren.length; i++) { |
| Object child = appChildren[i]; |
| if (child instanceof Integer) { |
| int subChildID = ((Integer)child).intValue(); |
| event.childID = subChildID; |
| event.detail = -1; |
| for (int j = 0; j < accessibleControlListenersSize(); j++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(j); |
| listener.getRole(event); |
| } |
| |
| if (event.detail == ACC.ROLE_TABITEM) { |
| id accChild = childIDToOs(((Integer)child).intValue()); |
| childArray.addObject(accChild); |
| } |
| } else { |
| childArray.addObject(((Accessible)child).control.view); |
| } |
| } |
| |
| returnValue = new id(OS.NSAccessibilityUnignoredChildren(childArray.id)); |
| } |
| } |
| } else { |
| // Lightweight children have no children of their own. |
| // Don't return null if there are no children -- always return an empty array. |
| returnValue = NSArray.array(); |
| } |
| |
| // Returning null here means we want the control itself to determine its children. If the accessible listener |
| // implemented getChildCount/getChildren, references to those objects would have been returned above. |
| return returnValue; |
| } |
| |
| id getWindowAttribute (int childID) { |
| return control.view.window(); |
| } |
| |
| id getTopLevelUIElementAttribute (int childID) { |
| return control.view.window(); |
| } |
| |
| id getPositionAttribute (int childID) { |
| id returnValue = null; |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.width = -1; |
| |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getLocation(event); |
| } |
| |
| Monitor primaryMonitor = Display.getCurrent().getPrimaryMonitor(); |
| |
| NSPoint osPositionAttribute = new NSPoint (); |
| if (event.width != -1) { |
| // The point returned is the lower-left coordinate of the widget in lower-left relative screen coordinates. |
| osPositionAttribute.x = event.x; |
| osPositionAttribute.y = primaryMonitor.getBounds().height - event.y - event.height; |
| returnValue = NSValue.valueWithPoint(osPositionAttribute); |
| } else { |
| if (childID != ACC.CHILDID_SELF) { |
| Point pt = null; |
| Rectangle location = control.getBounds(); |
| |
| if (control.getParent() != null) |
| pt = control.getParent().toDisplay(location.x, location.y); |
| else |
| pt = ((Shell)control).toDisplay(location.x, location.y); |
| |
| osPositionAttribute.x = pt.x; |
| osPositionAttribute.y = pt.y; |
| returnValue = NSValue.valueWithPoint(osPositionAttribute); |
| } |
| } |
| |
| return returnValue; |
| } |
| |
| id getSizeAttribute (int childID) { |
| id returnValue = null; |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.width = -1; |
| |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getLocation(event); |
| } |
| |
| NSSize controlSize = new NSSize (); |
| if (event.width != -1) { |
| controlSize.width = event.width; |
| controlSize.height = event.height; |
| returnValue = NSValue.valueWithSize(controlSize); |
| } else { |
| if (childID != ACC.CHILDID_SELF) { |
| controlSize.width = controlSize.height = 0; |
| returnValue = NSValue.valueWithSize(controlSize); |
| } |
| } |
| |
| return returnValue; |
| } |
| |
| id getCellForColumnAndRowParameter(id parameter, int childID) { |
| id returnValue = null; |
| NSArray parameterObject = new NSArray(parameter.id); |
| if (parameterObject.count() == 2) { |
| AccessibleTableEvent event = new AccessibleTableEvent(this); |
| event.column = new NSNumber(parameterObject.objectAtIndex(0)).intValue(); |
| event.row = new NSNumber(parameterObject.objectAtIndex(1)).intValue(); |
| for (int i = 0; i < accessibleTableListenersSize(); i++) { |
| AccessibleTableListener listener = accessibleTableListeners.get(i); |
| listener.getCell(event); |
| returnValue = event.accessible.delegate; |
| } |
| } |
| return returnValue; |
| } |
| |
| id getDescriptionAttribute (int childID) { |
| AccessibleEvent event = new AccessibleEvent(this); |
| event.childID = childID; |
| event.result = null; |
| id returnValue = null; |
| for (int i = 0; i < accessibleListenersSize(); i++) { |
| AccessibleListener listener = accessibleListeners.get(i); |
| listener.getDescription(event); |
| } |
| |
| returnValue = (event.result != null ? NSString.stringWith(event.result) : null); |
| |
| // If no description was provided, and this is a composite or canvas, return a blank string |
| // -- otherwise, let the Cocoa control handle it. |
| if (returnValue == null) { |
| if (control instanceof Composite) returnValue = NSString.string(); |
| } |
| |
| return returnValue; |
| } |
| |
| id getInsertionPointLineNumberAttribute (int childID) { |
| id returnValue = null; |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getCaretOffset(event); |
| } |
| int caretOffset = event.offset; |
| event.start = caretOffset; |
| event.end = caretOffset; |
| event.count = Integer.MIN_VALUE; |
| event.type = ACC.TEXT_BOUNDARY_LINE; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getText(event); |
| } |
| returnValue = NSNumber.numberWithInt(Math.max(0, -event.count)); |
| } else { |
| AccessibleControlEvent controlEvent = new AccessibleControlEvent(this); |
| controlEvent.childID = childID; |
| controlEvent.result = null; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getValue(controlEvent); |
| } |
| AccessibleTextEvent textEvent = new AccessibleTextEvent(this); |
| textEvent.childID = childID; |
| textEvent.offset = -1; |
| for (int i = 0; i < accessibleTextListenersSize(); i++) { |
| AccessibleTextListener listener = accessibleTextListeners.get(i); |
| listener.getCaretOffset(textEvent); |
| } |
| if (controlEvent.result != null && textEvent.offset != -1) { |
| int lineNumber = lineNumberForOffset (controlEvent.result, textEvent.offset); |
| returnValue = NSNumber.numberWithInt(lineNumber); |
| } |
| } |
| return returnValue; |
| } |
| |
| id getLineForIndexParameterizedAttribute (id parameter, int childID) { |
| id returnValue = null; |
| NSNumber charNumberObj = new NSNumber(parameter.id); |
| int charNumber = charNumberObj.intValue(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.start = charNumber; |
| event.end = charNumber; |
| event.count = Integer.MIN_VALUE; |
| event.type = ACC.TEXT_BOUNDARY_LINE; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getText(event); |
| } |
| returnValue = NSNumber.numberWithInt(Math.max(0, -event.count)); |
| } else { |
| AccessibleControlEvent controlEvent = new AccessibleControlEvent(this); |
| controlEvent.childID = childID; |
| controlEvent.result = null; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getValue(controlEvent); |
| } |
| String text = controlEvent.result; |
| if (text != null) returnValue = NSNumber.numberWithInt(lineNumberForOffset(text, charNumber)); |
| } |
| return returnValue; |
| } |
| |
| id getMaxValueAttribute(int childID) { |
| id returnValue = null; |
| if (accessibleValueListenersSize() > 0) { |
| AccessibleValueEvent event = new AccessibleValueEvent(this); |
| for (int i = 0; i < accessibleValueListenersSize(); i++) { |
| AccessibleValueListener listener = accessibleValueListeners.get(i); |
| listener.getMaximumValue(event); |
| } |
| returnValue = NSNumber.numberWithDouble(event.value.doubleValue()); |
| } |
| return returnValue; |
| } |
| |
| id getMinValueAttribute(int childID) { |
| id returnValue = null; |
| if (accessibleValueListenersSize() > 0) { |
| AccessibleValueEvent event = new AccessibleValueEvent(this); |
| for (int i = 0; i < accessibleValueListenersSize(); i++) { |
| AccessibleValueListener listener = accessibleValueListeners.get(i); |
| listener.getMinimumValue(event); |
| } |
| returnValue = NSNumber.numberWithDouble(event.value.doubleValue()); |
| } |
| return returnValue; |
| } |
| |
| id getNumberOfCharactersAttribute (int childID) { |
| id returnValue = null; |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.count = -1; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getCharacterCount(event); |
| } |
| if (event.count != -1) { |
| AccessibleControlEvent e = new AccessibleControlEvent(this); |
| e.childID = ACC.CHILDID_SELF; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getRole(e); |
| listener.getValue(e); |
| } |
| // TODO: Consider passing the value through for other roles as well (i.e. combo, etc). Keep in sync with get_text. |
| event.count = e.detail == ACC.ROLE_TEXT && e.result != null ? e.result.length() : 0; |
| returnValue = NSNumber.numberWithInt(event.count); |
| } |
| return returnValue; |
| } |
| |
| id getRangeForLineParameterizedAttribute (id parameter, int childID) { |
| id returnValue = null; |
| // The parameter is an NSNumber with the line number. |
| NSNumber lineNumberObj = new NSNumber(parameter.id); |
| int lineNumber = lineNumberObj.intValue(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.start = event.end = 0; |
| event.count = lineNumber; |
| event.type = ACC.TEXT_BOUNDARY_LINE; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getText(event); |
| } |
| NSRange range = new NSRange(); |
| range.location = event.start; |
| range.length = event.end - event.start; |
| returnValue = NSValue.valueWithRange(range); |
| } else if (accessibleControlListenersSize() > 0){ |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.result = null; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getValue(event); |
| } |
| if (event.result != null) { |
| NSRange range = rangeForLineNumber (lineNumber, event.result); |
| if (range.location != -1) { |
| returnValue = NSValue.valueWithRange(range); |
| } |
| } |
| } |
| return returnValue; |
| } |
| |
| id getRangeForIndexParameterizedAttribute (id parameter, int childID) { |
| id returnValue = null; |
| // The parameter is an NSNumber with the character number. |
| NSNumber charNumberObj = new NSNumber(parameter.id); |
| int charNumber = charNumberObj.intValue(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.start = event.end = 0; |
| event.count = charNumber; |
| event.type = ACC.TEXT_BOUNDARY_CHAR; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getText(event); |
| } |
| NSRange range = new NSRange(); |
| range.location = event.start; |
| range.length = event.end - event.start; |
| returnValue = NSValue.valueWithRange(range); |
| } else if (accessibleControlListenersSize() > 0) { |
| // AccessibleControlEvent event = new AccessibleControlEvent(this); |
| // event.childID = childID; |
| // event.result = null; |
| // for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| // AccessibleControlListener listener = accessibleControlListeners.get(i); |
| // listener.getValue(event); |
| // } |
| // if (event.result != null) { |
| // NSRange range = rangeForLineNumber (lineNumber, event.result); |
| // if (range.location != -1) { |
| // returnValue = NSValue.valueWithRange(range); |
| // } |
| // } |
| } |
| return returnValue; |
| } |
| |
| id getSelectedTextAttribute (int childID) { |
| id returnValue = NSString.string(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.index = 0; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getSelection(event); |
| } |
| int start = event.start; |
| int end = event.end; |
| if (start != end) { |
| event.type = ACC.TEXT_BOUNDARY_ALL; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getText(event); |
| } |
| } |
| String text = event.result; |
| if (text != null) returnValue = NSString.stringWith(text); |
| } else if (accessibleTextListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.offset = -1; |
| event.length = -1; |
| for (int i = 0; i < accessibleTextListenersSize(); i++) { |
| AccessibleTextListener listener = accessibleTextListeners.get(i); |
| listener.getSelectionRange(event); |
| } |
| int offset = event.offset; |
| int length = event.length; |
| if (offset != -1 && length != -1 && length != 0) { // TODO: do we need the && length != 0 ? |
| AccessibleControlEvent event2 = new AccessibleControlEvent(this); |
| event2.childID = event.childID; |
| event2.result = null; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getValue(event2); |
| } |
| String appValue = event2.result; |
| if (appValue != null) { |
| returnValue = NSString.stringWith(appValue.substring(offset, offset + length)); |
| } |
| } |
| } |
| return returnValue; |
| } |
| |
| id getSelectedTextRangeAttribute (int childID) { |
| id returnValue = null; |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.index = 0; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getSelection(event); |
| } |
| NSRange range = new NSRange(); |
| range.location = event.start; |
| range.length = event.end - event.start; |
| returnValue = NSValue.valueWithRange(range); |
| } else if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.offset = -1; |
| event.length = 0; |
| for (int i = 0; i < accessibleTextListenersSize(); i++) { |
| AccessibleTextListener listener = accessibleTextListeners.get(i); |
| listener.getSelectionRange(event); |
| } |
| if (event.offset != -1) { |
| NSRange range = new NSRange(); |
| range.location = event.offset; |
| range.length = event.length; |
| returnValue = NSValue.valueWithRange(range); |
| } |
| } |
| return returnValue; |
| } |
| |
| id getServesAsTitleForUIElementsAttribute(int childID) { |
| id returnValue = null; |
| Relation relation = relations[ACC.RELATION_LABEL_FOR]; |
| if (relation != null) returnValue = relation.getServesAsTitleForUIElements(); |
| return returnValue; |
| } |
| |
| id getStringForRangeParameterizedAttribute (id parameter, int childID) { |
| id returnValue = null; |
| |
| // Parameter is an NSRange wrapped in an NSValue. |
| NSValue parameterObject = new NSValue(parameter.id); |
| NSRange range = parameterObject.rangeValue(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.start = (int) /*64*/ range.location; |
| event.end = (int) /*64*/ (range.location + range.length); |
| event.type = ACC.TEXT_BOUNDARY_ALL; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getText(event); |
| } |
| if (event.result != null) returnValue = NSString.stringWith(event.result); |
| } else if (accessibleControlListenersSize() > 0) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.result = null; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getValue(event); |
| } |
| String appValue = event.result; |
| |
| if (appValue != null) { |
| returnValue = NSString.stringWith(appValue.substring((int)/*64*/range.location, (int)/*64*/(range.location + range.length))); |
| } |
| } |
| return returnValue; |
| } |
| |
| id getSelectedTextRangesAttribute (int childID) { |
| NSMutableArray returnValue = NSMutableArray.arrayWithCapacity(3); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getSelectionCount(event); |
| } |
| if (event.count > 0) { |
| for (int i = 0; i < event.count; i++) { |
| event.index = i; |
| for (int j = 0; j < accessibleTextExtendedListenersSize(); j++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(j); |
| listener.getSelection(event); |
| } |
| NSRange range = new NSRange(); |
| range.location = event.start; |
| range.length = event.end - event.start; |
| returnValue.addObject(NSValue.valueWithRange(range)); |
| } |
| } |
| } else if (accessibleTextListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| event.offset = -1; |
| event.length = 0; |
| |
| for (int i = 0; i < accessibleTextListenersSize(); i++) { |
| AccessibleTextListener listener = accessibleTextListeners.get(i); |
| listener.getSelectionRange(event); |
| } |
| |
| if (event.offset != -1) { |
| NSRange range = new NSRange(); |
| range.location = event.offset; |
| range.length = event.length; |
| returnValue.addObject(NSValue.valueWithRange(range)); |
| } |
| } |
| if (returnValue.count() == 0) { |
| returnValue.addObject(NSValue.valueWithRange(new NSRange())); |
| } |
| return returnValue; |
| } |
| |
| id getStyleRangeForIndexAttribute (id parameter, int childID) { |
| if (accessibleAttributeListenersSize() == 0) return null; |
| |
| // Parameter is an NSRange wrapped in an NSValue. |
| NSNumber parameterObject = new NSNumber(parameter.id); |
| int index = parameterObject.intValue(); |
| |
| AccessibleTextAttributeEvent event = new AccessibleTextAttributeEvent(this); |
| event.offset = (int) /*64*/ index; |
| |
| // Marker values -- if -1 after calling getTextAttributes, no one implemented it. |
| event.start = event.end = -1; |
| |
| for (int i = 0; i < accessibleAttributeListenersSize(); i++) { |
| AccessibleAttributeListener listener = accessibleAttributeListeners.get(i); |
| listener.getTextAttributes(event); |
| } |
| |
| NSRange range = new NSRange(); |
| if (event.start == -1 && event.end == -1) { |
| range.location = index; |
| range.length = 0; |
| } else { |
| range.location = event.start; |
| range.length = event.end - event.start; |
| } |
| |
| return NSValue.valueWithRange(range); |
| } |
| |
| id getVisibleCharacterRangeAttribute (int childID) { |
| NSRange range = null; |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.childID = childID; |
| for (int i=0; i<accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.getVisibleRanges(event); |
| } |
| range = new NSRange(); |
| range.location = event.start; |
| range.length = event.end - event.start; |
| } else if (accessibleControlListenersSize() > 0) { |
| AccessibleControlEvent event = new AccessibleControlEvent(this); |
| event.childID = childID; |
| event.result = null; |
| for (int i = 0; i < accessibleControlListenersSize(); i++) { |
| AccessibleControlListener listener = accessibleControlListeners.get(i); |
| listener.getValue(event); |
| } |
| if (event.result != null) { |
| range = new NSRange(); |
| range.location = 0; |
| range.length = event.result.length(); |
| } |
| } |
| |
| return (range != null) ? NSValue.valueWithRange(range) : null; |
| } |
| |
| int lineNumberForOffset (String text, int offset) { |
| int lineNumber = 1; |
| int length = text.length(); |
| for (int i = 0; i < offset; i++) { |
| switch (text.charAt (i)) { |
| case '\r': |
| if (i + 1 < length) { |
| if (text.charAt (i + 1) == '\n') ++i; |
| } |
| // FALL THROUGH |
| case '\n': |
| lineNumber++; |
| } |
| } |
| return lineNumber; |
| } |
| |
| NSRange rangeForLineNumber (int lineNumber, String text) { |
| NSRange range = new NSRange(); |
| range.location = -1; |
| int line = 1; |
| int count = 0; |
| int length = text.length (); |
| for (int i = 0; i < length; i++) { |
| if (line == lineNumber) { |
| if (count == 0) { |
| range.location = i; |
| } |
| count++; |
| } |
| if (line > lineNumber) break; |
| switch (text.charAt (i)) { |
| case '\r': |
| if (i + 1 < length && text.charAt (i + 1) == '\n') i++; |
| // FALL THROUGH |
| case '\n': |
| line++; |
| } |
| } |
| range.length = count; |
| return range; |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when an accessible client asks for certain strings, |
| * such as name, description, help, or keyboard shortcut. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for a name, description, help, or keyboard shortcut string |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleListener |
| * @see #addAccessibleListener |
| */ |
| public void removeAccessibleListener(AccessibleListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleListeners != null) { |
| accessibleListeners.remove(listener); |
| if (accessibleListeners.isEmpty()) accessibleListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when an accessible client asks for custom control |
| * specific information. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for custom control specific information |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleControlListener |
| * @see #addAccessibleControlListener |
| */ |
| public void removeAccessibleControlListener(AccessibleControlListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleControlListeners != null) { |
| accessibleControlListeners.remove(listener); |
| if (accessibleControlListeners.isEmpty()) accessibleControlListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners who will |
| * be notified when an accessible client asks for custom text control |
| * specific information. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for custom text control specific information |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleTextListener |
| * @see AccessibleTextExtendedListener |
| * @see #addAccessibleTextListener |
| * |
| * @since 3.0 |
| */ |
| public void removeAccessibleTextListener (AccessibleTextListener listener) { |
| checkWidget (); |
| if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); |
| if (listener instanceof AccessibleTextExtendedListener) { |
| if (accessibleTextExtendedListeners != null) { |
| accessibleTextExtendedListeners.remove(listener); |
| if (accessibleTextExtendedListeners.isEmpty()) accessibleTextExtendedListeners = null; |
| } |
| } else { |
| if (accessibleTextListeners != null) { |
| accessibleTextListeners.remove(listener); |
| if (accessibleTextListeners.isEmpty()) accessibleTextListeners = null; |
| } |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleActionListener</code> interface. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for <code>AccessibleActionListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleActionListener |
| * @see #addAccessibleActionListener |
| * |
| * @since 3.6 |
| */ |
| public void removeAccessibleActionListener(AccessibleActionListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleActionListeners != null) { |
| accessibleActionListeners.remove(listener); |
| if (accessibleActionListeners.isEmpty()) accessibleActionListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleEditableTextListener</code> interface. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for <code>AccessibleEditableTextListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleEditableTextListener |
| * @see #addAccessibleEditableTextListener |
| * |
| * @since 3.7 |
| */ |
| public void removeAccessibleEditableTextListener(AccessibleEditableTextListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleEditableTextListeners != null) { |
| accessibleEditableTextListeners.remove(listener); |
| if (accessibleEditableTextListeners.isEmpty()) accessibleEditableTextListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleHyperlinkListener</code> interface. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for <code>AccessibleHyperlinkListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleHyperlinkListener |
| * @see #addAccessibleHyperlinkListener |
| * |
| * @since 3.6 |
| */ |
| public void removeAccessibleHyperlinkListener(AccessibleHyperlinkListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleHyperlinkListeners != null) { |
| accessibleHyperlinkListeners.remove(listener); |
| if (accessibleHyperlinkListeners.isEmpty()) accessibleHyperlinkListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleTableListener</code> interface. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for <code>AccessibleTableListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleTableListener |
| * @see #addAccessibleTableListener |
| * |
| * @since 3.6 |
| */ |
| public void removeAccessibleTableListener(AccessibleTableListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleTableListeners != null) { |
| accessibleTableListeners.remove(listener); |
| if (accessibleTableListeners.isEmpty()) accessibleTableListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleTableCellListener</code> interface. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for <code>AccessibleTableCellListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleTableCellListener |
| * @see #addAccessibleTableCellListener |
| * |
| * @since 3.6 |
| */ |
| public void removeAccessibleTableCellListener(AccessibleTableCellListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleTableCellListeners != null) { |
| accessibleTableCellListeners.remove(listener); |
| if (accessibleTableCellListeners.isEmpty()) accessibleTableCellListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleValueListener</code> interface. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for <code>AccessibleValueListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleValueListener |
| * @see #addAccessibleValueListener |
| * |
| * @since 3.6 |
| */ |
| public void removeAccessibleValueListener(AccessibleValueListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleValueListeners != null) { |
| accessibleValueListeners.remove(listener); |
| if (accessibleValueListeners.isEmpty()) accessibleValueListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the listener from the collection of listeners that will be |
| * notified when an accessible client asks for any of the properties |
| * defined in the <code>AccessibleAttributeListener</code> interface. |
| * |
| * @param listener the listener that should no longer be notified when the receiver |
| * is asked for <code>AccessibleAttributeListener</code> interface properties |
| * |
| * @exception IllegalArgumentException <ul> |
| * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
| * </ul> |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see AccessibleAttributeListener |
| * @see #addAccessibleAttributeListener |
| * |
| * @since 3.6 |
| */ |
| public void removeAccessibleAttributeListener(AccessibleAttributeListener listener) { |
| checkWidget(); |
| if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); |
| if (accessibleAttributeListeners != null) { |
| accessibleAttributeListeners.remove(listener); |
| if (accessibleAttributeListeners.isEmpty()) accessibleAttributeListeners = null; |
| } |
| } |
| |
| /** |
| * Removes the relation with the specified type and target |
| * from the receiver's set of relations. |
| * |
| * @param type an <code>ACC</code> constant beginning with RELATION_* indicating the type of relation |
| * @param target the accessible that is the target for this relation |
| * @exception IllegalArgumentException ERROR_NULL_ARGUMENT - if the Accessible target is null |
| * @since 3.6 |
| */ |
| public void removeRelation(int type, Accessible target) { |
| checkWidget(); |
| if (target == null) SWT.error (SWT.ERROR_NULL_ARGUMENT); |
| if (relations[type] != null) { |
| relations[type].removeTarget(target); |
| } |
| } |
| |
| void release(boolean destroy) { |
| if (actionNames != null) actionNames.release(); |
| actionNames = null; |
| if (attributeNames != null) attributeNames.release(); |
| attributeNames = null; |
| if (parameterizedAttributeNames != null) parameterizedAttributeNames.release(); |
| parameterizedAttributeNames = null; |
| if (delegate != null) { |
| delegate.internal_dispose_SWTAccessibleDelegate(); |
| delegate.release(); |
| } |
| delegate = null; |
| relations = null; |
| |
| if (childToIdMap != null) { |
| Collection delegates = childToIdMap.values(); |
| Iterator iter = delegates.iterator(); |
| while (iter.hasNext()) { |
| SWTAccessibleDelegate childDelegate = (SWTAccessibleDelegate)iter.next(); |
| childDelegate.internal_dispose_SWTAccessibleDelegate(); |
| childDelegate.release(); |
| } |
| childToIdMap.clear(); |
| childToIdMap = null; |
| } |
| |
| if (tableDelegate != null) tableDelegate.release(); |
| } |
| |
| static NSArray retainedAutoreleased(NSArray inObject) { |
| id temp = inObject.retain(); |
| id temp2 = new NSObject(temp.id).autorelease(); |
| return new NSArray(temp2.id); |
| } |
| |
| /** |
| * Sends a message with event-specific data to accessible clients |
| * indicating that something has changed within a custom control. |
| * |
| * @param event an <code>ACC</code> constant beginning with EVENT_* indicating the message to send |
| * @param eventData an object containing event-specific data, or null if there is no event-specific data |
| * (eventData is specified in the documentation for individual ACC.EVENT_* constants) |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see ACC#EVENT_ACTION_CHANGED |
| * @see ACC#EVENT_ATTRIBUTE_CHANGED |
| * @see ACC#EVENT_DESCRIPTION_CHANGED |
| * @see ACC#EVENT_DOCUMENT_LOAD_COMPLETE |
| * @see ACC#EVENT_DOCUMENT_LOAD_STOPPED |
| * @see ACC#EVENT_DOCUMENT_RELOAD |
| * @see ACC#EVENT_HYPERLINK_ACTIVATED |
| * @see ACC#EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED |
| * @see ACC#EVENT_HYPERLINK_END_INDEX_CHANGED |
| * @see ACC#EVENT_HYPERLINK_SELECTED_LINK_CHANGED |
| * @see ACC#EVENT_HYPERLINK_START_INDEX_CHANGED |
| * @see ACC#EVENT_HYPERTEXT_LINK_COUNT_CHANGED |
| * @see ACC#EVENT_HYPERTEXT_LINK_SELECTED |
| * @see ACC#EVENT_LOCATION_CHANGED |
| * @see ACC#EVENT_NAME_CHANGED |
| * @see ACC#EVENT_PAGE_CHANGED |
| * @see ACC#EVENT_SECTION_CHANGED |
| * @see ACC#EVENT_SELECTION_CHANGED |
| * @see ACC#EVENT_STATE_CHANGED |
| * @see ACC#EVENT_TABLE_CAPTION_CHANGED |
| * @see ACC#EVENT_TABLE_CHANGED |
| * @see ACC#EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED |
| * @see ACC#EVENT_TABLE_COLUMN_HEADER_CHANGED |
| * @see ACC#EVENT_TABLE_ROW_DESCRIPTION_CHANGED |
| * @see ACC#EVENT_TABLE_ROW_HEADER_CHANGED |
| * @see ACC#EVENT_TABLE_SUMMARY_CHANGED |
| * @see ACC#EVENT_TEXT_ATTRIBUTE_CHANGED |
| * @see ACC#EVENT_TEXT_CARET_MOVED |
| * @see ACC#EVENT_TEXT_CHANGED |
| * @see ACC#EVENT_TEXT_COLUMN_CHANGED |
| * @see ACC#EVENT_TEXT_SELECTION_CHANGED |
| * @see ACC#EVENT_VALUE_CHANGED |
| * |
| * @since 3.6 |
| */ |
| public void sendEvent(int event, Object eventData) { |
| checkWidget(); |
| |
| id eventSource = accessibleHandle(this); |
| if (DEBUG) System.out.println("sendEvent: 0x" + Integer.toHexString(event) + ", data = " + eventData + ", source = " + eventSource); |
| |
| switch (event) { |
| case ACC.EVENT_TEXT_CHANGED: |
| case ACC.EVENT_VALUE_CHANGED: |
| case ACC.EVENT_STATE_CHANGED: |
| case ACC.EVENT_PAGE_CHANGED: |
| case ACC.EVENT_SECTION_CHANGED: |
| case ACC.EVENT_ACTION_CHANGED: |
| case ACC.EVENT_HYPERLINK_START_INDEX_CHANGED: |
| case ACC.EVENT_HYPERLINK_END_INDEX_CHANGED: |
| case ACC.EVENT_HYPERLINK_ANCHOR_COUNT_CHANGED: |
| case ACC.EVENT_HYPERLINK_SELECTED_LINK_CHANGED: |
| case ACC.EVENT_HYPERLINK_ACTIVATED: |
| case ACC.EVENT_HYPERTEXT_LINK_COUNT_CHANGED: |
| case ACC.EVENT_ATTRIBUTE_CHANGED: |
| case ACC.EVENT_TABLE_CAPTION_CHANGED: |
| case ACC.EVENT_TABLE_COLUMN_DESCRIPTION_CHANGED: |
| case ACC.EVENT_TABLE_COLUMN_HEADER_CHANGED: |
| case ACC.EVENT_TABLE_ROW_DESCRIPTION_CHANGED: |
| case ACC.EVENT_TABLE_ROW_HEADER_CHANGED: |
| case ACC.EVENT_TABLE_SUMMARY_CHANGED: |
| case ACC.EVENT_TEXT_ATTRIBUTE_CHANGED: |
| case ACC.EVENT_TEXT_COLUMN_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityValueChangedNotification.id); break; |
| |
| case ACC.EVENT_SELECTION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedChildrenChangedNotification.id); break; |
| case ACC.EVENT_TEXT_SELECTION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedTextChangedNotification.id); break; |
| case ACC.EVENT_LOCATION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityMovedNotification.id); break; |
| case ACC.EVENT_NAME_CHANGED: |
| case ACC.EVENT_DESCRIPTION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityTitleChangedNotification.id); break; |
| case ACC.EVENT_TEXT_CARET_MOVED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedTextChangedNotification.id); break; |
| case ACC.EVENT_TABLE_CHANGED: |
| if (tableDelegate != null) { |
| tableDelegate.reset(); |
| getRowsAttribute(ACC.CHILDID_SELF); |
| getColumnsAttribute(ACC.CHILDID_SELF); |
| } |
| if (eventData != null) { |
| int[] eventParams = (int[])eventData; |
| // Slot 2 of the array is the number of rows that were either added or deleted. If non-zero, fire a notification. |
| // Cocoa doesn't have a notification for a change in the number of columns. |
| if (eventParams[2] != 0) OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityRowCountChangedNotification.id); |
| } |
| break; |
| |
| // None of these correspond to anything in Cocoa. |
| case ACC.EVENT_HYPERTEXT_LINK_SELECTED: |
| case ACC.EVENT_DOCUMENT_LOAD_COMPLETE: |
| case ACC.EVENT_DOCUMENT_LOAD_STOPPED: |
| case ACC.EVENT_DOCUMENT_RELOAD: |
| break; |
| |
| } |
| } |
| |
| /** |
| * Sends a message with event-specific data and a childID |
| * to accessible clients, indicating that something has changed |
| * within a custom control. |
| * |
| * NOTE: This API is intended for applications that are still using childIDs. |
| * Moving forward, applications should use accessible objects instead of childIDs. |
| * |
| * @param event an <code>ACC</code> constant beginning with EVENT_* indicating the message to send |
| * @param eventData an object containing event-specific data, or null if there is no event-specific data |
| * (eventData is specified in the documentation for individual ACC.EVENT_* constants) |
| * @param childID an identifier specifying a child of the control |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see ACC#EVENT_DESCRIPTION_CHANGED |
| * @see ACC#EVENT_LOCATION_CHANGED |
| * @see ACC#EVENT_NAME_CHANGED |
| * @see ACC#EVENT_SELECTION_CHANGED |
| * @see ACC#EVENT_STATE_CHANGED |
| * @see ACC#EVENT_TEXT_SELECTION_CHANGED |
| * @see ACC#EVENT_VALUE_CHANGED |
| * |
| * @since 3.8 |
| */ |
| public void sendEvent(int event, Object eventData, int childID) { |
| checkWidget(); |
| |
| id eventSource = childIDToOs(childID); |
| if (DEBUG) System.out.println("sendEvent: 0x" + Integer.toHexString(event) + ", data = " + eventData + ", source = " + eventSource); |
| |
| switch (event) { |
| case ACC.EVENT_VALUE_CHANGED: |
| case ACC.EVENT_STATE_CHANGED: |
| case ACC.EVENT_SELECTION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedChildrenChangedNotification.id); break; |
| case ACC.EVENT_TEXT_SELECTION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedTextChangedNotification.id); break; |
| case ACC.EVENT_LOCATION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityMovedNotification.id); break; |
| case ACC.EVENT_NAME_CHANGED: |
| case ACC.EVENT_DESCRIPTION_CHANGED: |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilityTitleChangedNotification.id); break; |
| } |
| } |
| |
| /** |
| * Sends a message to accessible clients that the child selection |
| * within a custom container control has changed. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @since 3.0 |
| */ |
| public void selectionChanged () { |
| checkWidget(); |
| id eventSource = accessibleHandle(this); |
| if (DEBUG) System.out.println("selectionChanged on " + eventSource); |
| if (currentRole == ACC.ROLE_TABLE) { |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedRowsChangedNotification.id); |
| } else { |
| OS.NSAccessibilityPostNotification(eventSource.id, OS.NSAccessibilitySelectedChildrenChangedNotification.id); |
| } |
| } |
| |
| /** |
| * Sends a message to accessible clients indicating that the focus |
| * has changed within a custom control. |
| * |
| * @param childID an identifier specifying a child of the control |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| */ |
| public void setFocus(int childID) { |
| checkWidget(); |
| id accessible = childIDToOs(childID); |
| if (DEBUG) System.out.println("setFocus on " + accessible); |
| OS.NSAccessibilityPostNotification(accessible.id, OS.NSAccessibilityFocusedUIElementChangedNotification.id); |
| } |
| |
| void setSelectedTextAttribute(id value, int childId) { |
| NSString newText = new NSString(value.id); |
| int rangeStart = 0; |
| id charsValue = getNumberOfCharactersAttribute(childId); |
| int rangeEnd = new NSNumber(charsValue).intValue(); |
| id rangeObj = getSelectedTextRangeAttribute(childId); |
| |
| if (rangeObj != null) { |
| NSRange range = new NSValue(rangeObj).rangeValue(); |
| rangeStart = (int)/*64*/range.location; |
| rangeEnd = (int)/*64*/(range.location + range.length); |
| } |
| |
| if (accessibleEditableTextListenersSize() > 0) { |
| AccessibleEditableTextEvent event = new AccessibleEditableTextEvent(this); |
| event.start = rangeStart; |
| event.end = rangeEnd; |
| event.string = newText.getString(); |
| |
| for (int i = 0; i < accessibleEditableTextListenersSize(); i++) { |
| AccessibleEditableTextListener listener = (AccessibleEditableTextListener) accessibleEditableTextListeners.get(i); |
| listener.replaceText(event); |
| } |
| } |
| } |
| |
| void setSelectedTextRangeAttribute(id value, int childId) { |
| NSRange newRange = new NSValue(value.id).rangeValue(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.index = 0; |
| event.start = (int)newRange.location; |
| event.end = (int)(newRange.location + newRange.length); |
| |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.removeSelection(event); |
| listener.addSelection(event); |
| } |
| } |
| } |
| |
| void setVisibleCharacterRangeAttribute(id value, int childId) { |
| NSRange newRange = new NSValue(value.id).rangeValue(); |
| if (accessibleTextExtendedListenersSize() > 0) { |
| AccessibleTextEvent event = new AccessibleTextEvent(this); |
| event.type = ACC.SCROLL_TYPE_TOP_LEFT; |
| event.start = (int)newRange.location; |
| event.end = (int)(newRange.location + newRange.length); |
| |
| for (int i = 0; i < accessibleTextExtendedListenersSize(); i++) { |
| AccessibleTextExtendedListener listener = accessibleTextExtendedListeners.get(i); |
| listener.scrollText(event); |
| } |
| } |
| } |
| |
| /** |
| * Sends a message to accessible clients that the text |
| * caret has moved within a custom control. |
| * |
| * @param index the new caret index within the control |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @since 3.0 |
| */ |
| public void textCaretMoved (int index) { |
| checkWidget(); |
| OS.NSAccessibilityPostNotification(control.view.id, OS.NSAccessibilitySelectedTextChangedNotification.id); |
| } |
| |
| /** |
| * Sends a message to accessible clients that the text |
| * within a custom control has changed. |
| * |
| * @param type the type of change, one of <code>ACC.TEXT_INSERT</code> |
| * or <code>ACC.TEXT_DELETE</code> |
| * @param startIndex the text index within the control where the insertion or deletion begins |
| * @param length the non-negative length in characters of the insertion or deletion |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @see ACC#TEXT_INSERT |
| * @see ACC#TEXT_DELETE |
| * |
| * @since 3.0 |
| */ |
| public void textChanged (int type, int startIndex, int length) { |
| checkWidget(); |
| OS.NSAccessibilityPostNotification(control.view.id, OS.NSAccessibilityValueChangedNotification.id); |
| } |
| |
| /** |
| * Sends a message to accessible clients that the text |
| * selection has changed within a custom control. |
| * |
| * @exception SWTException <ul> |
| * <li>ERROR_WIDGET_DISPOSED - if the receiver's control has been disposed</li> |
| * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver's control</li> |
| * </ul> |
| * |
| * @since 3.0 |
| */ |
| public void textSelectionChanged () { |
| checkWidget(); |
| OS.NSAccessibilityPostNotification(control.view.id, OS.NSAccessibilitySelectedTextChangedNotification.id); |
| } |
| |
| id childIDToOs(int childID) { |
| if (childID == ACC.CHILDID_SELF) { |
| return control.view; |
| } |
| |
| /* Check cache for childID, if found, return corresponding osChildID. */ |
| SWTAccessibleDelegate childRef = (SWTAccessibleDelegate) childToIdMap.get(Integer.valueOf(childID)); |
| |
| if (childRef == null) { |
| childRef = new SWTAccessibleDelegate(this, childID); |
| childToIdMap.put(Integer.valueOf(childID), childRef); |
| } |
| |
| return childRef; |
| } |
| |
| NSString concatStringsAsRole(NSString str1, NSString str2) { |
| NSString returnValue = str1; |
| returnValue = returnValue.stringByAppendingString(NSString.stringWith(":")); |
| returnValue = returnValue.stringByAppendingString(str2); |
| return returnValue; |
| } |
| |
| String roleToOs(int role) { |
| NSString nsReturnValue = null; //OS.NSAccessibilityUnknownRole; |
| |
| switch (role) { |
| case ACC.ROLE_CLIENT_AREA: nsReturnValue = OS.NSAccessibilityGroupRole; break; |
| case ACC.ROLE_WINDOW: nsReturnValue = OS.NSAccessibilityWindowRole; break; |
| case ACC.ROLE_MENUBAR: nsReturnValue = OS.NSAccessibilityMenuBarRole; break; |
| case ACC.ROLE_MENU: nsReturnValue = OS.NSAccessibilityMenuRole; break; |
| case ACC.ROLE_MENUITEM: nsReturnValue = OS.NSAccessibilityMenuItemRole; break; |
| case ACC.ROLE_SEPARATOR: nsReturnValue = OS.NSAccessibilitySplitterRole; break; |
| case ACC.ROLE_TOOLTIP: nsReturnValue = OS.NSAccessibilityHelpTagRole; break; |
| case ACC.ROLE_SCROLLBAR: nsReturnValue = OS.NSAccessibilityScrollBarRole; break; |
| case ACC.ROLE_DIALOG: nsReturnValue = concatStringsAsRole(OS.NSAccessibilityWindowRole, OS.NSAccessibilityDialogSubrole); break; |
| case ACC.ROLE_LABEL: nsReturnValue = OS.NSAccessibilityStaticTextRole; break; |
| case ACC.ROLE_PUSHBUTTON: nsReturnValue = OS.NSAccessibilityButtonRole; break; |
| case ACC.ROLE_CHECKBUTTON: nsReturnValue = OS.NSAccessibilityCheckBoxRole; break; |
| case ACC.ROLE_RADIOBUTTON: nsReturnValue = OS.NSAccessibilityRadioButtonRole; break; |
| case ACC.ROLE_SPLITBUTTON: nsReturnValue = OS.NSAccessibilityMenuButtonRole; break; |
| case ACC.ROLE_COMBOBOX: nsReturnValue = OS.NSAccessibilityComboBoxRole; break; |
| case ACC.ROLE_TEXT: { |
| int style = control.getStyle(); |
| |
| if ((style & SWT.MULTI) != 0) { |
| nsReturnValue = OS.NSAccessibilityTextAreaRole; |
| } else { |
| nsReturnValue = OS.NSAccessibilityTextFieldRole; |
| } |
| |
| break; |
| } |
| case ACC.ROLE_TOOLBAR: nsReturnValue = OS.NSAccessibilityToolbarRole; break; |
| case ACC.ROLE_LIST: nsReturnValue = OS.NSAccessibilityOutlineRole; break; |
| case ACC.ROLE_LISTITEM: nsReturnValue = OS.NSAccessibilityStaticTextRole; break; |
| case ACC.ROLE_COLUMN: nsReturnValue = OS.NSAccessibilityColumnRole; break; |
| case ACC.ROLE_ROW: nsReturnValue = concatStringsAsRole(OS.NSAccessibilityRowRole, OS.NSAccessibilityTableRowSubrole); break; |
| case ACC.ROLE_TABLE: nsReturnValue = OS.NSAccessibilityTableRole; break; |
| case ACC.ROLE_TABLECELL: nsReturnValue = OS.NSAccessibilityStaticTextRole; break; |
| case ACC.ROLE_TABLECOLUMNHEADER: nsReturnValue = OS.NSAccessibilityGroupRole; break; |
| case ACC.ROLE_TABLEROWHEADER: nsReturnValue = OS.NSAccessibilityGroupRole; break; |
| case ACC.ROLE_TREE: nsReturnValue = OS.NSAccessibilityOutlineRole; break; |
| case ACC.ROLE_TREEITEM: nsReturnValue = concatStringsAsRole(OS.NSAccessibilityOutlineRole, OS.NSAccessibilityOutlineRowSubrole); break; |
| case ACC.ROLE_TABFOLDER: nsReturnValue = OS.NSAccessibilityTabGroupRole; break; |
| case ACC.ROLE_TABITEM: nsReturnValue = OS.NSAccessibilityRadioButtonRole; break; |
| case ACC.ROLE_PROGRESSBAR: nsReturnValue = OS.NSAccessibilityProgressIndicatorRole; break; |
| case ACC.ROLE_SLIDER: nsReturnValue = OS.NSAccessibilitySliderRole; break; |
| case ACC.ROLE_LINK: nsReturnValue = OS.NSAccessibilityLinkRole; break; |
| |
| //10.6 only -> case ACC.ROLE_CANVAS: nsReturnValue = OS.NSAccessibilityLayoutAreaRole; break; |
| case ACC.ROLE_CANVAS: nsReturnValue = OS.NSAccessibilityGroupRole; break; |
| case ACC.ROLE_GRAPHIC: nsReturnValue = OS.NSAccessibilityImageRole; break; |
| |
| //CLIENT_AREA uses NSAccessibilityGroupRole already |
| case ACC.ROLE_GROUP: nsReturnValue = OS.NSAccessibilityGroupRole; break; |
| //SPLIT_BUTTON uses NSAccessibilityMenuButtonRole already |
| case ACC.ROLE_CHECKMENUITEM: nsReturnValue = OS.NSAccessibilityMenuButtonRole; break; |
| case ACC.ROLE_RADIOMENUITEM: nsReturnValue = OS.NSAccessibilityMenuButtonRole; break; |
| //don't know the right answer for these: |
| case ACC.ROLE_FOOTER: |
| case ACC.ROLE_HEADER: |
| case ACC.ROLE_FORM: |
| case ACC.ROLE_PAGE: |
| case ACC.ROLE_SECTION: |
| nsReturnValue = OS.NSAccessibilityGroupRole; |
| break; |
| case ACC.ROLE_HEADING: |
| case ACC.ROLE_PARAGRAPH: |
| nsReturnValue = OS.NSAccessibilityTextAreaRole; |
| break; |
| case ACC.ROLE_CLOCK: |
| case ACC.ROLE_DATETIME: |
| case ACC.ROLE_CALENDAR: |
| case ACC.ROLE_ALERT: |
| case ACC.ROLE_ANIMATION: |
| case ACC.ROLE_DOCUMENT: |
| case ACC.ROLE_SPINBUTTON: |
| case ACC.ROLE_STATUSBAR: |
| nsReturnValue = OS.NSAccessibilityUnknownRole; |
| } |
| |
| return nsReturnValue.getString(); |
| } |
| |
| /* checkWidget was copied from Widget, and rewritten to work in this package */ |
| void checkWidget () { |
| if (!isValidThread ()) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS); |
| if (control.isDisposed ()) SWT.error (SWT.ERROR_WIDGET_DISPOSED); |
| } |
| |
| /* isValidThread was copied from Widget, and rewritten to work in this package */ |
| boolean isValidThread () { |
| return control.getDisplay ().getThread () == Thread.currentThread (); |
| } |
| |
| /** |
| * Adds relationship attributes if needed to the property list. |
| * <p> |
| * <b>IMPORTANT:</b> This method is <em>not</em> part of the SWT |
| * public API. It is marked public only so that it can be shared |
| * within the packages provided by SWT. It is not available on all |
| * platforms and should never be accessed from application code. |
| * </p> |
| * |
| * @noreference This method is not intended to be referenced by clients. |
| */ |
| public long /*int*/ internal_addRelationAttributes(long /*int*/ defaultAttributes) { |
| NSArray attributes = new NSArray(defaultAttributes); |
| NSMutableArray returnArray = NSMutableArray.arrayWithCapacity(attributes.count()); |
| returnArray.addObjectsFromArray(attributes); |
| |
| if (getTitleAttribute(ACC.CHILDID_SELF) != null) { |
| if (!returnArray.containsObject(OS.NSAccessibilityTitleAttribute)) returnArray.addObject(OS.NSAccessibilityTitleAttribute); |
| } |
| |
| if (getDescriptionAttribute(ACC.CHILDID_SELF) != null) { |
| if (!returnArray.containsObject(OS.NSAccessibilityDescriptionAttribute)) returnArray.addObject(OS.NSAccessibilityDescriptionAttribute); |
| } |
| |
| // See if this object has a label or is a label for something else. If so, add that to the list. |
| if (relations[ACC.RELATION_LABEL_FOR] != null) { |
| if (!returnArray.containsObject(OS.NSAccessibilityServesAsTitleForUIElementsAttribute)) returnArray.addObject(OS.NSAccessibilityServesAsTitleForUIElementsAttribute); |
| if (!returnArray.containsObject(OS.NSAccessibilityTitleAttribute)) returnArray.addObject(OS.NSAccessibilityTitleAttribute); |
| } else { |
| returnArray.removeObject(OS.NSAccessibilityServesAsTitleForUIElementsAttribute); |
| } |
| |
| if (relations[ACC.RELATION_LABELLED_BY] != null) { |
| if (!returnArray.containsObject(OS.NSAccessibilityTitleUIElementAttribute)) returnArray.addObject(OS.NSAccessibilityTitleUIElementAttribute); |
| } else { |
| returnArray.removeObject(OS.NSAccessibilityTitleUIElementAttribute); |
| } |
| |
| return returnArray.id; |
| } |
| |
| } |