1 import java.awt.*;
2 import javax.swing.*;
3 import javax.swing.tree.*;
4 import java.awt.geom.Rectangle2D;
5 
6 import com.sun.star.beans.XPropertyChangeListener;
7 import com.sun.star.beans.PropertyChangeEvent;
8 
9 import com.sun.star.accessibility.XAccessible;
10 import com.sun.star.accessibility.XAccessibleContext;
11 import com.sun.star.accessibility.XAccessibleComponent;
12 import com.sun.star.accessibility.XAccessibleExtendedComponent;
13 import com.sun.star.accessibility.XAccessibleText;
14 import com.sun.star.accessibility.XAccessibleStateSet;
15 import com.sun.star.accessibility.AccessibleStateType;
16 
17 class CanvasShape
18 {
19     public final Color maHighlightColor = Color.red;
20     public final Color maSelectionColor = Color.green;
21     public final Color maFocusColor = Color.blue;
22 
23     //    public AccessibleObject (XAccessibleContext xContext, TreePath aPath)
24     public CanvasShape (AccTreeNode aNode)
25     {
26         maNode = aNode;
27         mxContext = aNode.getContext();
28         msName = "name unknown";
29         msDescription = "description unknown";
30         maShape = new Rectangle2D.Double (-10,-10,10,10);
31         maPosition = new Point (-10,-10);
32         maSize = new Dimension (10,10);
33         maFgColor = java.awt.Color.black;
34         maBgColor = Color.blue;
35         mnRole = -1;
36         mbHighlighted = false;
37         mbSelected = false;
38         mbFocused = false;
39         mxComponent = aNode.getComponent();
40 
41         update ();
42     }
43 
44 
45 
46     /** Update the data obtained from the xAccessible.
47     */
48     public void update ()
49     {
50         if (mxContext != null)
51         {
52             msName = mxContext.getAccessibleName();
53             msDescription = mxContext.getAccessibleDescription();
54             mnRole = mxContext.getAccessibleRole();
55 
56             // Extract the selected and focused flag.
57             XAccessibleStateSet xStateSet = mxContext.getAccessibleStateSet ();
58             if (xStateSet != null)
59             {
60                 mbSelected = xStateSet.contains (AccessibleStateType.SELECTED);
61                 mbFocused = xStateSet.contains (AccessibleStateType.FOCUSED);
62             }
63         }
64 
65         updateGeometry ();
66         if (mxComponent != null)
67         {
68             // Note: alpha values in office 0..255 have to be mapped to
69             //       255..0 in Java
70             Color aCol = new Color (mxComponent.getForeground(), true);
71             maFgColor = new Color (aCol.getRed (),
72                                    aCol.getGreen (),
73                                    aCol.getBlue (),
74                                    0xff - aCol.getAlpha ());
75             aCol = new Color (mxComponent.getBackground(), true);
76             maBgColor = new Color (aCol.getRed (),
77                                    aCol.getGreen (),
78                                    aCol.getBlue (),
79                                    0xff - aCol.getAlpha ());
80         }
81     }
82 
83     public void updateGeometry ()
84     {
85         if (mxComponent != null)
86         {
87             com.sun.star.awt.Point aLocationOnScreen = mxComponent.getLocationOnScreen();
88             com.sun.star.awt.Size aSizeOnScreen = mxComponent.getSize();
89             maPosition = new Point (
90                 aLocationOnScreen.X,
91                 aLocationOnScreen.Y);
92             maSize = new Dimension (
93                 aSizeOnScreen.Width,
94                 aSizeOnScreen.Height);
95         }
96     }
97 
98 
99     /** Paint the object into the specified canvas.  It is transformed
100         according to the specified offset and scale.
101     */
102     public void paint (Graphics2D g,
103         double nXOffset, double nYOffset, double nScaleFactor,
104         boolean bShowDescription, boolean bShowName, boolean bShowText)
105     {
106         try{
107             // Transform the object's position and size according to the
108             // specified offset and scale.
109             Point aLocation = new Point();
110             maShape = new Rectangle2D.Double (
111                 maPosition.x * nScaleFactor + nXOffset,
112                 maPosition.y * nScaleFactor + nYOffset,
113                 maSize.width * nScaleFactor,
114                 maSize.height * nScaleFactor);
115 
116             // Fill the object's bounding box with its background color if it
117             // has no children.
118             if (mxContext.getAccessibleChildCount() == 0)
119             {
120                 g.setColor (maBgColor);
121                 g.fill (maShape);
122             }
123 
124             // Remove alpha channel from color before drawing the frame.
125             Color color = maFgColor;
126             if (maFgColor.getAlpha()<128)
127                 color = new Color (maFgColor.getRed(), maFgColor.getGreen(), maFgColor.getBlue());
128             g.setColor (color);
129             g.draw (maShape);
130 
131             if (mbFocused)
132             {
133                 g.setColor (maFocusColor);
134                 for (int x=0; x<=2; x++)
135                     for (int y=0; y<=2; y++)
136                         g.fill (
137                             new Rectangle2D.Double (
138                                 maShape.x + x/2.0 * maShape.width-3,
139                                 maShape.y + y/2.0 * maShape.height-3,
140                                 6,
141                                 6));
142             }
143             if (mbSelected)
144             {
145                 g.setColor (maSelectionColor);
146                 for (int x=0; x<=2; x++)
147                     for (int y=0; y<=2; y++)
148                         g.draw (
149                             new Rectangle2D.Double (
150                                 maShape.x + x/2.0 * maShape.width-2,
151                                 maShape.y + y/2.0 * maShape.height-2,
152                                 4,
153                                 4));
154             }
155 
156             // Write the object's text OR name and description.
157             g.setColor (maFgColor);
158             if (bShowName)
159                 paintName (g);
160             if (bShowDescription)
161                 paintDescription (g);
162             if (bShowText)
163                 paintText (g);
164         }
165         catch (Exception e)
166         { // don't care
167         }
168     }
169 
170     public void paint_highlight (Graphics2D g,
171         double nXOffset, double nYOffset, double nScaleFactor)
172     {
173         if (mbHighlighted)
174             g.setColor (maHighlightColor);
175         else
176             g.setColor (maFgColor);
177         g.draw (maShape);
178     }
179 
180 
181 
182 
183     private void paintName (Graphics2D g)
184     {
185         g.drawString ("Name: " + msName,
186             (float)maShape.x+5,
187             (float)maShape.y+15);
188     }
189 
190 
191 
192     private void paintDescription (Graphics2D g)
193     {
194         g.drawString ("Description: " + msDescription,
195             (float)maShape.x+5,
196             (float)maShape.y+35);
197     }
198 
199 
200 
201 
202     private void paintText (Graphics2D g)
203     {
204         XAccessibleText xText = null;
205         // get XAccessibleText
206         xText = maNode.getText();
207 
208         // Draw every character in the text string.
209         if (xText != null)
210         {
211             String sText = xText.getText();
212             try
213             {
214                 for(int i = 0; i < sText.length(); i++)
215                 {
216                     com.sun.star.awt.Rectangle aRect =
217                         xText.getCharacterBounds(i);
218 
219                     double x = maShape.x + aRect.X;
220                     double y = maShape.y + aRect.Y + aRect.Height;
221 
222                     g.drawString(sText.substring(i, i+1), (float)x, (float)y);
223                 }
224             }
225             catch (com.sun.star.lang.IndexOutOfBoundsException e)
226             {}
227         }
228     }
229 
230 
231 
232 
233     /** Callback for disposing events.
234     */
235     public void disposing (com.sun.star.lang.EventObject e)
236     {
237         System.out.println ("Disposing");
238     }
239 
240 
241 
242 
243     /** Compute whether the specified point lies inside the object's
244         bounding box.
245     */
246     public boolean contains (int x, int y)
247     {
248         return (maShape.contains (x,y));
249     }
250 
251     public void highlight ()
252     {
253         mbHighlighted = true;
254     }
255 
256     public void unhighlight ()
257     {
258         mbHighlighted = false;
259     }
260 
261     public boolean isHighlighted ()
262     {
263         return mbHighlighted;
264     }
265 
266     public Rectangle getBBox ()
267     {
268         return new Rectangle (maPosition, maSize);
269     }
270 
271     public Point getOrigin ()
272     {
273         return maPosition;
274     }
275 
276     public TreePath getPath ()
277     {
278         return new TreePath (maNode.createPath());
279     }
280 
281     public int getRole ()
282     {
283         return mnRole;
284     }
285 
286     public XAccessibleContext getContext ()
287     {
288         return mxContext;
289     }
290 
291     public XAccessibleComponent getComponent ()
292     {
293         return mxComponent;
294     }
295 
296     public String toString ()
297     {
298         return ">"+msName+", "+msDescription+" +"+maPosition.x+"+"+maPosition.y
299             +"x"+maSize.width+"x"+maSize.height+"<";
300     }
301 
302     private AccTreeNode
303         maNode;
304     private XAccessibleContext
305         mxContext;
306     private XAccessibleComponent
307         mxComponent;
308     private String
309         msDescription,
310         msName;
311     private Rectangle2D.Double
312         maShape;
313     private Point
314         maPosition;
315     private Dimension
316         maTransformedSize,
317         maSize;
318     private Color
319         maFgColor,
320         maBgColor;
321     private boolean
322         // Highlighting objects is an internal concept.  Corresponds to selection in the tree view.
323         mbHighlighted,
324         // Set when the accessible object is selected.
325         mbSelected,
326         // Set when the accessible object is focused.
327         mbFocused;
328     private int
329         mnRole;
330 }
331