1 import com.sun.star.uno.UnoRuntime;
2 import com.sun.star.accessibility.*;
3 import java.util.Vector;
4 
5 /**
6  * The node type for the AccessibleTreeModel.
7  * This implements all the child-handling based on the appropriate
8  * NodeHandlers. Trivial nodes can be implemented by any Object
9  * type.
10  */
11 class AccTreeNode
12     extends AccessibleTreeNode
13 {
14     class HandlerDescriptor
15     {
16         public HandlerDescriptor (NodeHandler aHandler)
17         {
18             maHandler = aHandler;
19             mnChildCount = -1;
20         }
21         public NodeHandler maHandler;
22         public int mnChildCount;
23     }
24     /// NodeHandlers for this node
25     private Vector maHandlers;
26 
27     // The accessible context of this node.
28     private XAccessible mxAccessible;
29     private XAccessibleContext mxContext;
30     private XAccessibleComponent mxComponent;
31     private XAccessibleText mxText;
32     private XAccessibleTable mxTable;
33 
34     public AccTreeNode (XAccessible xAccessible, XAccessibleContext xContext, AccessibleTreeNode aParent)
35     {
36         this (xAccessible, xContext, xContext, aParent);
37     }
38 
39     public AccTreeNode (XAccessible xAccessible, XAccessibleContext xContext, Object aDisplay, AccessibleTreeNode aParent)
40     {
41         super (aDisplay, aParent);
42 
43         maHandlers = new Vector(5);
44         mxContext = xContext;
45         mxAccessible = xAccessible;
46     }
47 
48     /** Update the internal data extracted from the corresponding accessible
49         object.  This is done by replacing every handler by a new one.  An
50         update method at each handler would be better of course.
51     */
52     public void update ()
53     {
54         for (int i=0; i<maHandlers.size(); i++)
55         {
56             System.out.println ("replacing handler " + i);
57             HandlerDescriptor aDescriptor = (HandlerDescriptor)maHandlers.get(i);
58             aDescriptor.maHandler = aDescriptor.maHandler.createHandler (mxContext);
59             aDescriptor.mnChildCount =
60                     aDescriptor.maHandler.getChildCount (this);
61         }
62     }
63 
64     public XAccessibleContext getContext ()
65     {
66         return mxContext;
67     }
68 
69     public XAccessibleComponent getComponent ()
70     {
71         if (mxComponent == null && mxContext != null)
72             mxComponent = (XAccessibleComponent)UnoRuntime.queryInterface(
73                 XAccessibleComponent.class, mxContext);
74         return mxComponent;
75     }
76 
77     public XAccessibleExtendedComponent getExtendedComponent ()
78     {
79         if (mxComponent == null)
80             getComponent();
81         if (mxComponent != null)
82             return (XAccessibleExtendedComponent)UnoRuntime.queryInterface(
83                 XAccessibleExtendedComponent.class, mxComponent);
84         else
85             return null;
86     }
87 
88     public XAccessibleText getText ()
89     {
90         if (mxText == null && mxContext != null)
91             mxText = (XAccessibleText)UnoRuntime.queryInterface(
92                 XAccessibleText.class, mxContext);
93         return mxText;
94     }
95 
96     public XAccessibleEditableText getEditText ()
97     {
98         return (XAccessibleEditableText)UnoRuntime.queryInterface(
99                 XAccessibleEditableText.class, mxContext);
100     }
101 
102     public XAccessibleTable getTable ()
103     {
104         if (mxTable == null && mxContext != null)
105             mxTable = (XAccessibleTable)UnoRuntime.queryInterface(
106                 XAccessibleTable.class, mxContext);
107         return mxTable;
108     }
109 
110 
111     public XAccessible getAccessible()
112     {
113         if ((mxAccessible == null) && (mxContext != null))
114             mxAccessible = (XAccessible)UnoRuntime.queryInterface(
115                 XAccessible.class, mxContext);
116         return mxAccessible;
117     }
118 
119     public XAccessibleSelection getSelection ()
120     {
121         return (XAccessibleSelection)UnoRuntime.queryInterface(
122                 XAccessibleSelection.class, mxContext);
123     }
124 
125     public void addHandler( NodeHandler aHandler )
126     {
127         if (aHandler != null)
128             maHandlers.add (new HandlerDescriptor (aHandler));
129     }
130 
131 
132     /** iterate over handlers and return child sum */
133     protected HandlerDescriptor getHandlerDescriptor (int i)
134     {
135         HandlerDescriptor aDescriptor = (HandlerDescriptor)maHandlers.get(i);
136         if (aDescriptor.mnChildCount < 0)
137             aDescriptor.mnChildCount =
138                     aDescriptor.maHandler.getChildCount (this);
139         return aDescriptor;
140     }
141 
142     public int getChildCount()
143     {
144         int nChildCount = 0;
145         for (int i = 0; i < maHandlers.size(); i++)
146         {
147             HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
148             nChildCount += aDescriptor.mnChildCount;
149         }
150         return nChildCount;
151     }
152 
153     /** iterate over handlers until the child is found */
154     public AccessibleTreeNode getChild (int nIndex)
155         throws IndexOutOfBoundsException
156     {
157         if( nIndex >= 0 )
158         {
159             for(int i = 0; i < maHandlers.size(); i++)
160             {
161                 // check if this handler has the child, and if not
162                 // search with next handler
163                 HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
164                 if (nIndex < aDescriptor.mnChildCount)
165                     return aDescriptor.maHandler.getChild (this, nIndex);
166                 else
167                     nIndex -= aDescriptor.mnChildCount;
168             }
169         }
170         else
171             throw new IndexOutOfBoundsException();
172 
173         // nothing found?
174         return null;
175     }
176 
177     public AccessibleTreeNode getChildNoCreate (int nIndex)
178         throws IndexOutOfBoundsException
179     {
180         if( nIndex >= 0 )
181         {
182             for(int i = 0; i < maHandlers.size(); i++)
183             {
184                 // check if this handler has the child, and if not
185                 // search with next handler
186                 HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
187                 if (nIndex < aDescriptor.mnChildCount)
188                     return aDescriptor.maHandler.getChildNoCreate (this, nIndex);
189                 else
190                     nIndex -= aDescriptor.mnChildCount;
191             }
192         }
193         else
194             throw new IndexOutOfBoundsException();
195 
196         // nothing found?
197         return null;
198     }
199 
200     public boolean removeChild (int nIndex)
201         throws IndexOutOfBoundsException
202     {
203         boolean bStatus = false;
204         if (nIndex >= 0)
205         {
206             for (int i=0; i<maHandlers.size(); i++)
207             {
208                 // check if this handler has the child, and if not
209                 // search with next handler
210                 HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
211                 if (nIndex < aDescriptor.mnChildCount)
212                 {
213                     bStatus = aDescriptor.maHandler.removeChild (this, nIndex);
214                     aDescriptor.mnChildCount = aDescriptor.maHandler.getChildCount (this);
215                     break;
216                 }
217                 else
218                     nIndex -= aDescriptor.mnChildCount;
219             }
220         }
221         else
222             throw new IndexOutOfBoundsException();
223 
224         return bStatus;
225     }
226 
227 
228     public int indexOf (AccessibleTreeNode aNode)
229     {
230         int nBaseIndex = 0;
231         if (aNode != null)
232         {
233             for (int i=0; i<maHandlers.size(); i++)
234             {
235                 HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
236                 int nIndex = aDescriptor.maHandler.indexOf (aNode);
237                 if (nIndex >= 0)
238                     return nBaseIndex + nIndex;
239                 else
240                     nBaseIndex += aDescriptor.mnChildCount;
241             }
242         }
243 
244         return -1;
245     }
246 
247     /** this node is a leaf if have no handlers, or is those
248             handlers show no children */
249     public boolean isLeaf()
250     {
251         return (maHandlers.size() == 0);// || (getChildCount() == 0);
252     }
253 
254     public boolean equals (Object aOther)
255     {
256         return (this == aOther) || (aOther!=null && aOther.equals(mxContext));
257     }
258 
259 
260     /** iterate over handlers until the child is found */
261     public void getActions(Vector aActions)
262     {
263         for(int i = 0; i < maHandlers.size(); i++)
264         {
265             HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
266             NodeHandler aHandler = aDescriptor.maHandler;
267             String[] aHandlerActions = aHandler.getActions (this);
268             for(int j = 0; j < aHandlerActions.length; j++ )
269             {
270                 aActions.add( aHandlerActions[j] );
271             }
272         }
273     }
274 
275     public void performAction( int nIndex )
276     {
277         if( nIndex >= 0 )
278         {
279             for(int i = 0; i < maHandlers.size(); i++)
280             {
281                 // check if this handler has the child, and if not
282                 // search with next handler
283                 HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
284                 NodeHandler aHandler = aDescriptor.maHandler;
285                 int nCount = aHandler.getActions(this).length;
286                 if( nCount > nIndex )
287                 {
288                     aHandler.performAction(this, nIndex );
289                     return;
290                 }
291                 else
292                     nIndex -= nCount;
293             }
294         }
295     }
296 
297     /** Try to add the specified accessible object as new accessible child of the
298         AccessibleTreeHandler.
299         Note that child is used in another context than
300         it is used in the other methods of this class.
301     */
302     public AccessibleTreeNode addAccessibleChild (XAccessible xChild)
303     {
304         for(int i = 0; i < maHandlers.size(); i++)
305         {
306             HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
307             if (aDescriptor.maHandler instanceof AccessibleTreeHandler)
308             {
309                 AccessibleTreeHandler aHandler = (AccessibleTreeHandler)aDescriptor.maHandler;
310                 AccessibleTreeNode aNode = aHandler.addAccessibleChild (this, xChild);
311                 aDescriptor.mnChildCount = aHandler.getChildCount (this);
312                 return aNode;
313             }
314         }
315         return null;
316     }
317 
318     /** Update the specified handlers.
319         @return
320             The returned array containes the indices of the updated children
321             and can be used to create a TreeModelEvent.
322     */
323     public Vector updateChildren (java.lang.Class class1)
324     {
325         return updateChildren (class1, null);
326     }
327 
328     public Vector updateChildren (java.lang.Class class1, java.lang.Class class2)
329     {
330         Vector aChildIndices = new Vector();
331         int nOffset = 0;
332         for(int i=0; i < maHandlers.size(); i++)
333         {
334             HandlerDescriptor aDescriptor = getHandlerDescriptor (i);
335             if ((class1.isInstance(aDescriptor.maHandler))
336                 || (class2 !=null && class2.isInstance(aDescriptor.maHandler)))
337             {
338                 aDescriptor.maHandler.update(this);
339                 // Get updated number of children.
340                 int nChildCount = aDescriptor.maHandler.getChildCount (this);
341                 aDescriptor.mnChildCount = nChildCount;
342                 // Fill in the indices of the updated children.
343                 for (int j=0; j<nChildCount; j++)
344                     aChildIndices.add(new Integer(j+nOffset));
345             }
346             nOffset += aDescriptor.mnChildCount;
347         }
348         return aChildIndices;
349     }
350 }
351