1*34dd1e25SAndrew Rist /**************************************************************
2*34dd1e25SAndrew Rist  *
3*34dd1e25SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*34dd1e25SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*34dd1e25SAndrew Rist  * distributed with this work for additional information
6*34dd1e25SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*34dd1e25SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*34dd1e25SAndrew Rist  * "License"); you may not use this file except in compliance
9*34dd1e25SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*34dd1e25SAndrew Rist  *
11*34dd1e25SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*34dd1e25SAndrew Rist  *
13*34dd1e25SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*34dd1e25SAndrew Rist  * software distributed under the License is distributed on an
15*34dd1e25SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*34dd1e25SAndrew Rist  * KIND, either express or implied.  See the License for the
17*34dd1e25SAndrew Rist  * specific language governing permissions and limitations
18*34dd1e25SAndrew Rist  * under the License.
19*34dd1e25SAndrew Rist  *
20*34dd1e25SAndrew Rist  *************************************************************/
21*34dd1e25SAndrew Rist 
22*34dd1e25SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir import java.awt.Color;
25cdf0e10cSrcweir import java.awt.Font;
26cdf0e10cSrcweir import java.awt.Dimension;
27cdf0e10cSrcweir import javax.swing.JTextArea;
28cdf0e10cSrcweir import javax.swing.JScrollPane;
29cdf0e10cSrcweir import java.util.Vector;
30cdf0e10cSrcweir 
31cdf0e10cSrcweir import com.sun.star.accessibility.XAccessible;
32cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleContext;
33cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleComponent;
34cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleStateSet;
35cdf0e10cSrcweir 
36cdf0e10cSrcweir import com.sun.star.uno.AnyConverter;
37cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
38cdf0e10cSrcweir 
39cdf0e10cSrcweir import com.sun.star.awt.Point;
40cdf0e10cSrcweir import com.sun.star.awt.Size;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir /** Display textual information for a given accessible object.  This
43cdf0e10cSrcweir     includes the names of that object of its ancestors as well as some
44cdf0e10cSrcweir     information retrieved from the XAccessibleContext and
45cdf0e10cSrcweir     XAccessibleComponent interfaces.
46cdf0e10cSrcweir */
47cdf0e10cSrcweir class TextualDisplay
48cdf0e10cSrcweir     extends JScrollPane
49cdf0e10cSrcweir     implements IAccessibleObjectDisplay
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     /** Create a new scroll pane that contains a text widget which display
52cdf0e10cSrcweir         information about given accessible objects.
53cdf0e10cSrcweir     */
TextualDisplay()54cdf0e10cSrcweir     public TextualDisplay ()
55cdf0e10cSrcweir     {
56cdf0e10cSrcweir         // Create a text widget for displaying the text information...
57cdf0e10cSrcweir         maText = new JTextArea (80,10);
58cdf0e10cSrcweir         maText.setBackground (new Color (250,240,230));
59cdf0e10cSrcweir         maText.setFont (new Font ("Courier", Font.PLAIN, 11));
60cdf0e10cSrcweir 
61cdf0e10cSrcweir         // ...and set-up the scroll pane to show this widget.
62cdf0e10cSrcweir         setViewportView (maText);
63cdf0e10cSrcweir         setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
64cdf0e10cSrcweir         setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
65cdf0e10cSrcweir     }
66cdf0e10cSrcweir 
67cdf0e10cSrcweir 
68cdf0e10cSrcweir 
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     /** Set the accessible object to display.  Call this method e.g. when a
71cdf0e10cSrcweir         new object has been focused.
72cdf0e10cSrcweir     */
setAccessibleObject(XAccessibleContext xContext)73cdf0e10cSrcweir     public synchronized void setAccessibleObject (XAccessibleContext xContext)
74cdf0e10cSrcweir     {
75cdf0e10cSrcweir         // First clear the display area.
76cdf0e10cSrcweir         msTextContent = new String ();
77cdf0e10cSrcweir 
78cdf0e10cSrcweir         if (xContext != null)
79cdf0e10cSrcweir         {
80cdf0e10cSrcweir             String sIndentation = showParents (xContext);
81cdf0e10cSrcweir             showContextInfo (xContext, sIndentation);
82cdf0e10cSrcweir             showComponentInfo (xContext, sIndentation);
83cdf0e10cSrcweir         }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         maText.setText (msTextContent);
86cdf0e10cSrcweir     }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 
updateAccessibleObject(XAccessibleContext xContext)91cdf0e10cSrcweir     public synchronized void updateAccessibleObject (XAccessibleContext xContext)
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         setAccessibleObject (xContext);
94cdf0e10cSrcweir     }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir 
97cdf0e10cSrcweir 
98cdf0e10cSrcweir     /** Show some of the information available over the given object's
99cdf0e10cSrcweir         XAccessibleContext interface.
100cdf0e10cSrcweir     */
showContextInfo(XAccessibleContext xContext, String sIndentation)101cdf0e10cSrcweir     private void showContextInfo (XAccessibleContext xContext, String sIndentation)
102cdf0e10cSrcweir     {
103cdf0e10cSrcweir         // Show the description.
104cdf0e10cSrcweir         msTextContent += sIndentation + "Description: "
105cdf0e10cSrcweir             + xContext.getAccessibleDescription() + "\n";
106cdf0e10cSrcweir 
107cdf0e10cSrcweir         showStates (xContext, sIndentation);
108cdf0e10cSrcweir     }
109cdf0e10cSrcweir 
110cdf0e10cSrcweir 
111cdf0e10cSrcweir 
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     /** Show a list of all of the the given object's states.  Use the
114cdf0e10cSrcweir         NameConverter class to transform the numerical state ids into human
115cdf0e10cSrcweir         readable names.
116cdf0e10cSrcweir         @param xContext
117cdf0e10cSrcweir             The accessible context for which to show the state names.
118cdf0e10cSrcweir     */
showStates(XAccessibleContext xContext, String sIndentation)119cdf0e10cSrcweir     private void showStates (XAccessibleContext xContext, String sIndentation)
120cdf0e10cSrcweir     {
121cdf0e10cSrcweir         // Get the state set object...
122cdf0e10cSrcweir         XAccessibleStateSet xStateSet = xContext.getAccessibleStateSet();
123cdf0e10cSrcweir         // ...and retrieve an array of numerical ids.
124cdf0e10cSrcweir         short aStates[] = xStateSet.getStates();
125cdf0e10cSrcweir 
126cdf0e10cSrcweir         // Iterate over the array and print the names of the states.
127cdf0e10cSrcweir         msTextContent += sIndentation + "States     : ";
128cdf0e10cSrcweir         for (int i=0; i<aStates.length; i++)
129cdf0e10cSrcweir         {
130cdf0e10cSrcweir             if (i > 0)
131cdf0e10cSrcweir                 msTextContent += ", ";
132cdf0e10cSrcweir             msTextContent += NameProvider.getStateName(aStates[i]);
133cdf0e10cSrcweir         }
134cdf0e10cSrcweir         msTextContent += "\n";
135cdf0e10cSrcweir     }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 
139cdf0e10cSrcweir 
140cdf0e10cSrcweir     /** When the given object supports the XAccessibleComponent interface then
141cdf0e10cSrcweir         show its size and location on the screen.
142cdf0e10cSrcweir     */
showComponentInfo(XAccessibleContext xContext, String sIndentation)143cdf0e10cSrcweir     private void showComponentInfo (XAccessibleContext xContext, String sIndentation)
144cdf0e10cSrcweir     {
145cdf0e10cSrcweir         // Try to cast the given accessible context to the
146cdf0e10cSrcweir         // XAccessibleComponent interface.
147cdf0e10cSrcweir         XAccessibleComponent xComponent =
148cdf0e10cSrcweir             (XAccessibleComponent)UnoRuntime.queryInterface(
149cdf0e10cSrcweir                 XAccessibleComponent.class, xContext);
150cdf0e10cSrcweir         if (xComponent != null)
151cdf0e10cSrcweir         {
152cdf0e10cSrcweir             Point aLocation = xComponent.getLocationOnScreen();
153cdf0e10cSrcweir             msTextContent += sIndentation + "Position   : "
154cdf0e10cSrcweir                 + aLocation.X + ", " + aLocation.Y + "\n";
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             Size aSize = xComponent.getSize();
157cdf0e10cSrcweir             msTextContent += sIndentation + "Size       : "
158cdf0e10cSrcweir                 + aSize.Width + ", " + aSize.Height + "\n";
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir     }
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 
164cdf0e10cSrcweir 
165cdf0e10cSrcweir 
166cdf0e10cSrcweir     /** Print the names of the given object and its parents and return an
167cdf0e10cSrcweir         indentation string that can be used to print further information
168cdf0e10cSrcweir         about the object.
169cdf0e10cSrcweir     */
showParents(XAccessibleContext xContext)170cdf0e10cSrcweir     private String showParents (XAccessibleContext xContext)
171cdf0e10cSrcweir     {
172cdf0e10cSrcweir         // Create the path from the given object to its tree's root.
173cdf0e10cSrcweir         Vector aPathToRoot = new Vector();
174cdf0e10cSrcweir         while (xContext != null)
175cdf0e10cSrcweir         {
176cdf0e10cSrcweir             aPathToRoot.add (xContext);
177cdf0e10cSrcweir             // Go up the hierarchy one level to the object's parent.
178cdf0e10cSrcweir             try
179cdf0e10cSrcweir             {
180cdf0e10cSrcweir                 XAccessible xParent = xContext.getAccessibleParent();
181cdf0e10cSrcweir                 if (xParent != null)
182cdf0e10cSrcweir                     xContext = xParent.getAccessibleContext();
183cdf0e10cSrcweir                 else
184cdf0e10cSrcweir                     xContext = null;
185cdf0e10cSrcweir             }
186cdf0e10cSrcweir             catch (Exception e)
187cdf0e10cSrcweir             {
188cdf0e10cSrcweir                 System.err.println ("caught exception " + e + " while getting path to root");
189cdf0e10cSrcweir             }
190cdf0e10cSrcweir         }
191cdf0e10cSrcweir 
192cdf0e10cSrcweir         // Print the path in the accessibility tree from the given context to
193cdf0e10cSrcweir         // the root.
194cdf0e10cSrcweir         String sIndentation = new String ();
195cdf0e10cSrcweir         for (int i=aPathToRoot.size()-1; i>=0; i--)
196cdf0e10cSrcweir         {
197cdf0e10cSrcweir             XAccessibleContext xParentContext = (XAccessibleContext)aPathToRoot.get(i);
198cdf0e10cSrcweir             String sParentName = xParentContext.getAccessibleName();
199cdf0e10cSrcweir             if (sParentName.length() == 0)
200cdf0e10cSrcweir                 sParentName = "<unnamed> / Role "
201cdf0e10cSrcweir                     + NameProvider.getRoleName(xParentContext.getAccessibleRole());
202cdf0e10cSrcweir             msTextContent += sIndentation + sParentName + "\n";
203cdf0e10cSrcweir             sIndentation += msIndentation;
204cdf0e10cSrcweir         }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir         return sIndentation;
207cdf0e10cSrcweir     }
208cdf0e10cSrcweir 
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     /// The text widget that is used for the actual text display.
212cdf0e10cSrcweir     private JTextArea maText;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     /// The indentation with which an object's child is indented.
215cdf0e10cSrcweir     private final String msIndentation = new String("  ");
216cdf0e10cSrcweir 
217cdf0e10cSrcweir     /// The text content displayed by this object.
218cdf0e10cSrcweir     private String msTextContent = new String ();
219cdf0e10cSrcweir }
220