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