bump product version to 5.0.4.1
[LibreOffice.git] / toolkit / test / accessibility / AccessibilityTree.java
blobd750bf75c8115a8ba87a92875f6b47ee84a7a41d
1 /*
2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 import java.awt.Cursor;
20 import java.awt.event.ActionEvent;
21 import java.awt.event.MouseAdapter;
22 import java.awt.event.MouseEvent;
23 import java.util.ArrayList;
25 import javax.swing.AbstractAction;
26 import javax.swing.JPopupMenu;
27 import javax.swing.JTree;
28 import javax.swing.event.TreeExpansionEvent;
29 import javax.swing.event.TreeExpansionListener;
30 import javax.swing.event.TreeWillExpandListener;
31 import javax.swing.tree.TreePath;
33 import com.sun.star.accessibility.XAccessibleContext;
37 /** This is the tree component that is responsible for displaying the
38 contents of the tree model on the screen.
40 public class AccessibilityTree
41 implements TreeExpansionListener, TreeWillExpandListener
43 /** Create a new accessibility tree. Use the specified message display
44 for displaying messages and the specified canvas to draw the
45 graphical representations of accessible objects on.
47 public AccessibilityTree ()
49 maTree = new JTree ();
51 AccessibilityTreeModel aModel =
52 new AccessibilityTreeModel (
53 new StringNode ("Please press Update button", null));
54 maTree.setModel (aModel);
56 maTree.addMouseListener (new MouseListener (this));
58 // Listen to expansions and collapses to change the mouse cursor.
59 mnExpandLevel = 0;
60 maTree.addTreeWillExpandListener (this);
61 maTree.addTreeExpansionListener (this);
64 public JTree getComponent ()
66 return maTree;
69 // Change cursor during expansions to show the user that this is a
70 // lengthy operation.
71 public void treeWillExpand (TreeExpansionEvent e)
73 if (mnExpandLevel == 0)
75 maTree.setCursor (new Cursor (Cursor.WAIT_CURSOR));
77 mnExpandLevel += 1;
79 public void treeWillCollapse (TreeExpansionEvent e)
81 if (mnExpandLevel == 0)
83 maTree.setCursor (new Cursor (Cursor.WAIT_CURSOR));
85 mnExpandLevel += 1;
87 public void treeExpanded (TreeExpansionEvent e)
89 mnExpandLevel -= 1;
90 if (mnExpandLevel == 0)
92 maTree.setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
95 public void treeCollapsed (TreeExpansionEvent e)
97 mnExpandLevel -= 1;
98 if (mnExpandLevel == 0)
100 maTree.setCursor (new Cursor (Cursor.DEFAULT_CURSOR));
106 public void SetCanvas (Canvas aCanvas)
108 ((AccessibilityTreeModel)maTree.getModel()).setCanvas(aCanvas);
111 /** Expand the nodes in the subtree rooted in aNode according to the
112 specified expander. The tree is locked during the expansion.
114 private void expandTree (AccessibleTreeNode aNode, Expander aExpander)
116 if (mnExpandLevel == 0)
118 maTree.setEnabled (false);
120 mnExpandLevel += 1;
122 ((AccessibilityTreeModel)maTree.getModel()).lock ();
126 expandTree (new TreePath (aNode.createPath()), aExpander);
128 catch (Exception e)
130 // Ignore
133 mnExpandLevel -= 1;
134 if (mnExpandLevel == 0)
136 maTree.setEnabled (true);
137 ((AccessibilityTreeModel)maTree.getModel()).unlock (aNode);
141 private TreePath expandTree( TreePath aPath, Expander aExpander )
143 // return first expanded object
144 TreePath aFirst = null;
148 // get 'our' object
149 Object aObj = aPath.getLastPathComponent();
151 // expand this object, if the Expander tells us so
152 if( aExpander.expand( aObj ) )
154 maTree.expandPath (aPath);
155 aFirst = aPath;
158 // visit all children
159 if (aObj instanceof AccessibleTreeNode)
161 AccessibleTreeNode aNode = (AccessibleTreeNode)aObj;
162 int nLength = aNode.getChildCount();
163 for( int i = 0; i < nLength; i++ )
165 TreePath aRet = expandTree(
166 aPath.pathByAddingChild( aNode.getChild( i ) ),
167 aExpander );
168 if( aFirst == null )
169 aFirst = aRet;
173 catch (Exception e)
175 System.out.println ("caught exception while expanding tree path "
176 + aPath + ": " + e);
177 e.printStackTrace ();
180 return aFirst;
184 /** Expand all nodes and their subtrees that represent shapes. Call
185 * this method from the outside. */
186 public void expandShapes ()
188 expandShapes ((AccessibleTreeNode)maTree.getModel().getRoot());
190 private void expandShapes (AccessibleTreeNode aNode)
192 expandTree (aNode, new ShapeExpander());
195 /** Expand all nodes */
196 public void expandAll ()
198 expandAll ((AccessibleTreeNode)maTree.getModel().getRoot());
200 private void expandAll (AccessibleTreeNode aNode)
202 expandTree (aNode, new AllExpander());
208 public Dimension getPreferredSize ()
210 Dimension aPreferredSize = super.getPreferredSize();
211 Dimension aMinimumSize = super.getMinimumSize();
212 if (aPreferredSize.width < aMinimumSize.width)
213 aPreferredSize.width = aMinimumSize.width;
214 return aPreferredSize;
218 private class MouseListener extends MouseAdapter
220 public MouseListener (AccessibilityTree aTree)
222 maTree=aTree;
224 @Override
225 public void mousePressed(MouseEvent e) { popupTrigger(e); }
226 @Override
227 public void mouseClicked(MouseEvent e) { popupTrigger(e); }
228 @Override
229 public void mouseEntered(MouseEvent e) { popupTrigger(e); }
230 @Override
231 public void mouseExited(MouseEvent e) { popupTrigger(e); }
232 @Override
233 public void mouseReleased(MouseEvent e) { popupTrigger(e); }
235 private boolean popupTrigger( MouseEvent e )
237 boolean bIsPopup = e.isPopupTrigger();
238 if( !bIsPopup )
239 return false;
241 int selRow = maTree.getComponent().getRowForLocation(e.getX(), e.getY());
242 if (selRow == -1)
243 return bIsPopup;
245 TreePath aPath = maTree.getComponent().getPathForLocation(e.getX(), e.getY());
247 // check for actions
248 Object aObject = aPath.getLastPathComponent();
249 JPopupMenu aMenu = new JPopupMenu();
250 if( aObject instanceof AccTreeNode )
252 AccTreeNode aNode = (AccTreeNode)aObject;
254 ArrayList<String> aActions = new ArrayList<String>();
255 aMenu.add (new AccessibilityTree.ShapeExpandAction(maTree, aNode));
256 aMenu.add (new AccessibilityTree.SubtreeExpandAction(maTree, aNode));
258 aNode.getActions(aActions);
259 for( int i = 0; i < aActions.size(); i++ )
261 aMenu.add( new NodeAction(
262 aActions.get(i),
263 aNode, i ) );
266 else if (aObject instanceof AccessibleTreeNode)
268 AccessibleTreeNode aNode = (AccessibleTreeNode)aObject;
269 String[] aActionNames = aNode.getActions();
270 int nCount=aActionNames.length;
271 if (nCount > 0)
273 for (int i=0; i<nCount; i++)
274 aMenu.add( new NodeAction(
275 aActionNames[i],
276 aNode,
277 i));
279 else
280 aMenu = null;
282 if (aMenu != null)
283 aMenu.show (maTree.getComponent(),
284 e.getX(), e.getY());
286 return bIsPopup;
289 private final AccessibilityTree maTree;
292 private class NodeAction extends AbstractAction
294 private final int mnIndex;
295 private final AccessibleTreeNode maNode;
297 private NodeAction( String aName, AccessibleTreeNode aNode, int nIndex )
299 super( aName );
300 maNode = aNode;
301 mnIndex = nIndex;
304 public void actionPerformed(ActionEvent e)
306 maNode.performAction(mnIndex);
310 // This action expands all shapes in the subtree rooted in the specified node.
311 private class ShapeExpandAction extends AbstractAction
313 private final AccessibilityTree maTree;
314 private final AccTreeNode maNode;
315 public ShapeExpandAction (AccessibilityTree aTree, AccTreeNode aNode)
317 super ("Expand Shapes");
318 maTree = aTree;
319 maNode = aNode;
321 public void actionPerformed (ActionEvent e)
323 maTree.expandShapes (maNode);
327 // This action expands all nodes in the subtree rooted in the specified node.
328 private class SubtreeExpandAction extends AbstractAction
330 private final AccessibilityTree maTree;
331 private final AccTreeNode maNode;
332 public SubtreeExpandAction (AccessibilityTree aTree, AccTreeNode aNode)
334 super ("Expand Subtree");
335 maTree = aTree;
336 maNode = aNode;
338 public void actionPerformed (ActionEvent e)
340 maTree.expandAll (maNode);
344 /** Predicate class to determine whether a node should be expanded
345 * For use with expandTree method */
346 private abstract class Expander
348 abstract public boolean expand (Object aObject);
351 /** expand all nodes */
352 private class AllExpander extends Expander
354 @Override
355 public boolean expand(Object aObject) { return true; }
358 /** expand all nodes with accessibility roles > 100 */
359 private class ShapeExpander extends Expander
361 @Override
362 public boolean expand (Object aObject)
364 if (aObject instanceof AccTreeNode)
366 AccTreeNode aNode = (AccTreeNode)aObject;
367 XAccessibleContext xContext = aNode.getContext();
368 if (xContext != null)
369 if (xContext.getAccessibleRole() >= 100)
370 return true;
372 return false;
378 private final JTree maTree;
379 private int mnExpandLevel;