| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| import com.sun.star.uno.UnoRuntime; |
| import com.sun.star.accessibility.*; |
| import java.util.Vector; |
| |
| /** |
| * The node type for the AccessibleTreeModel. |
| * This implements all the child-handling based on the appropriate |
| * NodeHandlers. Trivial nodes can be implemented by any Object |
| * type. |
| */ |
| class AccTreeNode |
| extends AccessibleTreeNode |
| { |
| class HandlerDescriptor |
| { |
| public HandlerDescriptor (NodeHandler aHandler) |
| { |
| maHandler = aHandler; |
| mnChildCount = -1; |
| } |
| public NodeHandler maHandler; |
| public int mnChildCount; |
| } |
| /// NodeHandlers for this node |
| private Vector maHandlers; |
| |
| // The accessible context of this node. |
| private XAccessible mxAccessible; |
| private XAccessibleContext mxContext; |
| private XAccessibleComponent mxComponent; |
| private XAccessibleText mxText; |
| private XAccessibleTable mxTable; |
| |
| public AccTreeNode (XAccessible xAccessible, XAccessibleContext xContext, AccessibleTreeNode aParent) |
| { |
| this (xAccessible, xContext, xContext, aParent); |
| } |
| |
| public AccTreeNode (XAccessible xAccessible, XAccessibleContext xContext, Object aDisplay, AccessibleTreeNode aParent) |
| { |
| super (aDisplay, aParent); |
| |
| maHandlers = new Vector(5); |
| mxContext = xContext; |
| mxAccessible = xAccessible; |
| } |
| |
| /** Update the internal data extracted from the corresponding accessible |
| object. This is done by replacing every handler by a new one. An |
| update method at each handler would be better of course. |
| */ |
| public void update () |
| { |
| for (int i=0; i<maHandlers.size(); i++) |
| { |
| System.out.println ("replacing handler " + i); |
| HandlerDescriptor aDescriptor = (HandlerDescriptor)maHandlers.get(i); |
| aDescriptor.maHandler = aDescriptor.maHandler.createHandler (mxContext); |
| aDescriptor.mnChildCount = |
| aDescriptor.maHandler.getChildCount (this); |
| } |
| } |
| |
| public XAccessibleContext getContext () |
| { |
| return mxContext; |
| } |
| |
| public XAccessibleComponent getComponent () |
| { |
| if (mxComponent == null && mxContext != null) |
| mxComponent = (XAccessibleComponent)UnoRuntime.queryInterface( |
| XAccessibleComponent.class, mxContext); |
| return mxComponent; |
| } |
| |
| public XAccessibleExtendedComponent getExtendedComponent () |
| { |
| if (mxComponent == null) |
| getComponent(); |
| if (mxComponent != null) |
| return (XAccessibleExtendedComponent)UnoRuntime.queryInterface( |
| XAccessibleExtendedComponent.class, mxComponent); |
| else |
| return null; |
| } |
| |
| public XAccessibleText getText () |
| { |
| if (mxText == null && mxContext != null) |
| mxText = (XAccessibleText)UnoRuntime.queryInterface( |
| XAccessibleText.class, mxContext); |
| return mxText; |
| } |
| |
| public XAccessibleEditableText getEditText () |
| { |
| return (XAccessibleEditableText)UnoRuntime.queryInterface( |
| XAccessibleEditableText.class, mxContext); |
| } |
| |
| public XAccessibleTable getTable () |
| { |
| if (mxTable == null && mxContext != null) |
| mxTable = (XAccessibleTable)UnoRuntime.queryInterface( |
| XAccessibleTable.class, mxContext); |
| return mxTable; |
| } |
| |
| |
| public XAccessible getAccessible() |
| { |
| if ((mxAccessible == null) && (mxContext != null)) |
| mxAccessible = (XAccessible)UnoRuntime.queryInterface( |
| XAccessible.class, mxContext); |
| return mxAccessible; |
| } |
| |
| public XAccessibleSelection getSelection () |
| { |
| return (XAccessibleSelection)UnoRuntime.queryInterface( |
| XAccessibleSelection.class, mxContext); |
| } |
| |
| public void addHandler( NodeHandler aHandler ) |
| { |
| if (aHandler != null) |
| maHandlers.add (new HandlerDescriptor (aHandler)); |
| } |
| |
| |
| /** iterate over handlers and return child sum */ |
| protected HandlerDescriptor getHandlerDescriptor (int i) |
| { |
| HandlerDescriptor aDescriptor = (HandlerDescriptor)maHandlers.get(i); |
| if (aDescriptor.mnChildCount < 0) |
| aDescriptor.mnChildCount = |
| aDescriptor.maHandler.getChildCount (this); |
| return aDescriptor; |
| } |
| |
| public int getChildCount() |
| { |
| int nChildCount = 0; |
| for (int i = 0; i < maHandlers.size(); i++) |
| { |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| nChildCount += aDescriptor.mnChildCount; |
| } |
| return nChildCount; |
| } |
| |
| /** iterate over handlers until the child is found */ |
| public AccessibleTreeNode getChild (int nIndex) |
| throws IndexOutOfBoundsException |
| { |
| if( nIndex >= 0 ) |
| { |
| for(int i = 0; i < maHandlers.size(); i++) |
| { |
| // check if this handler has the child, and if not |
| // search with next handler |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| if (nIndex < aDescriptor.mnChildCount) |
| return aDescriptor.maHandler.getChild (this, nIndex); |
| else |
| nIndex -= aDescriptor.mnChildCount; |
| } |
| } |
| else |
| throw new IndexOutOfBoundsException(); |
| |
| // nothing found? |
| return null; |
| } |
| |
| public AccessibleTreeNode getChildNoCreate (int nIndex) |
| throws IndexOutOfBoundsException |
| { |
| if( nIndex >= 0 ) |
| { |
| for(int i = 0; i < maHandlers.size(); i++) |
| { |
| // check if this handler has the child, and if not |
| // search with next handler |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| if (nIndex < aDescriptor.mnChildCount) |
| return aDescriptor.maHandler.getChildNoCreate (this, nIndex); |
| else |
| nIndex -= aDescriptor.mnChildCount; |
| } |
| } |
| else |
| throw new IndexOutOfBoundsException(); |
| |
| // nothing found? |
| return null; |
| } |
| |
| public boolean removeChild (int nIndex) |
| throws IndexOutOfBoundsException |
| { |
| boolean bStatus = false; |
| if (nIndex >= 0) |
| { |
| for (int i=0; i<maHandlers.size(); i++) |
| { |
| // check if this handler has the child, and if not |
| // search with next handler |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| if (nIndex < aDescriptor.mnChildCount) |
| { |
| bStatus = aDescriptor.maHandler.removeChild (this, nIndex); |
| aDescriptor.mnChildCount = aDescriptor.maHandler.getChildCount (this); |
| break; |
| } |
| else |
| nIndex -= aDescriptor.mnChildCount; |
| } |
| } |
| else |
| throw new IndexOutOfBoundsException(); |
| |
| return bStatus; |
| } |
| |
| |
| public int indexOf (AccessibleTreeNode aNode) |
| { |
| int nBaseIndex = 0; |
| if (aNode != null) |
| { |
| for (int i=0; i<maHandlers.size(); i++) |
| { |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| int nIndex = aDescriptor.maHandler.indexOf (aNode); |
| if (nIndex >= 0) |
| return nBaseIndex + nIndex; |
| else |
| nBaseIndex += aDescriptor.mnChildCount; |
| } |
| } |
| |
| return -1; |
| } |
| |
| /** this node is a leaf if have no handlers, or is those |
| handlers show no children */ |
| public boolean isLeaf() |
| { |
| return (maHandlers.size() == 0);// || (getChildCount() == 0); |
| } |
| |
| public boolean equals (Object aOther) |
| { |
| return (this == aOther) || (aOther!=null && aOther.equals(mxContext)); |
| } |
| |
| |
| /** iterate over handlers until the child is found */ |
| public void getActions(Vector aActions) |
| { |
| for(int i = 0; i < maHandlers.size(); i++) |
| { |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| NodeHandler aHandler = aDescriptor.maHandler; |
| String[] aHandlerActions = aHandler.getActions (this); |
| for(int j = 0; j < aHandlerActions.length; j++ ) |
| { |
| aActions.add( aHandlerActions[j] ); |
| } |
| } |
| } |
| |
| public void performAction( int nIndex ) |
| { |
| if( nIndex >= 0 ) |
| { |
| for(int i = 0; i < maHandlers.size(); i++) |
| { |
| // check if this handler has the child, and if not |
| // search with next handler |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| NodeHandler aHandler = aDescriptor.maHandler; |
| int nCount = aHandler.getActions(this).length; |
| if( nCount > nIndex ) |
| { |
| aHandler.performAction(this, nIndex ); |
| return; |
| } |
| else |
| nIndex -= nCount; |
| } |
| } |
| } |
| |
| /** Try to add the specified accessible object as new accessible child of the |
| AccessibleTreeHandler. |
| Note that child is used in another context than |
| it is used in the other methods of this class. |
| */ |
| public AccessibleTreeNode addAccessibleChild (XAccessible xChild) |
| { |
| for(int i = 0; i < maHandlers.size(); i++) |
| { |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| if (aDescriptor.maHandler instanceof AccessibleTreeHandler) |
| { |
| AccessibleTreeHandler aHandler = (AccessibleTreeHandler)aDescriptor.maHandler; |
| AccessibleTreeNode aNode = aHandler.addAccessibleChild (this, xChild); |
| aDescriptor.mnChildCount = aHandler.getChildCount (this); |
| return aNode; |
| } |
| } |
| return null; |
| } |
| |
| /** Update the specified handlers. |
| @return |
| The returned array contains the indices of the updated children |
| and can be used to create a TreeModelEvent. |
| */ |
| public Vector updateChildren (java.lang.Class class1) |
| { |
| return updateChildren (class1, null); |
| } |
| |
| public Vector updateChildren (java.lang.Class class1, java.lang.Class class2) |
| { |
| Vector aChildIndices = new Vector(); |
| int nOffset = 0; |
| for(int i=0; i < maHandlers.size(); i++) |
| { |
| HandlerDescriptor aDescriptor = getHandlerDescriptor (i); |
| if ((class1.isInstance(aDescriptor.maHandler)) |
| || (class2 !=null && class2.isInstance(aDescriptor.maHandler))) |
| { |
| aDescriptor.maHandler.update(this); |
| // Get updated number of children. |
| int nChildCount = aDescriptor.maHandler.getChildCount (this); |
| aDescriptor.mnChildCount = nChildCount; |
| // Fill in the indices of the updated children. |
| for (int j=0; j<nChildCount; j++) |
| aChildIndices.add(new Integer(j+nOffset)); |
| } |
| nOffset += aDescriptor.mnChildCount; |
| } |
| return aChildIndices; |
| } |
| } |