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) { | public ACSTargetElement createTarget(ACSProjectElement project) { | ||||
ACSTargetElement retval = (ACSTargetElement) project. | ACSTargetElement retval = (ACSTargetElement) project. | ||||
getOwnerDocument().createElement("target"); | getOwnerDocument().createElement("target"); | ||||
indent(project, 1); | |||||
project.appendChild(retval); | project.appendChild(retval); | ||||
return 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 | * Test code | ||||
* | * | ||||
@@ -59,7 +59,7 @@ import javax.swing.event.TreeModelListener; | |||||
import javax.swing.event.TreeModelEvent; | import javax.swing.event.TreeModelEvent; | ||||
import org.w3c.dom.Node; | import org.w3c.dom.Node; | ||||
import org.w3c.dom.NodeList; | import org.w3c.dom.NodeList; | ||||
import org.apache.tools.ant.gui.acs.ACSProjectElement; | |||||
import org.apache.tools.ant.gui.acs.*; | |||||
import java.util.*; | import java.util.*; | ||||
/** | /** | ||||
@@ -90,6 +90,9 @@ public class ElementTreeModel implements TreeModel { | |||||
/** | /** | ||||
* Gets the set of children that this tree model is interested in. | * 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. | * @param parent Parent to extract children from. | ||||
*/ | */ | ||||
@@ -123,7 +126,8 @@ public class ElementTreeModel implements TreeModel { | |||||
public Object getChild(Object parent, int index) { | public Object getChild(Object parent, int index) { | ||||
if(parent instanceof Node) { | if(parent instanceof Node) { | ||||
Node n = (Node) parent; | Node n = (Node) parent; | ||||
return getChildren(n).get(index); | |||||
List children = getChildren(n); | |||||
return children.get(index); | |||||
} | } | ||||
else { | else { | ||||
return null; | return null; | ||||
@@ -194,6 +198,8 @@ public class ElementTreeModel implements TreeModel { | |||||
* @param newValue the new value from the TreeCellEditor. | * @param newValue the new value from the TreeCellEditor. | ||||
*/ | */ | ||||
public void valueForPathChanged(TreePath path, Object newValue) { | 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); | _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; | package org.apache.tools.ant.gui.command; | ||||
import org.apache.tools.ant.gui.core.AppContext; | 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.*; | import org.apache.tools.ant.gui.acs.*; | ||||
/** | /** | ||||
@@ -88,8 +88,7 @@ public class NewTargetCmd extends AbstractCommand { | |||||
retval.setName(getContext().getResources(). | retval.setName(getContext().getResources(). | ||||
getString(getClass(), "defName") + " " + _count++); | getString(getClass(), "defName") + " " + _count++); | ||||
getContext().getEventBus().postEvent( | 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++) { | for(int i = 0; i < actionIDs.length; i++) { | ||||
AntAction action = (AntAction) _actions.get(actionIDs[i]); | AntAction action = (AntAction) _actions.get(actionIDs[i]); | ||||
if(action != null) { | if(action != null) { | ||||
retval.add(action); | |||||
AbstractButton button = retval.add(action); | |||||
addNiceStuff(button, action); | |||||
} | } | ||||
} | } | ||||
@@ -160,6 +160,15 @@ public class AppContext { | |||||
return _selectionManager; | 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$ | * @version $Revision$ | ||||
* @author Simeon Fitch | * @author Simeon Fitch | ||||
*/ | */ | ||||
public class NewProjectEvent extends ProjectSelectedEvent { | |||||
public class NewProjectEvent extends ProjectSelectedEvent | |||||
implements NewElementEvent { | |||||
/** | /** | ||||
* Standard ctor. | * Standard ctor. | ||||
@@ -77,5 +78,18 @@ public class NewProjectEvent extends ProjectSelectedEvent { | |||||
public NewProjectEvent( | public NewProjectEvent( | ||||
AppContext context, ACSProjectElement project) { | AppContext context, ACSProjectElement project) { | ||||
super(context, 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; | package org.apache.tools.ant.gui.modules.edit; | ||||
import org.apache.tools.ant.gui.core.*; | import org.apache.tools.ant.gui.core.*; | ||||
import org.apache.tools.ant.gui.event.*; | 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.*; | ||||
import javax.swing.tree.*; | 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.GridLayout; | ||||
import java.awt.Dimension; | import java.awt.Dimension; | ||||
import java.awt.event.MouseAdapter; | import java.awt.event.MouseAdapter; | ||||
@@ -104,10 +101,11 @@ public class ElementNavigator extends AntModule { | |||||
_tree.setCellRenderer(new ElementTreeCellRenderer()); | _tree.setCellRenderer(new ElementTreeCellRenderer()); | ||||
_tree.addMouseListener(new PopupHandler()); | _tree.addMouseListener(new PopupHandler()); | ||||
_tree.putClientProperty("JTree.lineStyle", "Angled"); | _tree.putClientProperty("JTree.lineStyle", "Angled"); | ||||
_tree.setShowsRootHandles(true); | |||||
JScrollPane scroller = new JScrollPane(_tree); | JScrollPane scroller = new JScrollPane(_tree); | ||||
add(scroller); | add(scroller); | ||||
setPreferredSize(new Dimension(200, 100)); | |||||
setPreferredSize(new Dimension(250, 100)); | |||||
setMinimumSize(new Dimension(200, 100)); | setMinimumSize(new Dimension(200, 100)); | ||||
} | } | ||||
@@ -134,12 +132,18 @@ public class ElementNavigator extends AntModule { | |||||
* it should be cancelled. | * it should be cancelled. | ||||
*/ | */ | ||||
public boolean eventPosted(EventObject event) { | public boolean eventPosted(EventObject event) { | ||||
ElementTreeModel model = (ElementTreeModel)_tree.getModel(); | |||||
// XXX This crap needs cleaning up. Type switching is lazy... | |||||
if(event instanceof PropertyChangeEvent) { | if(event instanceof PropertyChangeEvent) { | ||||
// The project node has changed. | // 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 { | else { | ||||
ACSProjectElement project = null; | ACSProjectElement project = null; | ||||
@@ -190,6 +194,7 @@ public class ElementNavigator extends AntModule { | |||||
public boolean accept(EventObject event) { | public boolean accept(EventObject event) { | ||||
return event instanceof ProjectSelectedEvent || | return event instanceof ProjectSelectedEvent || | ||||
event instanceof ProjectClosedEvent || | event instanceof ProjectClosedEvent || | ||||
event instanceof NewElementEvent || | |||||
event instanceof PropertyChangeEvent; | event instanceof PropertyChangeEvent; | ||||
} | } | ||||
} | } | ||||