diff --git a/src/antidote/TODO b/src/antidote/TODO new file mode 100644 index 000000000..09b368815 --- /dev/null +++ b/src/antidote/TODO @@ -0,0 +1,36 @@ +TODO List: + * Need Ant API access to: + - Tasks within a Target + - The topo sorted task list to get flattened dependencies + - The build setup code to recduce code replication. + - Normalize the Ant data model to represent a more consistent + tree structure, and more bean-like API. + + * Cause console to clear when a project is closed. + + * Better define the data model architecture, and how it interfaces + with the Ant data model. + + * Define a list of proposed changes for the Ant datamodel, + specifically the Project class and the ability to stop running builds, + and reduction of code duplication in launching builds. + + * Project navigator (currently stubbed out in the ProjectNavigator class). + + * Implement a ListSelectionModel that is backed by a set of selected + targets. + + * Project properties viewer, including the ability to view + dependencies (local and cascading). + + * Acquire or implement a logging facility. + + * Build launching capability. + + * Build monitoring console. + + * Get some icons! + + * Create a listener for the ActionManager that knows how to change + the enanbled state of the various actions based on the + application state. diff --git a/src/antidote/docs/gui-requirements.html b/src/antidote/docs/gui-requirements.html index e9d9a085d..a6e7d663b 100644 --- a/src/antidote/docs/gui-requirements.html +++ b/src/antidote/docs/gui-requirements.html @@ -5,7 +5,7 @@

Ant GUI Feature List

-

Version 0.3 (2000/10/31)

+

Version 0.4 (2000/11/06)

Authors: Simeon H.K. Fitch, Chris Todd, @@ -31,7 +31,6 @@

The features are in a loose order of expressed interested by contributors.

-
    @@ -68,7 +67,6 @@

-
  • Build Wizard (auto-configure)

  • To make starting a new project with Ant as easy as possible, the a wizard type of UI can be used where the user provides some basic @@ -155,7 +153,9 @@ introspection to discover attribute set, then reference some other mechanism for attributes that are manifested as properties. -

  • Report errors in the XML source.
  • +
  • Report errors in the XML source.
  • +
  • Provide a list of recently opened documents for + quick reloading.
  • View project contents.
    1. diff --git a/src/antidote/org/apache/tools/ant/gui/Console.java b/src/antidote/org/apache/tools/ant/gui/Console.java index 7dbcff2cf..87bc8da98 100644 --- a/src/antidote/org/apache/tools/ant/gui/Console.java +++ b/src/antidote/org/apache/tools/ant/gui/Console.java @@ -54,6 +54,7 @@ package org.apache.tools.ant.gui; import org.apache.tools.ant.gui.event.*; import javax.swing.*; +import javax.swing.plaf.ComponentUI; import javax.swing.text.Document; import java.awt.BorderLayout; import java.awt.FlowLayout; @@ -82,7 +83,7 @@ public class Console extends AntEditor { context.getEventBus().addMember(EventBus.MONITORING, new Handler()); setLayout(new BorderLayout()); - _text = new JTextPane(); + _text = new NoWrapTextPane(); _text.setEditable(false); JScrollPane scroller = new JScrollPane(_text); scroller.setVerticalScrollBarPolicy( @@ -162,7 +163,6 @@ public class Console extends AntEditor { } } } - /** Class providing filtering for project events. */ private static class Filter implements BusFilter { /** @@ -176,4 +176,20 @@ public class Console extends AntEditor { } } + /** Specialization of JTextPane to provide proper wrapping behavior. */ + private static class NoWrapTextPane extends JTextPane { + /** + * Overridden to ensure that the JTextPane is only + * forced to match the viewport if it is smaller than + * the viewport. + * + * @return True if smaller than viewport, false otherwise. + */ + public boolean getScrollableTracksViewportWidth() { + ComponentUI ui = getUI(); + return getParent() != null ? ui.getPreferredSize(this).width <= + getParent().getSize().width : true; + } + } + } diff --git a/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java b/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java index 523a2c5d1..9a634c9f6 100644 --- a/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java +++ b/src/antidote/org/apache/tools/ant/gui/ProjectNavigator.java @@ -116,9 +116,11 @@ class ProjectNavigator extends AntEditor { // XXX this needs to be tested against // different version of Swing... _tree.setModel(null); + _tree.setSelectionModel(null); } else { _tree.setModel(project.getTreeModel()); + _tree.setSelectionModel(project.getTreeSelectionModel()); } } } diff --git a/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java b/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java index b2496fee5..44fd77e9b 100644 --- a/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java +++ b/src/antidote/org/apache/tools/ant/gui/ProjectProxy.java @@ -52,17 +52,17 @@ * . */ package org.apache.tools.ant.gui; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.ProjectHelper; -import org.apache.tools.ant.BuildEvent; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.*; import org.apache.tools.ant.gui.event.*; import java.io.File; import java.io.IOException; import javax.swing.tree.TreeModel; import javax.swing.text.Document; +import javax.swing.tree.TreeSelectionModel; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; import java.util.Enumeration; +import java.util.Vector; /** * This class provides the gateway interface to the data model for @@ -81,8 +81,10 @@ public class ProjectProxy { private File _file = null; /** The real Ant Project instance. */ private Project _project = null; - /** Private the current thread executing a build. */ + /** The current thread executing a build. */ private Thread _buildThread = null; + /** The selection model for selected targets. */ + private TargetSelectionModel _selections = null; /** * File loading ctor. @@ -101,6 +103,8 @@ public class ProjectProxy { */ private void loadProject() throws IOException { _project = new Project(); + _selections = new TargetSelectionModel(); + _selections.addTreeSelectionListener(new SelectionForwarder()); synchronized(_project) { _project.init(); @@ -117,6 +121,15 @@ public class ProjectProxy { } } + /** + * Called to indicate that the project is no longer going to be used + * by the GUI, and that any cleanup should occur. + * + */ + //public void close() { + // + //} + /** * Build the project with the current target (or the default target * if none is selected. Build occurs on a separate thread, so method @@ -152,6 +165,15 @@ public class ProjectProxy { return null; } + /** + * Get the tree selection model for selected targets. + * + * @return Selection model. + */ + public TreeSelectionModel getTreeSelectionModel() { + return _selections; + } + /** * Get the Document perspective on the data. * @@ -197,10 +219,23 @@ public class ProjectProxy { try { fireBuildEvent(new BuildEvent( _project), BuildEventType.BUILD_STARTED); - // XXX add code to indicate target execution - // on the targets that are selected. - _project.executeTarget( - _project.getDefaultTarget()); + + // Generate list of targets to execute. + Target[] targets = _selections.getSelectedTargets(); + Vector targetNames = new Vector(); + if(targets.length == 0) { + targetNames.add(_project.getDefaultTarget()); + } + else { + for(int i = 0; i < targets.length; i++) { + targetNames.add(targets[i].getName()); + } + } + + // Execute build on selected targets. XXX It would be + // nice if the Project API supported passing in target + // objects rather than String names. + _project.executeTargets(targetNames); } catch(BuildException ex) { BuildEvent errorEvent = new BuildEvent(_project); @@ -218,4 +253,12 @@ public class ProjectProxy { } } + /** Forwards selection events to the event bus. */ + private class SelectionForwarder implements TreeSelectionListener { + public void valueChanged(TreeSelectionEvent e) { + _context.getEventBus().postEvent(new TargetSelectionEvent( + _context, _selections.getSelectedTargets())); + } + } + } diff --git a/src/antidote/org/apache/tools/ant/gui/PropertyEditor.java b/src/antidote/org/apache/tools/ant/gui/PropertyEditor.java index 4b5069064..ffffc8955 100644 --- a/src/antidote/org/apache/tools/ant/gui/PropertyEditor.java +++ b/src/antidote/org/apache/tools/ant/gui/PropertyEditor.java @@ -52,7 +52,13 @@ * . */ package org.apache.tools.ant.gui; +import org.apache.tools.ant.Target; +import org.apache.tools.ant.gui.event.*; import javax.swing.*; +import java.util.*; +import java.io.StringReader; +import java.io.IOException; +import java.awt.BorderLayout; /** * Stub for a property editor. @@ -62,8 +68,162 @@ import javax.swing.*; */ class PropertyEditor extends AntEditor { + /** Text pane. */ + private JEditorPane _text = null; + + /** + * Standard ctor. + * + * @param context Application context. + */ public PropertyEditor(AppContext context) { super(context); - add(new JLabel(getName())); + context.getEventBus().addMember(EventBus.MONITORING, new Handler()); + setLayout(new BorderLayout()); + + _text = new JEditorPane("text/html", getAppContext().getResources(). + getString(getClass(), "noTargets")); + _text.setEditable(false); + _text.setOpaque(false); + + add(BorderLayout.CENTER, _text); } + + /** + * Populate the display with the given target info. + * + * @param targets Targets to display info for. + */ + private void displayTargetInfo(Target[] targets) { + + // The text to display. + String text = null; + + int num = targets == null ? 0 : targets.length; + Object[] args = null; + switch(num) { + case 0: + text = getAppContext().getResources(). + getString(getClass(), "noTargets"); + break; + case 1: + args = getTargetParams(targets[0]); + text = getAppContext().getResources(). + getMessage(getClass(), "oneTarget", args); + break; + default: + args = getTargetParams(targets); + text = getAppContext().getResources(). + getMessage(getClass(), "manyTargets", args); + break; + } + + if(text != null) { + _text.setText(text); + } + } + + /** + * Get the parameters for the formatted message presented for a single + * target. + * + * @param target Target to generate params for. + * @return Argument list for the formatted message. + */ + private Object[] getTargetParams(Target target) { + List args = new LinkedList(); + args.add(target.getName()); + args.add(target.getDescription() == null ? + "" : target.getDescription()); + StringBuffer buf = new StringBuffer(); + Enumeration enum = target.getDependencies(); + while(enum.hasMoreElements()) { + buf.append(enum.nextElement()); + if(enum.hasMoreElements()) { + buf.append(", "); + } + } + args.add(buf.toString()); + + return args.toArray(); + } + + /** + * Get the parameters for the formatted message presented for multiple + * targets. + * + * @param target Targets to generate params for. + * @return Argument list for the formatted message. + */ + private Object[] getTargetParams(Target[] targets) { + List args = new LinkedList(); + + StringBuffer buf = new StringBuffer(); + Set depends = new HashSet(); + for(int i = 0; i < targets.length; i++) { + buf.append(targets[i].getName()); + if(i < targets.length - 1) { + buf.append(", "); + } + + Enumeration enum = targets[i].getDependencies(); + while(enum.hasMoreElements()) { + depends.add(enum.nextElement()); + } + } + + args.add(buf.toString()); + + Iterator it = depends.iterator(); + buf = new StringBuffer(); + while(it.hasNext()) { + buf.append(it.next()); + if(it.hasNext()) { + buf.append(", "); + } + } + + args.add(buf.toString()); + + return args.toArray(); + } + + /** Class for handling project events. */ + private class Handler implements BusMember { + private final Filter _filter = new Filter(); + + /** + * Get the filter to that is used to determine if an event should + * to to the member. + * + * @return Filter to use. + */ + public BusFilter getBusFilter() { + return _filter; + } + + /** + * Called when an event is to be posted to the member. + * + * @param event Event to post. + */ + public void eventPosted(EventObject event) { + TargetSelectionEvent e = (TargetSelectionEvent) event; + Target[] targets = e.getSelectedTargets(); + displayTargetInfo(targets); + } + + } + /** Class providing filtering for project events. */ + private static class Filter implements BusFilter { + /** + * Determines if the given event should be accepted. + * + * @param event Event to test. + * @return True if event should be given to BusMember, false otherwise. + */ + public boolean accept(EventObject event) { + return event instanceof TargetSelectionEvent; + } + } } diff --git a/src/antidote/org/apache/tools/ant/gui/TargetSelectionModel.java b/src/antidote/org/apache/tools/ant/gui/TargetSelectionModel.java new file mode 100644 index 000000000..1ccf9d998 --- /dev/null +++ b/src/antidote/org/apache/tools/ant/gui/TargetSelectionModel.java @@ -0,0 +1,96 @@ +/* + * 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", "Tomcat", 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 + * . + */ +package org.apache.tools.ant.gui; +import org.apache.tools.ant.Target; + +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreePath; +import java.util.*; + +/** + * Selection model for the currently selected targets. + * + * @version $Revision$ + * @author Simeon Fitch + */ +class TargetSelectionModel extends DefaultTreeSelectionModel { + /** + * Default ctor. + * + */ + public TargetSelectionModel() { + setSelectionMode(DISCONTIGUOUS_TREE_SELECTION); + } + + /** + * Convenience method for providing the set of currently selected + * targets. + * + * @return the currently selected targets. + */ + public Target[] getSelectedTargets() { + TreePath[] path = getSelectionPaths(); + List values = new LinkedList(); + for(int i = 0; path != null && i < path.length; i++) { + Object val = path[i].getLastPathComponent(); + if(val instanceof Target) { + values.add(val); + } + } + + Target[] retval = new Target[values.size()]; + values.toArray(retval); + return retval; + } +} diff --git a/src/antidote/org/apache/tools/ant/gui/event/TargetSelectionEvent.java b/src/antidote/org/apache/tools/ant/gui/event/TargetSelectionEvent.java new file mode 100644 index 000000000..3256ceaf0 --- /dev/null +++ b/src/antidote/org/apache/tools/ant/gui/event/TargetSelectionEvent.java @@ -0,0 +1,98 @@ +/* + * 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", "Tomcat", 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 + * . + */ +package org.apache.tools.ant.gui.event; +import org.apache.tools.ant.Target; +import org.apache.tools.ant.gui.command.Command; +import org.apache.tools.ant.gui.command.NoOpCmd; +import org.apache.tools.ant.gui.AppContext; + +/** + * Event indicating that the current set of selected targets has changed. + * + * @version $Revision$ + * @author Simeon Fitch + */ +public class TargetSelectionEvent extends AntEvent { + + /** New set of selected targets. */ + private Target[] _selectedTargets = null; + + /** + * Standard ctor. + * + * @param context application context. + */ + public TargetSelectionEvent(AppContext context, Target[] selectedTargets) { + super(context); + _selectedTargets = selectedTargets; + } + + /** + * Current set of selected targets. + * + * @return selected target set. + */ + public Target[] getSelectedTargets() { + return _selectedTargets; + } + + /** + * Create the appropriate default response command to this event. + * + * @return Command representing an appropriate response to this event. + */ + public Command createDefaultCmd() { + return new NoOpCmd(); + } +} diff --git a/src/antidote/org/apache/tools/ant/gui/resources/action.properties b/src/antidote/org/apache/tools/ant/gui/resources/action.properties index bcf1c8617..1d659f9de 100644 --- a/src/antidote/org/apache/tools/ant/gui/resources/action.properties +++ b/src/antidote/org/apache/tools/ant/gui/resources/action.properties @@ -1,6 +1,6 @@ menus=File, Build, Help -actions=open, close, exit, about, startBuild, stopBuild +actions=open, close, exit, about, startBuild new.name=New new.shortDescription=Create a new project diff --git a/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties b/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties index 8b6119161..5dc235703 100644 --- a/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties +++ b/src/antidote/org/apache/tools/ant/gui/resources/antidote.properties @@ -15,7 +15,22 @@ org.apache.tools.ant.gui.Antidote.bottom.editors=\ # Set specific class properties. org.apache.tools.ant.gui.SourceEditor.name=Source -org.apache.tools.ant.gui.PropertyEditor.name=Properties + +org.apache.tools.ant.gui.PropertyEditor.name=Target Info +org.apache.tools.ant.gui.PropertyEditor.noTargets=No targets selected. +org.apache.tools.ant.gui.PropertyEditor.oneTarget=\ +\ +\ +\ +\ +
      Name:{0}
      Description:{1}
      Depends:{2}
      + +org.apache.tools.ant.gui.PropertyEditor.manyTargets=\ +\ +\ +\ +
      Names:{0}
      Depends:{1}
      + org.apache.tools.ant.gui.ProjectNavigator.name=Project org.apache.tools.ant.gui.Console.name=Console org.apache.tools.ant.gui.Console.logLevel=Log message level: