1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * The Contents of this file are made available subject to the terms of 4*cdf0e10cSrcweir * the BSD license. 5*cdf0e10cSrcweir * 6*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 7*cdf0e10cSrcweir * All rights reserved. 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * Redistribution and use in source and binary forms, with or without 10*cdf0e10cSrcweir * modification, are permitted provided that the following conditions 11*cdf0e10cSrcweir * are met: 12*cdf0e10cSrcweir * 1. Redistributions of source code must retain the above copyright 13*cdf0e10cSrcweir * notice, this list of conditions and the following disclaimer. 14*cdf0e10cSrcweir * 2. Redistributions in binary form must reproduce the above copyright 15*cdf0e10cSrcweir * notice, this list of conditions and the following disclaimer in the 16*cdf0e10cSrcweir * documentation and/or other materials provided with the distribution. 17*cdf0e10cSrcweir * 3. Neither the name of Sun Microsystems, Inc. nor the names of its 18*cdf0e10cSrcweir * contributors may be used to endorse or promote products derived 19*cdf0e10cSrcweir * from this software without specific prior written permission. 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22*cdf0e10cSrcweir * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23*cdf0e10cSrcweir * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24*cdf0e10cSrcweir * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25*cdf0e10cSrcweir * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26*cdf0e10cSrcweir * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27*cdf0e10cSrcweir * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 28*cdf0e10cSrcweir * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 29*cdf0e10cSrcweir * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 30*cdf0e10cSrcweir * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 31*cdf0e10cSrcweir * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32*cdf0e10cSrcweir * 33*cdf0e10cSrcweir *************************************************************************/ 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir import java.awt.Color; 36*cdf0e10cSrcweir import java.awt.Font; 37*cdf0e10cSrcweir import java.awt.Dimension; 38*cdf0e10cSrcweir import javax.swing.JTextArea; 39*cdf0e10cSrcweir import javax.swing.JScrollPane; 40*cdf0e10cSrcweir import java.util.Vector; 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessible; 43*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleContext; 44*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleComponent; 45*cdf0e10cSrcweir import com.sun.star.accessibility.XAccessibleStateSet; 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir import com.sun.star.uno.AnyConverter; 48*cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir import com.sun.star.awt.Point; 51*cdf0e10cSrcweir import com.sun.star.awt.Size; 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir /** Display textual information for a given accessible object. This 54*cdf0e10cSrcweir includes the names of that object of its ancestors as well as some 55*cdf0e10cSrcweir information retrieved from the XAccessibleContext and 56*cdf0e10cSrcweir XAccessibleComponent interfaces. 57*cdf0e10cSrcweir */ 58*cdf0e10cSrcweir class TextualDisplay 59*cdf0e10cSrcweir extends JScrollPane 60*cdf0e10cSrcweir implements IAccessibleObjectDisplay 61*cdf0e10cSrcweir { 62*cdf0e10cSrcweir /** Create a new scroll pane that contains a text widget which display 63*cdf0e10cSrcweir information about given accessible objects. 64*cdf0e10cSrcweir */ 65*cdf0e10cSrcweir public TextualDisplay () 66*cdf0e10cSrcweir { 67*cdf0e10cSrcweir // Create a text widget for displaying the text information... 68*cdf0e10cSrcweir maText = new JTextArea (80,10); 69*cdf0e10cSrcweir maText.setBackground (new Color (250,240,230)); 70*cdf0e10cSrcweir maText.setFont (new Font ("Courier", Font.PLAIN, 11)); 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir // ...and set-up the scroll pane to show this widget. 73*cdf0e10cSrcweir setViewportView (maText); 74*cdf0e10cSrcweir setVerticalScrollBarPolicy (JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 75*cdf0e10cSrcweir setHorizontalScrollBarPolicy (JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 76*cdf0e10cSrcweir } 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir /** Set the accessible object to display. Call this method e.g. when a 82*cdf0e10cSrcweir new object has been focused. 83*cdf0e10cSrcweir */ 84*cdf0e10cSrcweir public synchronized void setAccessibleObject (XAccessibleContext xContext) 85*cdf0e10cSrcweir { 86*cdf0e10cSrcweir // First clear the display area. 87*cdf0e10cSrcweir msTextContent = new String (); 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir if (xContext != null) 90*cdf0e10cSrcweir { 91*cdf0e10cSrcweir String sIndentation = showParents (xContext); 92*cdf0e10cSrcweir showContextInfo (xContext, sIndentation); 93*cdf0e10cSrcweir showComponentInfo (xContext, sIndentation); 94*cdf0e10cSrcweir } 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir maText.setText (msTextContent); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir public synchronized void updateAccessibleObject (XAccessibleContext xContext) 103*cdf0e10cSrcweir { 104*cdf0e10cSrcweir setAccessibleObject (xContext); 105*cdf0e10cSrcweir } 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir /** Show some of the information available over the given object's 110*cdf0e10cSrcweir XAccessibleContext interface. 111*cdf0e10cSrcweir */ 112*cdf0e10cSrcweir private void showContextInfo (XAccessibleContext xContext, String sIndentation) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir // Show the description. 115*cdf0e10cSrcweir msTextContent += sIndentation + "Description: " 116*cdf0e10cSrcweir + xContext.getAccessibleDescription() + "\n"; 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir showStates (xContext, sIndentation); 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir /** Show a list of all of the the given object's states. Use the 125*cdf0e10cSrcweir NameConverter class to transform the numerical state ids into human 126*cdf0e10cSrcweir readable names. 127*cdf0e10cSrcweir @param xContext 128*cdf0e10cSrcweir The accessible context for which to show the state names. 129*cdf0e10cSrcweir */ 130*cdf0e10cSrcweir private void showStates (XAccessibleContext xContext, String sIndentation) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir // Get the state set object... 133*cdf0e10cSrcweir XAccessibleStateSet xStateSet = xContext.getAccessibleStateSet(); 134*cdf0e10cSrcweir // ...and retrieve an array of numerical ids. 135*cdf0e10cSrcweir short aStates[] = xStateSet.getStates(); 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir // Iterate over the array and print the names of the states. 138*cdf0e10cSrcweir msTextContent += sIndentation + "States : "; 139*cdf0e10cSrcweir for (int i=0; i<aStates.length; i++) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir if (i > 0) 142*cdf0e10cSrcweir msTextContent += ", "; 143*cdf0e10cSrcweir msTextContent += NameProvider.getStateName(aStates[i]); 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir msTextContent += "\n"; 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir /** When the given object supports the XAccessibleComponent interface then 152*cdf0e10cSrcweir show its size and location on the screen. 153*cdf0e10cSrcweir */ 154*cdf0e10cSrcweir private void showComponentInfo (XAccessibleContext xContext, String sIndentation) 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir // Try to cast the given accessible context to the 157*cdf0e10cSrcweir // XAccessibleComponent interface. 158*cdf0e10cSrcweir XAccessibleComponent xComponent = 159*cdf0e10cSrcweir (XAccessibleComponent)UnoRuntime.queryInterface( 160*cdf0e10cSrcweir XAccessibleComponent.class, xContext); 161*cdf0e10cSrcweir if (xComponent != null) 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir Point aLocation = xComponent.getLocationOnScreen(); 164*cdf0e10cSrcweir msTextContent += sIndentation + "Position : " 165*cdf0e10cSrcweir + aLocation.X + ", " + aLocation.Y + "\n"; 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir Size aSize = xComponent.getSize(); 168*cdf0e10cSrcweir msTextContent += sIndentation + "Size : " 169*cdf0e10cSrcweir + aSize.Width + ", " + aSize.Height + "\n"; 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir /** Print the names of the given object and its parents and return an 178*cdf0e10cSrcweir indentation string that can be used to print further information 179*cdf0e10cSrcweir about the object. 180*cdf0e10cSrcweir */ 181*cdf0e10cSrcweir private String showParents (XAccessibleContext xContext) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir // Create the path from the given object to its tree's root. 184*cdf0e10cSrcweir Vector aPathToRoot = new Vector(); 185*cdf0e10cSrcweir while (xContext != null) 186*cdf0e10cSrcweir { 187*cdf0e10cSrcweir aPathToRoot.add (xContext); 188*cdf0e10cSrcweir // Go up the hierarchy one level to the object's parent. 189*cdf0e10cSrcweir try 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir XAccessible xParent = xContext.getAccessibleParent(); 192*cdf0e10cSrcweir if (xParent != null) 193*cdf0e10cSrcweir xContext = xParent.getAccessibleContext(); 194*cdf0e10cSrcweir else 195*cdf0e10cSrcweir xContext = null; 196*cdf0e10cSrcweir } 197*cdf0e10cSrcweir catch (Exception e) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir System.err.println ("caught exception " + e + " while getting path to root"); 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir // Print the path in the accessibility tree from the given context to 204*cdf0e10cSrcweir // the root. 205*cdf0e10cSrcweir String sIndentation = new String (); 206*cdf0e10cSrcweir for (int i=aPathToRoot.size()-1; i>=0; i--) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir XAccessibleContext xParentContext = (XAccessibleContext)aPathToRoot.get(i); 209*cdf0e10cSrcweir String sParentName = xParentContext.getAccessibleName(); 210*cdf0e10cSrcweir if (sParentName.length() == 0) 211*cdf0e10cSrcweir sParentName = "<unnamed> / Role " 212*cdf0e10cSrcweir + NameProvider.getRoleName(xParentContext.getAccessibleRole()); 213*cdf0e10cSrcweir msTextContent += sIndentation + sParentName + "\n"; 214*cdf0e10cSrcweir sIndentation += msIndentation; 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir return sIndentation; 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir /// The text widget that is used for the actual text display. 223*cdf0e10cSrcweir private JTextArea maText; 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir /// The indentation with which an object's child is indented. 226*cdf0e10cSrcweir private final String msIndentation = new String(" "); 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir /// The text content displayed by this object. 229*cdf0e10cSrcweir private String msTextContent = new String (); 230*cdf0e10cSrcweir } 231