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 import com.sun.star.awt.XWindow; 23 import com.sun.star.awt.XExtendedToolkit; 24 import com.sun.star.accessibility.XAccessible; 25 import com.sun.star.accessibility.XAccessibleContext; 26 import com.sun.star.uno.XInterface; 27 import com.sun.star.uno.UnoRuntime; 28 import javax.swing.event.TreeModelEvent; 29 30 /** Listen for top window events and create or delete children of the tree 31 model accordingly. 32 */ 33 class TopWindowListener 34 { TopWindowListener(AccessibilityTreeModel aModel, SimpleOffice aOffice)35 TopWindowListener (AccessibilityTreeModel aModel, SimpleOffice aOffice) 36 { 37 maModel = aModel; 38 maOffice = aOffice; 39 } 40 41 42 43 44 /** Use this function to initially fill the accessibility object tree 45 view with nodes for top level windows. 46 */ Initialize()47 public void Initialize () 48 { 49 XExtendedToolkit xToolkit = maOffice.getExtendedToolkit(); 50 if (xToolkit != null) 51 { 52 maModel.lock (); 53 int nTopWindowCount = xToolkit.getTopWindowCount(); 54 MessageArea.println ("There are " + nTopWindowCount + " top windows."); 55 for (int i=0; i<nTopWindowCount; i++) 56 { 57 try 58 { 59 XAccessible xAccessible = maOffice.getAccessibleObject( 60 xToolkit.getTopWindow (i)); 61 // Uncomment the following line to get the real root of 62 // the accessible tree that xAccessible belongs to. 63 // xAccessible = maOffice.getAccessibleRoot(xAccessible); 64 AddTopLevelNode (xAccessible); 65 } 66 catch (Exception e) 67 { 68 System.out.println ("caught exception: " + e); 69 e.printStackTrace(); 70 } 71 } 72 maModel.unlock ((AccessibleTreeNode)maModel.getRoot()); 73 } 74 } 75 76 77 78 /** Add a new top level node which, to be exact, will be placed on the 79 second layer of the tree. 80 @param xNewTopLevelObject 81 The accessible object of the new top level window. 82 */ AddTopLevelNode(XAccessible xNewTopLevelObject)83 private void AddTopLevelNode (XAccessible xNewTopLevelObject) 84 { 85 System.out.println ("adding top level window"); 86 if (xNewTopLevelObject != null) 87 { 88 XAccessibleContext xContext = xNewTopLevelObject.getAccessibleContext(); 89 if (xContext == null) 90 System.out.println ("top level window not accessible"); 91 else 92 { 93 if ( ! FilterTopLevelNode (xContext)) 94 { 95 Object aRootObject = maModel.getRoot(); 96 if (aRootObject instanceof VectorNode) 97 { 98 VectorNode aRoot = (VectorNode) aRootObject; 99 AccessibleTreeNode aNode = 100 NodeFactory.Instance().createDefaultNode (xNewTopLevelObject, aRoot); 101 aRoot.addChild (aNode); 102 maModel.fireTreeNodesInserted (maModel.createEvent (aRoot, aNode)); 103 } 104 } 105 } 106 } 107 } 108 109 /** Ignore windows that have no accessible name, i.e. do not represent 110 document windows. 111 @return 112 Returns <true/> when the given object should not be displayed, 113 i.e. filtered out. 114 */ FilterTopLevelNode(XAccessibleContext xContext)115 private boolean FilterTopLevelNode (XAccessibleContext xContext) 116 { 117 // No filtering at the moment. 118 return false; 119 // return xContext.getAccessibleName().length() == 0; 120 } 121 122 123 124 125 /** Remove an existing top level node from the tree. 126 @param xNewTopLevelObject 127 The accessible object to remove. 128 */ RemoveTopLevelNode(XAccessible xTopLevelObject)129 private void RemoveTopLevelNode (XAccessible xTopLevelObject) 130 { 131 Object aObject = maModel.getRoot(); 132 if (aObject instanceof VectorNode && xTopLevelObject != null) 133 { 134 System.out.println ("removing node " + xTopLevelObject); 135 VectorNode aRoot = (VectorNode) aObject; 136 maModel.removeNode (xTopLevelObject.getAccessibleContext()); 137 } 138 } 139 140 141 142 143 144 /** This method exists for debugging. It prints a list of all top 145 level windows. 146 */ ShowAllTopLevelWindows()147 private void ShowAllTopLevelWindows () 148 { 149 XExtendedToolkit xToolkit = maOffice.getExtendedToolkit(); 150 if (xToolkit != null) 151 { 152 int nTopWindowCount = xToolkit.getTopWindowCount(); 153 for (int i=0; i<nTopWindowCount; i++) 154 { 155 try 156 { 157 System.out.println (i + " : " + xToolkit.getTopWindow (i)); 158 } 159 catch (Exception e) 160 { 161 System.out.println ("caught exception; " + e); 162 } 163 } 164 } 165 } 166 167 168 169 170 // XTopWindowListener windowOpened(final com.sun.star.lang.EventObject aEvent)171 public void windowOpened (final com.sun.star.lang.EventObject aEvent) 172 throws RuntimeException 173 { 174 if (maModel != null) 175 { 176 XWindow xWindow = (XWindow) UnoRuntime.queryInterface( 177 XWindow.class, aEvent.Source); 178 if (xWindow == null) 179 System.out.println ("event source is no XWindow"); 180 else 181 { 182 XAccessible xAccessible = maOffice.getAccessibleObject(xWindow); 183 if (xAccessible == null) 184 System.out.println ("event source is no XAccessible"); 185 else 186 AddTopLevelNode (xAccessible); 187 } 188 } 189 } 190 191 192 193 windowClosed(final com.sun.star.lang.EventObject aEvent)194 public void windowClosed (final com.sun.star.lang.EventObject aEvent) 195 throws RuntimeException 196 { 197 if (maModel != null) 198 { 199 XWindow xWindow = (XWindow) UnoRuntime.queryInterface( 200 XWindow.class, aEvent.Source); 201 if (xWindow == null) 202 System.out.println ("event source is no XWindow"); 203 else 204 { 205 XAccessible xAccessible = maOffice.getAccessibleObject(xWindow); 206 if (xAccessible == null) 207 System.out.println ("event source is no XAccessible"); 208 else 209 RemoveTopLevelNode (xAccessible); 210 } 211 } 212 } 213 disposing(final com.sun.star.lang.EventObject aEvent)214 public void disposing (final com.sun.star.lang.EventObject aEvent) 215 { 216 System.out.println ("Top window disposed: " + aEvent); 217 } 218 219 220 221 222 private AccessibilityTreeModel 223 maModel; 224 private SimpleOffice 225 maOffice; 226 } 227