git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268448 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -201,10 +201,29 @@ public class ACSFactory { | |||
| public ACSTargetElement createTarget(ACSProjectElement project) { | |||
| ACSTargetElement retval = (ACSTargetElement) project. | |||
| getOwnerDocument().createElement("target"); | |||
| indent(project, 1); | |||
| project.appendChild(retval); | |||
| return retval; | |||
| } | |||
| /** | |||
| * Insert a new line and indentation at the end of the given | |||
| * node in preparation for a new element being added. | |||
| * | |||
| * @param node Node to append indent to. | |||
| * @param level Indentation level. | |||
| */ | |||
| private void indent(ACSElement node, int level) { | |||
| StringBuffer buf = new StringBuffer("\n"); | |||
| for(int i = 0; i < level; i++) { | |||
| buf.append(" "); | |||
| } | |||
| Text text = node.getOwnerDocument().createTextNode(buf.toString()); | |||
| node.appendChild(text); | |||
| } | |||
| /** | |||
| * Test code | |||
| * | |||
| @@ -59,7 +59,7 @@ import javax.swing.event.TreeModelListener; | |||
| import javax.swing.event.TreeModelEvent; | |||
| import org.w3c.dom.Node; | |||
| import org.w3c.dom.NodeList; | |||
| import org.apache.tools.ant.gui.acs.ACSProjectElement; | |||
| import org.apache.tools.ant.gui.acs.*; | |||
| import java.util.*; | |||
| /** | |||
| @@ -90,6 +90,9 @@ public class ElementTreeModel implements TreeModel { | |||
| /** | |||
| * Gets the set of children that this tree model is interested in. | |||
| * NB: This is <b>really</b> inefficient, but may not be an issue given | |||
| * the number of times it is ultimately called. A profiler definately needs | |||
| * to be applied here. | |||
| * | |||
| * @param parent Parent to extract children from. | |||
| */ | |||
| @@ -123,7 +126,8 @@ public class ElementTreeModel implements TreeModel { | |||
| public Object getChild(Object parent, int index) { | |||
| if(parent instanceof Node) { | |||
| Node n = (Node) parent; | |||
| return getChildren(n).get(index); | |||
| List children = getChildren(n); | |||
| return children.get(index); | |||
| } | |||
| else { | |||
| return null; | |||
| @@ -194,6 +198,8 @@ public class ElementTreeModel implements TreeModel { | |||
| * @param newValue the new value from the TreeCellEditor. | |||
| */ | |||
| public void valueForPathChanged(TreePath path, Object newValue) { | |||
| // XXX What should the implementation be here? | |||
| fireNodeChanged((Node) path.getLastPathComponent()); | |||
| } | |||
| @@ -217,4 +223,90 @@ public class ElementTreeModel implements TreeModel { | |||
| _listeners.remove(l); | |||
| } | |||
| /** | |||
| * Get the list of nodes from the root to the | |||
| * given node. | |||
| * | |||
| * @param startNode Node to get path for. | |||
| */ | |||
| public Node[] getPathToRoot(Node startNode) { | |||
| return getPathToRoot(startNode, 0); | |||
| } | |||
| /** | |||
| * A recursive method for generating a list of nodes defining | |||
| * the path from the given node to the root. | |||
| * | |||
| * @param node Node to get path for. | |||
| * @param depth The number of calls taken towards the root. | |||
| */ | |||
| private Node[] getPathToRoot(Node node, int depth) { | |||
| Node[] retval = null; | |||
| depth++; | |||
| if(node == _root || node.getParentNode() == null) { | |||
| retval = new Node[depth]; | |||
| } | |||
| else { | |||
| retval = getPathToRoot(node.getParentNode(), depth); | |||
| } | |||
| retval[retval.length - depth] = node; | |||
| return retval; | |||
| } | |||
| /** | |||
| * Fire a node change event. | |||
| * | |||
| * @param node Node that changed. | |||
| */ | |||
| public void fireNodeChanged(Node node) { | |||
| TreeModelEvent event = new TreeModelEvent(this, getPathToRoot(node)); | |||
| // XXX This doen't support modifying the list during dispatch... | |||
| Iterator it = _listeners.iterator(); | |||
| while(it.hasNext()) { | |||
| TreeModelListener l = (TreeModelListener) it.next(); | |||
| l.treeNodesChanged(event); | |||
| } | |||
| } | |||
| /** | |||
| * Fire a node change event. | |||
| * | |||
| * @param node Node that changed. | |||
| */ | |||
| public void fireNodeAdded(Node node) { | |||
| Node parent = node.getParentNode(); | |||
| TreeModelEvent event = null; | |||
| if(parent == null) { | |||
| event = new TreeModelEvent(this, getPathToRoot(node)); | |||
| } | |||
| else { | |||
| Node[] path = getPathToRoot(parent); | |||
| int[] indicies = null; | |||
| Node[] children = new Node[] { node }; | |||
| // XXX Right now we assume that the node was added at the end. | |||
| // This may not be the case in the future. | |||
| if(parent.getLastChild() == node) { | |||
| List filteredChildren = getChildren(parent); | |||
| indicies = new int[] { filteredChildren.indexOf(node) }; | |||
| } | |||
| else { | |||
| throw new UnsupportedOperationException( | |||
| "Haven't implemented non-append notification yet."); | |||
| } | |||
| event = new TreeModelEvent(this, path, indicies, children); | |||
| } | |||
| // XXX This doen't support modifying the list during dispatch... | |||
| Iterator it = _listeners.iterator(); | |||
| while(it.hasNext()) { | |||
| TreeModelListener l = (TreeModelListener) it.next(); | |||
| l.treeNodesInserted(event); | |||
| } | |||
| } | |||
| } | |||
| @@ -53,7 +53,7 @@ | |||
| */ | |||
| package org.apache.tools.ant.gui.command; | |||
| import org.apache.tools.ant.gui.core.AppContext; | |||
| import org.apache.tools.ant.gui.event.TargetSelectionEvent; | |||
| import org.apache.tools.ant.gui.event.NewTargetEvent; | |||
| import org.apache.tools.ant.gui.acs.*; | |||
| /** | |||
| @@ -88,8 +88,7 @@ public class NewTargetCmd extends AbstractCommand { | |||
| retval.setName(getContext().getResources(). | |||
| getString(getClass(), "defName") + " " + _count++); | |||
| getContext().getEventBus().postEvent( | |||
| new TargetSelectionEvent( | |||
| getContext(), new ACSElement[] { retval })); | |||
| new NewTargetEvent(getContext(), retval)); | |||
| } | |||
| } | |||
| @@ -232,7 +232,8 @@ public class ActionManager { | |||
| for(int i = 0; i < actionIDs.length; i++) { | |||
| AntAction action = (AntAction) _actions.get(actionIDs[i]); | |||
| if(action != null) { | |||
| retval.add(action); | |||
| AbstractButton button = retval.add(action); | |||
| addNiceStuff(button, action); | |||
| } | |||
| } | |||
| @@ -160,6 +160,15 @@ public class AppContext { | |||
| return _selectionManager; | |||
| } | |||
| /** | |||
| * Determine if debug mode is turned on. | |||
| * | |||
| * @return True if in debug mode, false otherwise. | |||
| */ | |||
| public boolean isDebugOn() { | |||
| return _resources.getBoolean("debug"); | |||
| } | |||
| } | |||
| @@ -0,0 +1,70 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2001 The Apache Software Foundation. All rights | |||
| * reserved. | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * 1. Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * 2. Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in | |||
| * the documentation and/or other materials provided with the | |||
| * distribution. | |||
| * | |||
| * 3. The end-user documentation included with the redistribution, if | |||
| * any, must include the following acknowlegement: | |||
| * "This product includes software developed by the | |||
| * Apache Software Foundation (http://www.apache.org/)." | |||
| * Alternately, this acknowlegement may appear in the software itself, | |||
| * if and wherever such third-party acknowlegements normally appear. | |||
| * | |||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||
| * Foundation" must not be used to endorse or promote products derived | |||
| * from this software without prior written permission. For written | |||
| * permission, please contact apache@apache.org. | |||
| * | |||
| * 5. Products derived from this software may not be called "Apache" | |||
| * nor may "Apache" appear in their names without prior written | |||
| * permission of the Apache Group. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | |||
| * ==================================================================== | |||
| * | |||
| * This software consists of voluntary contributions made by many | |||
| * individuals on behalf of the Apache Software Foundation. For more | |||
| * information on the Apache Software Foundation, please see | |||
| * <http://www.apache.org/>. | |||
| */ | |||
| package org.apache.tools.ant.gui.event; | |||
| import org.apache.tools.ant.gui.acs.ACSElement; | |||
| /** | |||
| * Tag interface for indicating that an event is related to creating new | |||
| * build definition elements. | |||
| * | |||
| * @version $Revision$ | |||
| * @author Simeon Fitch | |||
| */ | |||
| public interface NewElementEvent { | |||
| /** | |||
| * Get the element that has been added. | |||
| * | |||
| * @return New element. | |||
| */ | |||
| ACSElement getNewElement(); | |||
| } | |||
| @@ -67,7 +67,8 @@ import org.apache.tools.ant.gui.acs.ACSElement; | |||
| * @version $Revision$ | |||
| * @author Simeon Fitch | |||
| */ | |||
| public class NewProjectEvent extends ProjectSelectedEvent { | |||
| public class NewProjectEvent extends ProjectSelectedEvent | |||
| implements NewElementEvent { | |||
| /** | |||
| * Standard ctor. | |||
| @@ -77,5 +78,18 @@ public class NewProjectEvent extends ProjectSelectedEvent { | |||
| public NewProjectEvent( | |||
| AppContext context, ACSProjectElement project) { | |||
| super(context, project); | |||
| if(project == null) { | |||
| throw new IllegalArgumentException("A new project can't be null."); | |||
| } | |||
| } | |||
| /** | |||
| * Get the newly added project. | |||
| * | |||
| * @return New project. | |||
| */ | |||
| public ACSElement getNewElement() { | |||
| return getSelectedProject(); | |||
| } | |||
| } | |||
| @@ -0,0 +1,90 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights | |||
| * reserved. | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * 1. Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * 2. Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in | |||
| * the documentation and/or other materials provided with the | |||
| * distribution. | |||
| * | |||
| * 3. The end-user documentation included with the redistribution, if | |||
| * any, must include the following acknowlegement: | |||
| * "This product includes software developed by the | |||
| * Apache Software Foundation (http://www.apache.org/)." | |||
| * Alternately, this acknowlegement may appear in the software itself, | |||
| * if and wherever such third-party acknowlegements normally appear. | |||
| * | |||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||
| * Foundation" must not be used to endorse or promote products derived | |||
| * from this software without prior written permission. For written | |||
| * permission, please contact apache@apache.org. | |||
| * | |||
| * 5. Products derived from this software may not be called "Apache" | |||
| * nor may "Apache" appear in their names without prior written | |||
| * permission of the Apache Group. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | |||
| * ==================================================================== | |||
| * | |||
| * This software consists of voluntary contributions made by many | |||
| * individuals on behalf of the Apache Software Foundation. For more | |||
| * information on the Apache Software Foundation, please see | |||
| * <http://www.apache.org/>. | |||
| */ | |||
| package org.apache.tools.ant.gui.event; | |||
| import org.apache.tools.ant.gui.acs.ACSElement; | |||
| import org.apache.tools.ant.gui.acs.ACSTargetElement; | |||
| import org.apache.tools.ant.gui.core.AppContext; | |||
| /** | |||
| * Event fired when a new target is created. | |||
| * | |||
| * @version $Revision$ | |||
| * @author Simeon Fitch | |||
| */ | |||
| public class NewTargetEvent extends TargetSelectionEvent | |||
| implements NewElementEvent { | |||
| /** | |||
| * Standard ctor. | |||
| * | |||
| * @param context application context. | |||
| * @param target the new target. | |||
| */ | |||
| public NewTargetEvent(AppContext context, | |||
| ACSTargetElement target) { | |||
| super(context, new ACSElement[] { target }); | |||
| if(target == null) { | |||
| throw new IllegalArgumentException("A new target can't be null."); | |||
| } | |||
| } | |||
| /** | |||
| * Get the newly added target. | |||
| * | |||
| * @return New target. | |||
| */ | |||
| public ACSElement getNewElement() { | |||
| return getSelectedTargets()[0]; | |||
| } | |||
| } | |||
| @@ -54,13 +54,10 @@ | |||
| package org.apache.tools.ant.gui.modules.edit; | |||
| import org.apache.tools.ant.gui.core.*; | |||
| import org.apache.tools.ant.gui.event.*; | |||
| import org.apache.tools.ant.gui.acs.ElementTreeSelectionModel; | |||
| import org.apache.tools.ant.gui.acs.ElementTreeModel; | |||
| import org.apache.tools.ant.gui.acs.ACSProjectElement; | |||
| import org.apache.tools.ant.gui.acs.*; | |||
| import javax.swing.*; | |||
| import javax.swing.tree.*; | |||
| import javax.swing.event.TreeSelectionListener; | |||
| import javax.swing.event.TreeSelectionEvent; | |||
| import javax.swing.event.*; | |||
| import java.awt.GridLayout; | |||
| import java.awt.Dimension; | |||
| import java.awt.event.MouseAdapter; | |||
| @@ -104,10 +101,11 @@ public class ElementNavigator extends AntModule { | |||
| _tree.setCellRenderer(new ElementTreeCellRenderer()); | |||
| _tree.addMouseListener(new PopupHandler()); | |||
| _tree.putClientProperty("JTree.lineStyle", "Angled"); | |||
| _tree.setShowsRootHandles(true); | |||
| JScrollPane scroller = new JScrollPane(_tree); | |||
| add(scroller); | |||
| setPreferredSize(new Dimension(200, 100)); | |||
| setPreferredSize(new Dimension(250, 100)); | |||
| setMinimumSize(new Dimension(200, 100)); | |||
| } | |||
| @@ -134,12 +132,18 @@ public class ElementNavigator extends AntModule { | |||
| * it should be cancelled. | |||
| */ | |||
| public boolean eventPosted(EventObject event) { | |||
| ElementTreeModel model = (ElementTreeModel)_tree.getModel(); | |||
| // XXX This crap needs cleaning up. Type switching is lazy... | |||
| if(event instanceof PropertyChangeEvent) { | |||
| // The project node has changed. | |||
| // XXX This won't work until ACSTreeNodeElement.getParent() is fixed | |||
| // ElementTreeModel model = (ElementTreeModel)_tree.getModel(); | |||
| // model.nodeChanged((TreeNode)model.getRoot()); | |||
| model.fireNodeChanged((ACSElement)event.getSource()); | |||
| } | |||
| else if(event instanceof NewElementEvent && model != null) { | |||
| ACSElement element = ((NewElementEvent)event).getNewElement(); | |||
| model.fireNodeAdded(element); | |||
| TreePath path = new TreePath(model.getPathToRoot(element)); | |||
| _selections.setSelectionPath(path); | |||
| _tree.scrollPathToVisible(path); | |||
| } | |||
| else { | |||
| ACSProjectElement project = null; | |||
| @@ -190,6 +194,7 @@ public class ElementNavigator extends AntModule { | |||
| public boolean accept(EventObject event) { | |||
| return event instanceof ProjectSelectedEvent || | |||
| event instanceof ProjectClosedEvent || | |||
| event instanceof NewElementEvent || | |||
| event instanceof PropertyChangeEvent; | |||
| } | |||
| } | |||