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 import java.awt.event.ActionListener;
25 import javax.swing.*;
26 import java.awt.*;
27 import java.util.*;
28 
29 import com.sun.star.awt.XTopWindowListener;
30 import com.sun.star.uno.UnoRuntime;
31 import com.sun.star.bridge.XUnoUrlResolver;
32 import com.sun.star.lang.XMultiServiceFactory;
33 import com.sun.star.accessibility.*;
34 import com.sun.star.awt.XExtendedToolkit;
35 
36 /** This class is used as a thread and registers or unregsiters a listener
37     given the constructor at all nodes of a tree of accessibility objects.
38 */
39 public class RegistrationThread
40     implements Runnable
41 {
42     /** Start a new thread that adds or removes the given listener at all
43         accessible objects in the sub-tree rooted in the given accessible
44         object.
45         @param aListener
46             The listener that is added or removed.
47         @param xRoot
48             The root of the sub-tree of accessibility objects.
49         @param bRegister
50             This flag decides whether to add or remove the listener.
51     */
RegistrationThread( EventListenerProxy aListener, XAccessibleContext xRoot, boolean bRegister, boolean bShowMessages)52     public RegistrationThread (
53         EventListenerProxy aListener,
54         XAccessibleContext xRoot,
55         boolean bRegister,
56         boolean bShowMessages)
57     {
58         maListener = aListener;
59         mxRoot = xRoot;
60         mbRegister = bRegister;
61         mbShowMessages = bShowMessages;
62 
63         if (mxRoot != null)
64         {
65             if (mbShowMessages)
66                 MessageArea.println ("starting to register at " + mxRoot.getAccessibleName());
67             new Thread (this, "RegistrationThread").start();
68         }
69     }
70 
71 
72 
run()73     public void run ()
74     {
75         System.out.println ("starting registration");
76         long nNodeCount = traverseTree (mxRoot);
77         System.out.println ("ending registration");
78         if (mbShowMessages)
79         {
80             if ( ! mbRegister)
81                 MessageArea.print ("un");
82             MessageArea.println ("registered at " + nNodeCount
83                 + " objects in accessibility tree of " + mxRoot.getAccessibleName());
84         }
85     }
86 
87 
88 
89 
90     /** Register this object as listener for accessibility events at all nodes
91         of the given tree.
92         @param xRoot
93             The root node of the tree at which to register.
94     */
traverseTree(XAccessibleContext xRoot)95     public long traverseTree (XAccessibleContext xRoot)
96     {
97         long nNodeCount = 0;
98         if (xRoot != null)
99         {
100             // Register the root node.
101             XAccessibleEventBroadcaster xBroadcaster =
102                 (XAccessibleEventBroadcaster) UnoRuntime.queryInterface (
103                     XAccessibleEventBroadcaster.class,
104                     xRoot);
105             if (xBroadcaster != null)
106             {
107                 if (mbRegister)
108                     xBroadcaster.addEventListener (maListener);
109                 else
110                     xBroadcaster.removeEventListener (maListener);
111                 nNodeCount += 1;
112             }
113 
114             // Call this method recursively to register all sub-trees.
115             try
116             {
117                 int nChildCount = xRoot.getAccessibleChildCount();
118                 for (int i=0; i<nChildCount; i++)
119                 {
120                     XAccessible xChild = xRoot.getAccessibleChild (i);
121                     if (xChild != null)
122                         nNodeCount += traverseTree (xChild.getAccessibleContext());
123                 }
124             }
125             catch (com.sun.star.lang.IndexOutOfBoundsException aException)
126             {
127                 // The set of children has changed since our last call to
128                 // getAccesibleChildCount().  Don't try any further on this
129                 // sub-tree.
130             }
131             catch (com.sun.star.lang.DisposedException aException)
132             {
133                 // The child has been destroyed since our last call to
134                 // getAccesibleChildCount().  That is OK. Don't try any
135                 // further on this sub-tree.
136             }
137         }
138         return nNodeCount;
139     }
140 
141     private EventListenerProxy maListener;
142     private XAccessibleContext mxRoot;
143     private boolean mbRegister;
144     private boolean mbShowMessages;
145 }
146