1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package org.openoffice.java.accessibility;
25 
26 import javax.accessibility.AccessibleContext;
27 import javax.accessibility.AccessibleState;
28 
29 import com.sun.star.uno.*;
30 import com.sun.star.accessibility.*;
31 
32 public abstract class Component extends java.awt.Component {
33 	public static final Type RectangleType = new Type(com.sun.star.awt.Rectangle.class);
34 	public static final Type SelectionType = new Type(com.sun.star.awt.Selection.class);
35 
36 	protected XAccessible unoAccessible;
37 	protected XAccessibleContext unoAccessibleContext;
38 	protected XAccessibleComponent unoAccessibleComponent;
39 
40 	protected boolean disposed = false;
41 
Component(XAccessible xAccessible, XAccessibleContext xAccessibleContext)42 	protected Component(XAccessible xAccessible, XAccessibleContext xAccessibleContext) {
43 		super();
44 		unoAccessible = xAccessible;
45 		unoAccessibleContext = xAccessibleContext;
46 		unoAccessibleComponent = (XAccessibleComponent)
47 			UnoRuntime.queryInterface(XAccessibleComponent.class, xAccessibleContext);
48 		// Add the event listener right away, because the global focus notification doesn't
49 		// work yet...
50 		XAccessibleEventBroadcaster broadcaster = (XAccessibleEventBroadcaster)
51 			UnoRuntime.queryInterface(XAccessibleEventBroadcaster.class,
52 			unoAccessibleComponent);
53 		if (broadcaster != null) {
54 			broadcaster.addEventListener(createEventListener());
55 		}
56 	}
57 
58 	/**
59 	* Determines whether this <code>Component</code> is showing on screen.
60 	* This means that the component must be visible, and it must be in a
61 	* <code>container</code> that is visible and showing.
62 	* @see #addNotify
63 	* @see #removeNotify
64 	* @since JDK1.0
65 	*/
isShowing()66 	public boolean isShowing() {
67 		if (isVisible()) {
68 			java.awt.Container parent = getParent();
69 			return (parent == null) || parent.isShowing();
70 		}
71 		return false;
72 	}
73 
74 	/**
75 	* Makes this <code>Component</code> displayable by connecting it to a
76 	* native screen resource.
77 	* This method is called internally by the toolkit and should
78 	* not be called directly by programs.
79 	* @see #isDisplayable
80 	* @see #removeNotify
81 	* @since JDK1.0
82 	*/
addNotify()83 	public void addNotify() {
84 	}
85 
86 	/**
87 	* Makes this <code>Component</code> undisplayable by destroying it native
88 	* screen resource.
89 	* This method is called by the toolkit internally and should
90 	* not be called directly by programs.
91 	* @see #isDisplayable
92 	* @see #addNotify
93 	* @since JDK1.0
94 	*/
removeNotify()95 	public void removeNotify() {
96 	}
97 
98 	/*
99 	 * Fake the java focus handling. This is necessary to keep AOO focus
100 	 * in sync with the java focus. See java.awt.DefaultKeyboardFocusManager
101 	 * for implementation details.
102 	 **/
103 
104 	/** Requests focus for this object */
requestFocus()105 	public void requestFocus() {
106 	}
107 
108 	/** Requests focus for this object */
requestFocus(boolean temporary)109 	public boolean requestFocus(boolean temporary) {
110 		// Must be a no-op to make focus handling work
111 		return true;
112 	}
113 
114 	/** Requests the focus for this object in the containing window */
requestFocusInWindow()115 	public boolean requestFocusInWindow() {
116 		return requestFocusInWindow(false);
117 	}
118 
119 	/** Requests the focus for this object in the containing window */
requestFocusInWindow(boolean temporary)120 	protected boolean requestFocusInWindow(boolean temporary) {
121 		if (isFocusable() && isVisible()) {
122 			getEventQueue().postEvent(new java.awt.event.FocusEvent(this, java.awt.event.FocusEvent.FOCUS_GAINED, temporary));
123 			return true;
124 		}
125 		return false;
126 	}
127 
getAccessibleComponents(Object[] targetSet)128 	public Object[] getAccessibleComponents(Object[] targetSet) {
129 		try {
130 			java.util.ArrayList list = new java.util.ArrayList(targetSet.length);
131 			for (int i=0; i < targetSet.length; i++) {
132 				java.awt.Component c = AccessibleObjectFactory.getAccessibleComponent(
133 					(XAccessible) UnoRuntime.queryInterface(XAccessible.class, targetSet[i]));
134 				if (c != null) {
135 					list.add(c);
136 				}
137 			}
138 			list.trimToSize();
139 			return list.toArray();
140 		} catch (com.sun.star.uno.RuntimeException e) {
141 			return null;
142 		}
143 	}
144 
getEventQueue()145 	protected java.awt.EventQueue getEventQueue() {
146 		return java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue();
147 	}
148 
149 	protected class PropertyChangeBroadcaster implements Runnable {
150 		String propertyName;
151 		Object oldValue;
152 		Object newValue;
153 
PropertyChangeBroadcaster(String name, Object param1, Object param2)154 		public PropertyChangeBroadcaster(String name, Object param1, Object param2) {
155 			propertyName = name;
156 			oldValue = param1;
157 			newValue = param2;
158 		}
159 
run()160 		public void run() {
161 			// Because this code is executed in the DispatchThread, it is better to catch every
162 			// exception that might occur
163 			try {
164 				AccessibleContext ac = accessibleContext;
165 				if (ac != null) {
166 					ac.firePropertyChange(propertyName, oldValue, newValue);
167 				}
168 			} catch (java.lang.Exception e) {
169 				if (Build.DEBUG) {
170 					System.err.println(e.getClass().getName() + " caught propagating " + propertyName + " event: " + e.getMessage());
171 					e.printStackTrace();
172 				}
173 			}
174 		}
175 	}
176 
firePropertyChange(String property, Object oldValue, Object newValue)177 	protected void firePropertyChange(String property, Object oldValue, Object newValue) {
178 		getEventQueue().invokeLater(new PropertyChangeBroadcaster(property, oldValue, newValue));
179 	}
180 
fireStatePropertyChange(AccessibleState state, boolean set)181 	protected void fireStatePropertyChange(AccessibleState state, boolean set) {
182 		PropertyChangeBroadcaster broadcaster;
183 
184 //	if (Build.DEBUG) {
185 //		System.err.println("[" + AccessibleRoleAdapter.getAccessibleRole(unoAccessibleContext.getAccessibleRole()) + "] " +
186 //				unoAccessibleContext.getAccessibleName() + " is " + (set ? "now " : "no longer ") + state);
187 //	}
188 
189 		if (set) {
190 			broadcaster = new PropertyChangeBroadcaster(
191 				accessibleContext.ACCESSIBLE_STATE_PROPERTY,
192 				null, state);
193 		} else {
194 			broadcaster = new PropertyChangeBroadcaster(
195 				accessibleContext.ACCESSIBLE_STATE_PROPERTY,
196 				state, null);
197 		}
198 		getEventQueue().invokeLater(broadcaster);
199 	}
200 
201 	/**
202 	* Update the proxy objects appropriately on property change events
203 	*/
204 	protected class AccessibleUNOComponentListener implements XAccessibleEventListener {
205 
AccessibleUNOComponentListener()206 		protected AccessibleUNOComponentListener() {
207 		}
208 
setComponentState(short state, boolean enable)209 		protected void setComponentState(short state, boolean enable) {
210 			switch (state) {
211 				case AccessibleStateType.ACTIVE:
212 					// Only frames should be active
213 					break;
214 				case AccessibleStateType.ARMED:
215 					fireStatePropertyChange(AccessibleState.ARMED, enable);
216 					break;
217 				case AccessibleStateType.CHECKED:
218 					fireStatePropertyChange(AccessibleState.CHECKED, enable);
219 					break;
220 				case AccessibleStateType.ENABLED:
221 					setEnabled(enable);
222 					// Since we can't access awt.Componet.accessibleContext, we need to fire
223 					// this event manually...
224 					fireStatePropertyChange(AccessibleState.ENABLED, enable);
225 					break;
226 				case AccessibleStateType.FOCUSED:
227 					getEventQueue().postEvent(new java.awt.event.FocusEvent(
228 						Component.this, enable ?
229 						java.awt.event.FocusEvent.FOCUS_GAINED :
230 						java.awt.event.FocusEvent.FOCUS_LOST));
231 					break;
232 				case AccessibleStateType.PRESSED:
233 					fireStatePropertyChange(AccessibleState.PRESSED, enable);
234 					break;
235 				case AccessibleStateType.SELECTED:
236 					fireStatePropertyChange(AccessibleState.SELECTED, enable);
237 					break;
238 				case AccessibleStateType.SENSITIVE:
239 					// This state equals ENABLED in AOO (but not in Gtk+) and does not exist in Java 1.5
240 					break;
241 				case AccessibleStateType.SHOWING:
242 //					fireStatePropertyChange(AccessibleState.SHOWING, enable);
243 					break;
244 				case AccessibleStateType.VISIBLE:
245 					Component.this.setVisible(enable);
246 					break;
247 				default:
248 					if (Build.DEBUG) {
249 						System.err.println("[component]: " + getName() + "unexpected state change " + state);
250 					}
251 					break;
252 			}
253 		}
254 
255 		/** Updates the accessible name and fires the appropriate PropertyChangedEvent */
handleNameChangedEvent(Object any)256 		protected void handleNameChangedEvent(Object any) {
257 			try {
258 				// This causes the property change event to be fired in the VCL thread
259 				// context. If this causes problems, it has to be deligated to the java
260 				// dispatch thread...
261 				if (accessibleContext != null) {
262 					accessibleContext.setAccessibleName(AnyConverter.toString(any));
263 				}
264 			} catch (com.sun.star.lang.IllegalArgumentException e) {
265 			}
266 		}
267 
268 		/** Updates the accessible description and fires the appropriate PropertyChangedEvent */
handleDescriptionChangedEvent(Object any)269 		protected void handleDescriptionChangedEvent(Object any) {
270 			try {
271 				// This causes the property change event to be fired in the VCL thread
272 				// context. If this causes problems, it has to be deligated to the java
273 				// dispatch thread...
274 				if (accessibleContext != null) {
275 					accessibleContext.setAccessibleDescription(AnyConverter.toString(any));
276 				}
277 			} catch (com.sun.star.lang.IllegalArgumentException e) {
278 			}
279 		}
280 
281 		/** Updates the internal states and fires the appropriate PropertyChangedEvent */
handleStateChangedEvent(Object any1, Object any2)282 		protected void handleStateChangedEvent(Object any1, Object any2) {
283 			try {
284 				if (AnyConverter.isShort(any1)) {
285 					setComponentState(AnyConverter.toShort(any1), false);
286 				}
287 
288 				if (AnyConverter.isShort(any2)) {
289 					setComponentState(AnyConverter.toShort(any2), true);
290 				}
291 			} catch (com.sun.star.lang.IllegalArgumentException e) {
292 			}
293 		}
294 
295 		/** Called by OpenOffice process to notify property changes */
notifyEvent(AccessibleEventObject event)296 		public void notifyEvent(AccessibleEventObject event) {
297 
298 			if ( !disposed ) {
299 
300 				switch (event.EventId) {
301 					case AccessibleEventId.ACTION_CHANGED:
302 						firePropertyChange(accessibleContext.ACCESSIBLE_ACTION_PROPERTY,
303 							toNumber(event.OldValue), toNumber(event.NewValue));
304 						break;
305 					case AccessibleEventId.NAME_CHANGED:
306 						// Set the accessible name for the corresponding context, which will fire a property
307 						// change event itself
308 						handleNameChangedEvent(event.NewValue);
309 						break;
310 					case AccessibleEventId.DESCRIPTION_CHANGED:
311 						// Set the accessible description for the corresponding context, which will fire a property
312 						// change event itself - so do not set propertyName !
313 						handleDescriptionChangedEvent(event.NewValue);
314 						break;
315 					case AccessibleEventId.CHILD:
316 						if (Build.DEBUG) {
317 							System.out.println("Unexpected child event for object of role " + getAccessibleContext().getAccessibleRole());
318 						}
319 						break;
320 					case AccessibleEventId.STATE_CHANGED:
321 						// Update the internal state set and fire the appropriate PropertyChangedEvent
322 						handleStateChangedEvent(event.OldValue, event.NewValue);
323 						break;
324 					case AccessibleEventId.VISIBLE_DATA_CHANGED:
325 					case AccessibleEventId.BOUNDRECT_CHANGED:
326 						firePropertyChange(AccessibleContext.ACCESSIBLE_VISIBLE_DATA_PROPERTY, null, null);
327 						break;
328 					case AccessibleEventId.TEXT_CHANGED:
329 						firePropertyChange(AccessibleContext.ACCESSIBLE_TEXT_PROPERTY,
330 												AccessibleTextImpl.convertTextSegment(event.OldValue),
331 												AccessibleTextImpl.convertTextSegment(event.NewValue));
332 						break;
333 					/*
334 					 * the Java AccessBridge for GNOME maps SELECTION_PROPERTY change events
335 					 * for objects of role TEXT to object:text-selection-changed
336 					 */
337 					case AccessibleEventId.TEXT_SELECTION_CHANGED:
338 						firePropertyChange(AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY, null, null);
339 						break;
340 					case AccessibleEventId.CARET_CHANGED:
341 						firePropertyChange(accessibleContext.ACCESSIBLE_CARET_PROPERTY, toNumber(event.OldValue), toNumber(event.NewValue));
342 						break;
343 					case AccessibleEventId.VALUE_CHANGED:
344 						firePropertyChange(accessibleContext.ACCESSIBLE_VALUE_PROPERTY, toNumber(event.OldValue), toNumber(event.NewValue));
345 					default:
346 						// Warn about unhandled events
347 						if(Build.DEBUG) {
348 							System.out.println(this + ": unhandled accessibility event id=" + event.EventId);
349 						}
350 				}
351 			}
352 		}
353 
354 		/** Called by OpenOffice process to notify that the UNO component is disposing */
disposing(com.sun.star.lang.EventObject eventObject)355 		public void disposing(com.sun.star.lang.EventObject eventObject) {
356 			disposed = true;
357 			AccessibleObjectFactory.disposing(Component.this);
358 		}
359 	}
360 
createEventListener()361 	protected XAccessibleEventListener createEventListener() {
362 		return new AccessibleUNOComponentListener();
363 	}
364 
365 	protected javax.accessibility.AccessibleContext accessibleContext = null;
366 
367 	/** This method actually creates the AccessibleContext object returned by
368 	 * getAccessibleContext().
369 	 */
createAccessibleContext()370 	protected javax.accessibility.AccessibleContext createAccessibleContext() {
371 		return null;
372 	}
373 
374 	/** Returns the AccessibleContext associated with this object */
getAccessibleContext()375 	public final javax.accessibility.AccessibleContext getAccessibleContext() {
376 		if (accessibleContext == null) {
377 			try {
378 				AccessibleContext ac = createAccessibleContext();
379 				if (ac != null) {
380 					// Set accessible name and description here to avoid
381 					// unnecessary property change events later...
382 					ac.setAccessibleName(unoAccessibleContext.getAccessibleName());
383 					ac.setAccessibleDescription(unoAccessibleContext.getAccessibleDescription());
384 					accessibleContext = ac;
385 				}
386 			} catch (com.sun.star.uno.RuntimeException e) {
387 			}
388 		}
389 		return accessibleContext;
390 	}
391 
392 	protected abstract class AccessibleUNOComponent extends java.awt.Component.AccessibleAWTComponent
393 		implements javax.accessibility.AccessibleExtendedComponent {
394 
395 		protected java.awt.event.ComponentListener accessibleComponentHandler = null;
396 
397 		/**
398 		* Fire PropertyChange listener, if one is registered,
399 		* when shown/hidden...
400 		*/
401 		protected class AccessibleComponentHandler implements java.awt.event.ComponentListener {
componentHidden(java.awt.event.ComponentEvent e)402 			public void componentHidden(java.awt.event.ComponentEvent e) {
403 				AccessibleUNOComponent.this.firePropertyChange(
404 					AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
405 					AccessibleState.VISIBLE, null);
406 			}
407 
componentShown(java.awt.event.ComponentEvent e)408 			public void componentShown(java.awt.event.ComponentEvent e) {
409 				AccessibleUNOComponent.this.firePropertyChange(
410 					AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
411 					null, AccessibleState.VISIBLE);
412 			}
413 
componentMoved(java.awt.event.ComponentEvent e)414 			public void componentMoved(java.awt.event.ComponentEvent e) {
415 			}
416 
componentResized(java.awt.event.ComponentEvent e)417 			public void componentResized(java.awt.event.ComponentEvent e) {
418 			}
419 		} // inner class AccessibleComponentHandler
420 
421 		protected java.awt.event.FocusListener accessibleFocusHandler = null;
422 
423 		/**
424 		* Fire PropertyChange listener, if one is registered,
425 		* when focus events happen
426 		*/
427 		protected class AccessibleFocusHandler implements java.awt.event.FocusListener {
focusGained(java.awt.event.FocusEvent event)428 			public void focusGained(java.awt.event.FocusEvent event) {
429 				AccessibleUNOComponent.this.firePropertyChange(
430 					AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
431 					null, AccessibleState.FOCUSED);
432 				if (Build.DEBUG) {
433 					System.err.println("[" + getAccessibleRole() + "] " + getAccessibleName() + " is now focused");
434 				}
435 			}
focusLost(java.awt.event.FocusEvent event)436 			public void focusLost(java.awt.event.FocusEvent event) {
437 				AccessibleUNOComponent.this.firePropertyChange(
438 					AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
439 					AccessibleState.FOCUSED, null);
440 				if (Build.DEBUG) {
441 					System.err.println("[" + getAccessibleRole() + "] " + getAccessibleName() + " is no longer focused");
442 				}
443 			}
444 		} // inner class AccessibleFocusHandler
445 
446 		protected int propertyChangeListenerCount = 0;
447 
448 		/**
449 		* Add a PropertyChangeListener to the listener list.
450 		*
451 		* @param listener The PropertyChangeListener to be added
452 		*/
addPropertyChangeListener(java.beans.PropertyChangeListener listener)453 		public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) {
454 			if (propertyChangeListenerCount++ == 0) {
455 				accessibleComponentHandler = new AccessibleComponentHandler();
456 				Component.this.addComponentListener(accessibleComponentHandler);
457 
458 				accessibleFocusHandler = new AccessibleFocusHandler();
459 				Component.this.addFocusListener(accessibleFocusHandler);
460 			}
461 			super.addPropertyChangeListener(listener);
462 		}
463 
464 		/**
465 		* Remove a PropertyChangeListener from the listener list.
466 		* This removes a PropertyChangeListener that was registered
467 		* for all properties.
468 		*
469 		* @param listener The PropertyChangeListener to be removed
470 		*/
removePropertyChangeListener(java.beans.PropertyChangeListener listener)471 		public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) {
472 			if (--propertyChangeListenerCount == 0) {
473 				Component.this.removeComponentListener(accessibleComponentHandler);
474 				accessibleComponentHandler = null;
475 
476 				Component.this.removeFocusListener(accessibleFocusHandler);
477 				accessibleFocusHandler = null;
478 			}
479 			super.removePropertyChangeListener(listener);
480 		}
481 
482 		/**
483 		* Gets the current state set of this object.
484 		*
485 		* @return an instance of <code>AccessibleStateSet</code>
486 		*	containing the current state set of the object
487 		* @see AccessibleState
488 		*/
getAccessibleStateSet()489 		public javax.accessibility.AccessibleStateSet getAccessibleStateSet() {
490 			if (disposed)
491 				return AccessibleStateAdapter.getDefunctStateSet();
492 
493 			try {
494 				return AccessibleStateAdapter.getAccessibleStateSet(Component.this,
495 					unoAccessibleContext.getAccessibleStateSet());
496 			} catch (com.sun.star.uno.RuntimeException e) {
497 				return AccessibleStateAdapter.getDefunctStateSet();
498 			}
499 		}
500 
501 		/** Gets the locale of the component */
getLocale()502 		public java.util.Locale getLocale() throws java.awt.IllegalComponentStateException {
503 			try {
504 				com.sun.star.lang.Locale unoLocale = unoAccessible.getAccessibleContext().getLocale();
505 				return new java.util.Locale(unoLocale.Language, unoLocale.Country);
506 			} catch (IllegalAccessibleComponentStateException e) {
507 				throw new java.awt.IllegalComponentStateException(e.getMessage());
508 			} catch (com.sun.star.uno.RuntimeException e) {
509 				return java.util.Locale.getDefault();
510 			}
511 		}
512 
513 		/*
514 		* AccessibleExtendedComponent
515 		*/
516 
517 		/** Returns the background color of the object */
getBackground()518 		public java.awt.Color getBackground() {
519 			try {
520 				return new java.awt.Color(unoAccessibleComponent.getBackground());
521 			} catch (com.sun.star.uno.RuntimeException e) {
522 				return null;
523 			}
524 		}
525 
setBackground(java.awt.Color c)526 		public void setBackground(java.awt.Color c) {
527 			// Not supported by UNO accessibility API
528 		}
529 
530 		/** Returns the foreground color of the object */
getForeground()531 		public java.awt.Color getForeground() {
532 			try {
533 				return new java.awt.Color(unoAccessibleComponent.getForeground());
534 			} catch (com.sun.star.uno.RuntimeException e) {
535 				return null;
536 			}
537 		}
538 
setForeground(java.awt.Color c)539 		public void setForeground(java.awt.Color c) {
540 			// Not supported by UNO accessibility API
541 		}
542 
getCursor()543 		public java.awt.Cursor getCursor() {
544 			// Not supported by UNO accessibility API
545 			return null;
546 		}
547 
setCursor(java.awt.Cursor cursor)548 		public void setCursor(java.awt.Cursor cursor) {
549 			// Not supported by UNO accessibility API
550 		}
551 
getFont()552 		public java.awt.Font getFont() {
553 			// FIXME
554 			return null;
555 		}
556 
setFont(java.awt.Font f)557 		public void setFont(java.awt.Font f) {
558 			// Not supported by UNO accessibility API
559 		}
560 
getFontMetrics(java.awt.Font f)561 		public java.awt.FontMetrics getFontMetrics(java.awt.Font f) {
562 			// FIXME
563 			return null;
564 		}
565 
isEnabled()566 		public boolean isEnabled() {
567 			return Component.this.isEnabled();
568 		}
569 
setEnabled(boolean b)570 		public void setEnabled(boolean b) {
571 			// Not supported by UNO accessibility API
572 		}
573 
isVisible()574 		public boolean isVisible() {
575 			return Component.this.isVisible();
576 		}
577 
setVisible(boolean b)578 		public void setVisible(boolean b) {
579 			// Not supported by UNO accessibility API
580 		}
581 
isShowing()582 		public boolean isShowing() {
583 			return Component.this.isShowing();
584 		}
585 
contains(java.awt.Point p)586 		public boolean contains(java.awt.Point p) {
587 			try {
588 				return unoAccessibleComponent.containsPoint(new com.sun.star.awt.Point(p.x, p.y));
589 			} catch (com.sun.star.uno.RuntimeException e) {
590 				return false;
591 			}
592 		}
593 
594 		/** Returns the location of the object on the screen. */
getLocationOnScreen()595 		public java.awt.Point getLocationOnScreen() {
596 			try {
597 				com.sun.star.awt.Point unoPoint = unoAccessibleComponent.getLocationOnScreen();
598 //			if (Build.DEBUG) {
599 //				System.err.println("Returning location on screen( " + unoPoint.X + ", " + unoPoint.Y + " )" );
600 //			}
601 				return new java.awt.Point(unoPoint.X, unoPoint.Y);
602 			} catch (com.sun.star.uno.RuntimeException e) {
603 				return null;
604 			}
605 		}
606 
607 		/** Gets the location of this component in the form of a point specifying the component's top-left corner */
getLocation()608 		public java.awt.Point getLocation() {
609 			try {
610 				com.sun.star.awt.Point unoPoint = unoAccessibleComponent.getLocation();
611 				return new java.awt.Point( unoPoint.X, unoPoint.Y );
612 			} catch (com.sun.star.uno.RuntimeException e) {
613 				return null;
614 			}
615 		}
616 
617 		/** Moves this component to a new location */
setLocation(java.awt.Point p)618 		public void setLocation(java.awt.Point p) {
619 			// Not supported by UNO accessibility API
620 		}
621 
622 		/** Gets the bounds of this component in the form of a Rectangle object */
getBounds()623 		public java.awt.Rectangle getBounds() {
624 			try {
625 				com.sun.star.awt.Rectangle unoRect = unoAccessibleComponent.getBounds();
626 				return new java.awt.Rectangle(unoRect.X, unoRect.Y, unoRect.Width, unoRect.Height);
627 			} catch (com.sun.star.uno.RuntimeException e) {
628 				return null;
629 			}
630 		}
631 
632 		/** Moves and resizes this component to conform to the new bounding rectangle r */
setBounds(java.awt.Rectangle r)633 		public void setBounds(java.awt.Rectangle r) {
634 			// Not supported by UNO accessibility API
635 		}
636 
637 		/** Returns the size of this component in the form of a Dimension object */
getSize()638 		public java.awt.Dimension getSize() {
639 			try {
640 				com.sun.star.awt.Size unoSize = unoAccessibleComponent.getSize();
641 				return new java.awt.Dimension(unoSize.Width, unoSize.Height);
642 			} catch (com.sun.star.uno.RuntimeException e) {
643 				return null;
644 			}
645 		}
646 
647 		/** Resizes this component so that it has width d.width and height d.height */
setSize(java.awt.Dimension d)648 		public void setSize(java.awt.Dimension d) {
649 			// Not supported by UNO accessibility API
650 		}
651 
getAccessibleAt(java.awt.Point p)652 		public javax.accessibility.Accessible getAccessibleAt(java.awt.Point p) {
653 			// Not supported by this implementation
654 			return null;
655 		}
656 
isFocusTraversable()657 		public boolean isFocusTraversable() {
658 			return Component.this.isFocusable();
659 		}
660 
requestFocus()661 		public void requestFocus() {
662 			unoAccessibleComponent.grabFocus();
663 		}
664 
getToolTipText()665 		public String getToolTipText() {
666 			try {
667 				XAccessibleExtendedComponent unoAccessibleExtendedComponent = (XAccessibleExtendedComponent)
668 					UnoRuntime.queryInterface(XAccessibleExtendedComponent.class, unoAccessibleComponent);
669 				if (unoAccessibleExtendedComponent != null) {
670 					return unoAccessibleExtendedComponent.getToolTipText();
671 				}
672 			} catch (com.sun.star.uno.RuntimeException e) {
673 				return null;
674 			}
675 			return null;
676 		}
677 
getTitledBorderText()678 		public String getTitledBorderText() {
679 			try {
680 				XAccessibleExtendedComponent unoAccessibleExtendedComponent = (XAccessibleExtendedComponent)
681 					UnoRuntime.queryInterface(XAccessibleExtendedComponent.class, unoAccessibleComponent);
682 				if (unoAccessibleExtendedComponent != null) {
683 					return unoAccessibleExtendedComponent.getTitledBorderText();
684 				}
685 			} catch (com.sun.star.uno.RuntimeException e) {
686 				return null;
687 			}
688 			return null;
689 		}
690 
getAccessibleKeyBinding()691 		public javax.accessibility.AccessibleKeyBinding getAccessibleKeyBinding() {
692 			try {
693 				XAccessibleAction unoAccessibleAction = (XAccessibleAction)
694 					UnoRuntime.queryInterface(XAccessibleAction.class, unoAccessibleComponent);
695 				if (unoAccessibleAction != null) {
696 					XAccessibleKeyBinding unoAccessibleKeyBinding = unoAccessibleAction.getAccessibleActionKeyBinding(0);
697 					if (unoAccessibleKeyBinding != null) {
698 						return new AccessibleKeyBinding(unoAccessibleKeyBinding);
699 					}
700 				}
701 			} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
702 				return null;
703 			} catch (com.sun.star.uno.RuntimeException e) {
704 				return null;
705 			}
706 			return null;
707 		}
708 	}
709 
710 	// Extract a number from a UNO any
toNumber(java.lang.Object any)711 	public static java.lang.Number toNumber(java.lang.Object any) {
712 		try {
713 			if (AnyConverter.isByte(any)) {
714 				return new Byte(AnyConverter.toByte(any));
715 			} else if (AnyConverter.isShort(any)) {
716 				return new Short(AnyConverter.toShort(any));
717 			} else if (AnyConverter.isInt(any)) {
718 				return new Integer(AnyConverter.toInt(any));
719 			} else if (AnyConverter.isLong(any)) {
720 				return new Long(AnyConverter.toLong(any));
721 			} else if (AnyConverter.isFloat(any)) {
722 				return new Float(AnyConverter.toFloat(any));
723 			} else if (AnyConverter.isDouble(any)) {
724 				return new Double(AnyConverter.toDouble(any));
725 			}
726 		} catch (com.sun.star.lang.IllegalArgumentException e) {
727 			throw new IllegalArgumentException(e.getMessage());
728 		}
729 			return null;
730 	}
731 
toString()732 	public String toString() {
733 		return UnoRuntime.generateOid(unoAccessible);
734 	}
735 }
736