From 1056b715f84a4c3b17b7fcdecbaef6eaeb566ea7 Mon Sep 17 00:00:00 2001 From: metasim Date: Mon, 8 Jan 2001 19:44:01 +0000 Subject: [PATCH] Added *internal* support multiple projects, and generalized the selection state mechanism. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268419 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/tools/ant/gui/Antidote.java | 2 +- .../org/apache/tools/ant/gui/Main.java | 2 +- .../tools/ant/gui/acs/ACSProjectElement.java | 17 +- .../gui/acs/ElementTreeSelectionModel.java | 30 +-- .../tools/ant/gui/command/BuildCmd.java | 39 ++- .../tools/ant/gui/command/CloseCmd.java | 33 ++- .../tools/ant/gui/command/EmacsNotifyCmd.java | 7 +- .../tools/ant/gui/command/LoadFileCmd.java | 9 +- .../tools/ant/gui/command/SaveAsCmd.java | 81 +++--- .../apache/tools/ant/gui/command/SaveCmd.java | 7 +- .../apache/tools/ant/gui/core/AppContext.java | 112 +++------ .../tools/ant/gui/core/ProjectManager.java | 235 +++++++++++++++++- .../tools/ant/gui/core/SelectionManager.java | 147 +++++++++++ .../ant/gui/event/ElementSelectionEvent.java | 29 ++- .../apache/tools/ant/gui/event/EventBus.java | 8 +- .../tools/ant/gui/event/NewProjectEvent.java | 73 ------ ...onEvent.java => ProjectSelectedEvent.java} | 28 ++- .../ant/gui/event/PropertySelectionEvent.java | 10 + .../ant/gui/event/TargetSelectionEvent.java | 12 +- .../ant/gui/event/TaskSelectionEvent.java | 10 + .../tools/ant/gui/modules/TargetMonitor.java | 22 +- .../ant/gui/modules/console/BuildConsole.java | 4 +- .../gui/modules/edit/ElementNavigator.java | 36 ++- .../ant/gui/modules/edit/PropertyEditor.java | 12 +- .../tools/ant/gui/resources/action.properties | 12 +- 25 files changed, 710 insertions(+), 267 deletions(-) create mode 100644 src/antidote/org/apache/tools/ant/gui/core/SelectionManager.java delete mode 100644 src/antidote/org/apache/tools/ant/gui/event/NewProjectEvent.java rename src/antidote/org/apache/tools/ant/gui/event/{ProjectSelectionEvent.java => ProjectSelectedEvent.java} (80%) diff --git a/src/antidote/org/apache/tools/ant/gui/Antidote.java b/src/antidote/org/apache/tools/ant/gui/Antidote.java index f15e0f547..bea955153 100644 --- a/src/antidote/org/apache/tools/ant/gui/Antidote.java +++ b/src/antidote/org/apache/tools/ant/gui/Antidote.java @@ -100,7 +100,7 @@ public class Antidote extends JPanel { add(BorderLayout.NORTH, populateModules("top")); - setPreferredSize(new Dimension(640, 600)); + setPreferredSize(new Dimension(640, 480)); } diff --git a/src/antidote/org/apache/tools/ant/gui/Main.java b/src/antidote/org/apache/tools/ant/gui/Main.java index 3499b2a22..aedb960ae 100644 --- a/src/antidote/org/apache/tools/ant/gui/Main.java +++ b/src/antidote/org/apache/tools/ant/gui/Main.java @@ -87,7 +87,7 @@ public class Main { context.getActions().createToolBar()); ImageIcon icon = - context.getResources().getImageIcon("icon-small.gif"); + context.getResources().loadImageIcon("icon-small.gif"); if(icon != null) { f.setIconImage(icon.getImage()); } diff --git a/src/antidote/org/apache/tools/ant/gui/acs/ACSProjectElement.java b/src/antidote/org/apache/tools/ant/gui/acs/ACSProjectElement.java index ee8380ec8..02743ab5f 100644 --- a/src/antidote/org/apache/tools/ant/gui/acs/ACSProjectElement.java +++ b/src/antidote/org/apache/tools/ant/gui/acs/ACSProjectElement.java @@ -55,6 +55,7 @@ package org.apache.tools.ant.gui.acs; import com.sun.xml.tree.ElementNode; import java.net.URL; +import java.io.File; /** * Class representing a project element in the build file. @@ -148,5 +149,19 @@ public class ACSProjectElement extends ACSNamedElement { firePropertyChange(LOCATION, old, _location); } - + /** + * Set the loction where the project is persisted. + * + * @param location Location of project as a file. + */ + public void setLocation(File location) { + try { + setLocation(new URL("file", null, location.getAbsolutePath())); + } + catch(java.net.MalformedURLException ex) { + // No reason why this should happen. + // xxx Log me. + ex.printStackTrace(); + } + } } diff --git a/src/antidote/org/apache/tools/ant/gui/acs/ElementTreeSelectionModel.java b/src/antidote/org/apache/tools/ant/gui/acs/ElementTreeSelectionModel.java index 054adfcb9..677fc7177 100644 --- a/src/antidote/org/apache/tools/ant/gui/acs/ElementTreeSelectionModel.java +++ b/src/antidote/org/apache/tools/ant/gui/acs/ElementTreeSelectionModel.java @@ -76,48 +76,28 @@ public class ElementTreeSelectionModel extends DefaultTreeSelectionModel { /** * Convenience method for providing the set of currently selected - * elements. + * elements. NB: It returns all of the nodes in the selection path, + * so the root node will be a selected element whenever a child is + * selected. * * @return the currently selected elements. */ public ACSElement[] getSelectedElements() { - 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 ACSElement) { - values.add(val); - } - } - - ACSElement[] retval = new ACSElement[values.size()]; - values.toArray(retval); - return retval; - } - - /** - * Get the set of selected tagets. A target is included if one of its - * child nodes is selected. - * - * @return the currently selected targets, and indirectly selected targets. - */ - public ACSTargetElement[] getSelectedTargets() { TreePath[] path = getSelectionPaths(); List values = new LinkedList(); for(int i = 0; path != null && i < path.length; i++) { TreePath curr = path[i]; for(int j = 0; j < curr.getPathCount(); j++) { Object item = curr.getPathComponent(j); - if(item instanceof ACSTargetElement) { + if(item instanceof ACSElement) { values.add(item); } } } - ACSTargetElement[] retval = new ACSTargetElement[values.size()]; + ACSElement[] retval = new ACSElement[values.size()]; values.toArray(retval); return retval; - } } diff --git a/src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java b/src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java index cfb1ea780..740f9a95b 100644 --- a/src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java +++ b/src/antidote/org/apache/tools/ant/gui/command/BuildCmd.java @@ -53,8 +53,9 @@ q * */ package org.apache.tools.ant.gui.command; import org.apache.tools.ant.gui.core.AppContext; -import org.apache.tools.ant.gui.core.ProjectProxy; import org.apache.tools.ant.gui.event.ErrorEvent; +import org.apache.tools.ant.gui.acs.ACSProjectElement; +import org.apache.tools.ant.gui.acs.ACSTargetElement; /** * Starts an Ant build. @@ -64,6 +65,11 @@ import org.apache.tools.ant.gui.event.ErrorEvent; */ public class BuildCmd extends AbstractCommand { + /** Project to build. */ + private ACSProjectElement _project = null; + /** Targets to build. */ + private ACSTargetElement[] _targets = null; + /** * Standard ctor. * @@ -72,15 +78,40 @@ public class BuildCmd extends AbstractCommand { super(context); } + /** + * Set the specific project to build (instead of the default). + * + * @param project Project to build. + */ + public void setProject(ACSProjectElement project) { + _project = project; + } + + /** + * Set the specific targets to build (instead of the default). + * + * @param targets Array of targets to build. + */ + public void setTargets(ACSTargetElement[] targets) { + _targets = targets; + } + /** * Start the Ant build. * */ public void run() { - ProjectProxy project = getContext().getProject(); - if(project != null) { + if(_project == null) { + _project = getContext().getSelectionManager().getSelectedProject(); + } + + if(_targets == null) { + _targets = getContext().getSelectionManager().getSelectedTargets(); + } + + if(_project != null) { try { - project.build(); + getContext().getProjectManager().build(_project, _targets); } catch(Throwable ex) { getContext().getEventBus().postEvent( diff --git a/src/antidote/org/apache/tools/ant/gui/command/CloseCmd.java b/src/antidote/org/apache/tools/ant/gui/command/CloseCmd.java index d8e2ffce1..fa050b15b 100644 --- a/src/antidote/org/apache/tools/ant/gui/command/CloseCmd.java +++ b/src/antidote/org/apache/tools/ant/gui/command/CloseCmd.java @@ -54,6 +54,8 @@ package org.apache.tools.ant.gui.command; import org.apache.tools.ant.gui.core.AppContext; import org.apache.tools.ant.gui.event.ProjectClosedEvent; +import org.apache.tools.ant.gui.event.ProjectSelectedEvent; +import org.apache.tools.ant.gui.acs.ACSProjectElement; /** @@ -64,6 +66,9 @@ import org.apache.tools.ant.gui.event.ProjectClosedEvent; */ public class CloseCmd extends AbstractCommand { + /** Project to close. */ + private ACSProjectElement _project = null; + /** * Standard constructor. * @@ -72,13 +77,35 @@ public class CloseCmd extends AbstractCommand { super(context); } + /** + * Set the specific project to close (instead of the default). + * + * @param project Project to close. + */ + public void setProject(ACSProjectElement project) { + _project = project; + } + /** * Send a close event to the parent window. * */ public void run() { - getContext().setProject(null); - getContext().getEventBus().postEvent( - new ProjectClosedEvent(getContext())); + if(_project == null) { + _project = getContext().getSelectionManager().getSelectedProject(); + } + + if(_project != null) { + getContext().getProjectManager().close(_project); + getContext().getEventBus().postEvent( + new ProjectClosedEvent(getContext())); + + ACSProjectElement[] open = + getContext().getProjectManager().getOpen(); + if(open != null && open.length > 0) { + getContext().getEventBus().postEvent( + new ProjectSelectedEvent(getContext(), open[0])); + } + } } } diff --git a/src/antidote/org/apache/tools/ant/gui/command/EmacsNotifyCmd.java b/src/antidote/org/apache/tools/ant/gui/command/EmacsNotifyCmd.java index 95a1c4205..38813ebbb 100644 --- a/src/antidote/org/apache/tools/ant/gui/command/EmacsNotifyCmd.java +++ b/src/antidote/org/apache/tools/ant/gui/command/EmacsNotifyCmd.java @@ -80,11 +80,12 @@ public class EmacsNotifyCmd extends AbstractCommand { * */ public void run() { - if(getContext().isRegisteredBuildListener(_notifier)) { - getContext().removeBuildListener(_notifier); + if(getContext().getProjectManager(). + isRegisteredBuildListener(_notifier)) { + getContext().getProjectManager().removeBuildListener(_notifier); } else { - getContext().addBuildListener(_notifier); + getContext().getProjectManager().addBuildListener(_notifier); } } } diff --git a/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java b/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java index 1c44d9af0..d199c534c 100644 --- a/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java +++ b/src/antidote/org/apache/tools/ant/gui/command/LoadFileCmd.java @@ -53,8 +53,9 @@ */ package org.apache.tools.ant.gui.command; import org.apache.tools.ant.gui.core.AppContext; -import org.apache.tools.ant.gui.core.ProjectProxy; import org.apache.tools.ant.gui.event.ErrorEvent; +import org.apache.tools.ant.gui.event.ProjectSelectedEvent; +import org.apache.tools.ant.gui.acs.ACSProjectElement; import java.io.File; import java.io.IOException; @@ -100,8 +101,10 @@ public class LoadFileCmd extends AbstractCommand { } else { try { - ProjectProxy project = new ProjectProxy(getContext(), _file); - getContext().setProject(project); + ACSProjectElement project = + getContext().getProjectManager().open(_file); + getContext().getEventBus().postEvent( + new ProjectSelectedEvent(getContext(), project)); } catch(Exception ex) { String message = getContext().getResources().getMessage( diff --git a/src/antidote/org/apache/tools/ant/gui/command/SaveAsCmd.java b/src/antidote/org/apache/tools/ant/gui/command/SaveAsCmd.java index 61a54d544..c27cc38ee 100644 --- a/src/antidote/org/apache/tools/ant/gui/command/SaveAsCmd.java +++ b/src/antidote/org/apache/tools/ant/gui/command/SaveAsCmd.java @@ -53,15 +53,15 @@ */ package org.apache.tools.ant.gui.command; import org.apache.tools.ant.gui.core.AppContext; -import org.apache.tools.ant.gui.core.ProjectProxy; import org.apache.tools.ant.gui.event.ErrorEvent; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; +import org.apache.tools.ant.gui.acs.ACSProjectElement; +import java.io.*; import org.apache.tools.ant.gui.core.XMLFileFilter; import javax.swing.JFileChooser; import javax.swing.filechooser.FileFilter; import javax.swing.JOptionPane; +import java.net.URL; +import java.net.MalformedURLException; /** @@ -72,7 +72,9 @@ import javax.swing.JOptionPane; */ public class SaveAsCmd extends AbstractCommand { /** File to save to. */ - private File _file = null; + private URL _location = null; + /** Project to save. */ + private ACSProjectElement _project = null; /** * Standard ctor. @@ -84,12 +86,21 @@ public class SaveAsCmd extends AbstractCommand { } /** - * Set the file to save to. + * Set the location to save to * - * @param file File to save to. + * @param location location to save to. */ - public void setFile(File file) { - _file = file; + public void setLocation(URL location) { + _location = location; + } + + /** + * Set the specific project to save (instead of the default). + * + * @param project Project to save. + */ + public void setProject(ACSProjectElement project) { + _project = project; } @@ -100,59 +111,59 @@ public class SaveAsCmd extends AbstractCommand { public void run() { FileFilter filter = new XMLFileFilter(getContext().getResources()); - ProjectProxy project = getContext().getProject(); - if(project != null) { - if(_file == null) { - // XXX code here to select a file to save to. + if(_project == null) { + _project = getContext().getSelectionManager().getSelectedProject(); + } + + if(_project != null) { + // If no location is specified, then this truly is a SaveAs + // command. Provide the user the UI to select the output. + if(_location == null) { JFileChooser chooser = new JFileChooser(); chooser.addChoosableFileFilter(filter); int val = chooser.showSaveDialog( getContext().getParentFrame()); if(val == JFileChooser.APPROVE_OPTION) { - _file = chooser.getSelectedFile(); - if(_file.exists()) { + File file = chooser.getSelectedFile(); + if(file.exists()) { String title = getContext().getResources(). getString(SaveCmd.class, "title"); String message = getContext().getResources(). getMessage(SaveCmd.class, "overwrite", - new Object[] {_file.toString()}); + new Object[] { file.toString()}); val = JOptionPane.showConfirmDialog( getContext().getParentFrame(), message, title, JOptionPane.YES_NO_OPTION); // If cancelled unset file. - if(val != JOptionPane.YES_OPTION) { - _file = null; + if(val == JOptionPane.YES_OPTION) { + try { + _location = new URL( + "file", null, file.getAbsolutePath()); + } + catch(MalformedURLException ex) { + // Shouldn't happen. Save will just not + // happen. + ex.printStackTrace(); + } } } } } - if(_file != null) { - project.setFile(_file); - FileWriter out = null; + // If a location is now available, do the save operation. + if(_location != null) { try { - out = new FileWriter(_file); - project.write(out); + getContext().getProjectManager().saveAs( + _project, _location); } catch(IOException ex) { String message = getContext().getResources().getMessage( SaveCmd.class, "saveError", - new Object[] { _file.toString() }); + new Object[] { _location.toString() }); getContext().getEventBus(). postEvent(new ErrorEvent(getContext(), message)); } - finally { - if (out != null) { - try { - out.flush(); - out.close(); - } - catch(IOException ex) { - // Intentionally ignored. - } - } - } } } else { diff --git a/src/antidote/org/apache/tools/ant/gui/command/SaveCmd.java b/src/antidote/org/apache/tools/ant/gui/command/SaveCmd.java index 3c752c736..e46df9029 100644 --- a/src/antidote/org/apache/tools/ant/gui/command/SaveCmd.java +++ b/src/antidote/org/apache/tools/ant/gui/command/SaveCmd.java @@ -53,6 +53,7 @@ */ package org.apache.tools.ant.gui.command; import org.apache.tools.ant.gui.core.AppContext; +import org.apache.tools.ant.gui.acs.ACSProjectElement; /** * Command to execute the saving of the current build file. @@ -69,6 +70,10 @@ public class SaveCmd extends SaveAsCmd { */ public SaveCmd(AppContext context) { super(context); - setFile(context.getProject().getFile()); + ACSProjectElement project = + getContext().getSelectionManager().getSelectedProject(); + if(project != null) { + setLocation(project.getLocation()); + } } } diff --git a/src/antidote/org/apache/tools/ant/gui/core/AppContext.java b/src/antidote/org/apache/tools/ant/gui/core/AppContext.java index 6f70985d1..6eb0a2221 100644 --- a/src/antidote/org/apache/tools/ant/gui/core/AppContext.java +++ b/src/antidote/org/apache/tools/ant/gui/core/AppContext.java @@ -54,6 +54,8 @@ package org.apache.tools.ant.gui.core; import org.apache.tools.ant.BuildListener; import org.apache.tools.ant.gui.event.*; +import org.apache.tools.ant.gui.acs.ACSProjectElement; +import org.apache.tools.ant.gui.acs.ACSTargetElement; import java.awt.Frame; import java.util.*; @@ -71,26 +73,46 @@ public class AppContext { private ResourceManager _resources = new ResourceManager(); /** The project manager. */ private ProjectManager _projectManager = new ProjectManager(); + /** Thing that keeps track of the current selection state. */ + private SelectionManager _selectionManager = new SelectionManager(); + /** Application actions. */ private ActionManager _actions = new ActionManager(_eventBus, new ResourceManager( "org.apache.tools.ant.gui.resources.action")); - /** List of build listeners to register when build starts. */ - private List _buildListeners = new LinkedList(); /** Parent frame used in various operations. XXX what do we do * in the applet context. */ private Frame _parentFrame = null; - /** The current data model. */ - private ProjectProxy _project = null; + /** + * Constructor of apps that don't have a graphical + * component (e.g. web based). + * + */ + public AppContext() { + this(null); + } + /** + * Standard constructor. + * + * @param parent Parent frame. XXX may go away. + */ public AppContext(Frame parent) { _parentFrame = parent; - // Add the build listener for dispatching BuildEvent - // objects to the EventBus. BuildEventForwarder handler = new BuildEventForwarder(this); - addBuildListener(handler); + _projectManager.addBuildListener(handler); + _eventBus.addMember(EventBus.MONITORING, _selectionManager); + } + + /** + * Get the parent frame. XXX may change... + * + * @return Parent frame. + */ + public Frame getParentFrame() { + return _parentFrame; } /** @@ -120,15 +142,6 @@ public class AppContext { return _eventBus; } - /** - * Get the parent frame. XXX may change... - * - * @return Parent frame. - */ - public Frame getParentFrame() { - return _parentFrame; - } - /** * Get the project manager. * @@ -138,68 +151,15 @@ public class AppContext { return _projectManager; } - /** - * Get the current project. - * - * @return Current project. NUll if no active project. - */ - public ProjectProxy getProject() { - return _project; - } - - - /** - * Add a build listener. - * - * @param l Listener to add. - */ - public void addBuildListener(BuildListener l) { - _buildListeners.add(l); - } - - /** - * Remove a build listener. - * - * @param l Listener to remove. - */ - public void removeBuildListener(BuildListener l) { - _buildListeners.remove(l); - } - - /** - * Determine if the given BuildListener is registered. - * - * @param l Listener to test for. - * @return True if listener has been added, false if unknown. - */ - public boolean isRegisteredBuildListener(BuildListener l) { - return _buildListeners.contains(l); - } - - /** - * Get the set of current build listeners. - * - * @return Set of current build listeners. - */ - public BuildListener[] getBuildListeners() { - BuildListener[] retval = new BuildListener[_buildListeners.size()]; - _buildListeners.toArray(retval); - return retval; + /** + * Get the selection manager. + * + * @return Selection manager. + */ + public SelectionManager getSelectionManager() { + return _selectionManager; } - /** - * Set the current project. - * - * @param project Next project to operate on. May be null for the "close" - * action. - - */ - public void setProject(ProjectProxy project) { - if(_project == null || !_project.equals(project)) { - _project = project; - getEventBus().postEvent(new NewProjectEvent(this)); - } - } } diff --git a/src/antidote/org/apache/tools/ant/gui/core/ProjectManager.java b/src/antidote/org/apache/tools/ant/gui/core/ProjectManager.java index 61c799d1a..9f97229e4 100644 --- a/src/antidote/org/apache/tools/ant/gui/core/ProjectManager.java +++ b/src/antidote/org/apache/tools/ant/gui/core/ProjectManager.java @@ -53,15 +53,24 @@ */ package org.apache.tools.ant.gui.core; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.ProjectHelper; +import org.apache.tools.ant.BuildEvent; import org.apache.tools.ant.gui.acs.*; -import java.io.IOException; +import org.apache.tools.ant.gui.event.BuildEventType; +import java.io.*; import java.net.URL; +import java.net.URLConnection; import java.util.*; /** * This class is responsible for managing the currently open projects, * and the loading of new projects. * + * XXX need to add property change listeners support. + * * @version $Revision$ * @author Simeon Fitch */ @@ -69,6 +78,10 @@ public class ProjectManager { /** Set of open projects. */ private List _projects = new ArrayList(1); + /** List of build listeners to register when build starts. */ + private List _buildListeners = new LinkedList(); + /** The current thread executing a build. */ + private Thread _buildThread = null; public ProjectManager() { } @@ -110,18 +123,44 @@ public class ProjectManager { // xxx Fix me. throw new IOException("xxx need a file name xxx"); } + + Writer out = null; + try { + URLConnection connection = location.openConnection(); + connection.setDoInput(false); + connection.setDoOutput(true); + out = new OutputStreamWriter(connection.getOutputStream()); + project.write(out); + project.setLocation(location); + } + finally { + try { out.close(); } catch(Exception ex) {} + } + } + + /** + * Open the project persisted at the given location + * + * @param location Location of project file. + * @return Successfully loaded project. + * @throws IOException thrown if there is a problem opening the project. + */ + public ACSProjectElement open(File location) throws IOException { + return open(new URL("file", null, location.getPath())); } /** * Open the project persisted at the given location * - * @param location Location to save to. + * @param location Location of project file. * @return Successfully loaded project. * @throws IOException thrown if there is a problem opening the project. */ public ACSProjectElement open(URL location) throws IOException { ACSProjectElement retval = null; retval = ACSFactory.getInstance().load(location); + retval.setLocation(location); + _projects.add(retval); return retval; } @@ -134,4 +173,196 @@ public class ProjectManager { ACSProjectElement retval = null; return retval; } + + /** + * Remove the given project from the set of active projects. + * + * @param project Project to close. + */ + public void close(ACSProjectElement project) { + _projects.remove(project); + } + + /** + * Build the project with the given target (or the default target + * if none is selected. Build occurs on a separate thread, so method + * returns immediately. + * + * @param project Project to build. + * @param targets Targets to build in project. + */ + public void build(ACSProjectElement project, ACSTargetElement[] targets) + throws BuildException { + _buildThread = new Thread(new BuildRunner(project, targets)); + _buildThread.start(); + } + + /** + * Add a build listener. + * + * @param l Listener to add. + */ + public void addBuildListener(BuildListener l) { + synchronized(_buildListeners) { + _buildListeners.add(l); + } + } + + /** + * Remove a build listener. + * + * @param l Listener to remove. + */ + public void removeBuildListener(BuildListener l) { + synchronized(_buildListeners) { + _buildListeners.remove(l); + } + } + + /** + * Determine if the given BuildListener is registered. + * + * @param l Listener to test for. + * @return True if listener has been added, false if unknown. + */ + public boolean isRegisteredBuildListener(BuildListener l) { + synchronized(_buildListeners) { + return _buildListeners.contains(l); + } + } + + /** + * Get the set of current build listeners. + * + * @return Set of current build listeners. + */ + public BuildListener[] getBuildListeners() { + synchronized(_buildListeners) { + BuildListener[] retval = new BuildListener[_buildListeners.size()]; + _buildListeners.toArray(retval); + return retval; + } + } + + /** Class for executing the build in a separate thread. */ + private class BuildRunner implements Runnable { + /** The project to execute build on. */ + private ACSProjectElement _project = null; + /** Targets to build. */ + private ACSTargetElement[] _targets = null; + /** The Ant core representation of a project. */ + private Project _antProject = null; + + /** + * Standard ctor. + * + * @param project Project to execute build on. + * @param targets Targets to build. + */ + public BuildRunner(ACSProjectElement project, + ACSTargetElement[] targets) throws BuildException { + _project = project; + _targets = targets; + + URL location = _project.getLocation(); + if(location == null) { + // XXX this needs to be changed so that if the project is + // not saved, or the persistence mechanism is remote + // then a temporary version is saved first. + throw new BuildException("Project must be saved first"); + } + + // XXX hopefully we will eventually be able to save + // project files to any type of URL. Right now the Ant core + // only supports Files. + if(!location.getProtocol().equals("file")) { + throw new IllegalArgumentException( + "The Ant core only supports building from locally " + + "stored build files."); + } + + File f = new File(location.getFile()); + + _antProject = new Project(); + _antProject.init(); + // XXX there is a bunch of stuff in the class + // org.apache.tools.ant.Main that needs to be + // refactored out so that it doesn't have to be + // replicated here. + + // XXX need to provide a way to pass in externally + // defined properties. Perhaps define an external + // Antidote properties file. JAVA_HOME may have to be set, + // as well as checking the .ant.properties + _antProject.setUserProperty( + "ant.file" , f.getAbsolutePath()); + ProjectHelper.configureProject(_antProject, f); + } + + /** + * Convenience method for causeing the project to fire a build event. + * Implemented because the corresponding method in the Project class + * is not publically accessible. + * + * @param event Event to fire. + */ + private void fireBuildEvent(BuildEvent event, BuildEventType type) { + Enumeration enum = _antProject.getBuildListeners().elements(); + while(enum.hasMoreElements()) { + BuildListener l = (BuildListener) enum.nextElement(); + type.fireEvent(event, l); + } + } + + /** + * Run the build. + * + */ + public void run() { + synchronized(_antProject) { + // Add the build listeners + BuildListener[] listeners = getBuildListeners(); + for(int i = 0; i < listeners.length; i++) { + _antProject.addBuildListener(listeners[i]); + } + + try { + + fireBuildEvent(new BuildEvent( + _antProject), BuildEventType.BUILD_STARTED); + + + Vector targetNames = new Vector(); + if(_targets == null || _targets.length == 0) { + targetNames.add(_antProject.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. + _antProject.executeTargets(targetNames); + } + catch(BuildException ex) { + BuildEvent errorEvent = new BuildEvent(_antProject); + errorEvent.setException(ex); + errorEvent.setMessage(ex.getMessage(), Project.MSG_ERR); + fireBuildEvent(errorEvent, BuildEventType.MESSAGE_LOGGED); + } + finally { + fireBuildEvent(new BuildEvent( + _antProject), BuildEventType.BUILD_FINISHED); + + // Remove the build listeners. + for(int i = 0; i < listeners.length; i++) { + _antProject.removeBuildListener(listeners[i]); + } + } + } + } + } } diff --git a/src/antidote/org/apache/tools/ant/gui/core/SelectionManager.java b/src/antidote/org/apache/tools/ant/gui/core/SelectionManager.java new file mode 100644 index 000000000..ca24214aa --- /dev/null +++ b/src/antidote/org/apache/tools/ant/gui/core/SelectionManager.java @@ -0,0 +1,147 @@ +/* + * 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 + * . + */ +package org.apache.tools.ant.gui.core; + +import org.apache.tools.ant.gui.event.*; +import org.apache.tools.ant.gui.command.*; +import org.apache.tools.ant.gui.acs.*; +import java.util.EventObject; +import java.awt.event.ActionEvent; +import javax.swing.*; + +/** + * State management class for keeping track of what build file elements are + * currently selected. It monitors the EventBus for selection events and + * Records the current state. It should be registered with the EventBus + * at the MONITORING level. + * + * @version $Revision$ + * @author Simeon Fitch + */ +public class SelectionManager implements BusMember { + /** The filter for getting the correct events.*/ + private final Filter _filter = new Filter(); + + /** The currently selected project. */ + private ACSProjectElement _project = null; + /** The current set of selected targets. */ + private ACSTargetElement[] _targets = null; + /** The current set of selected elements. */ + private ACSElement[] _elements = null; + + public SelectionManager() { + } + + /** + * 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; + } + + + /** + * Get the currently selected project. + * + * @return Current project. + */ + public ACSProjectElement getSelectedProject() { + return _project; + } + + /** + * Get the selected elements that are targets. + * + */ + public ACSTargetElement[] getSelectedTargets() { + return _targets; + } + + /** + * Get the selected elements. + * + */ + public ACSElement[] getSelectedElements() { + return _elements; + } + + /** + * Called when an event is to be posed to the member. + * + * @param event Event to post. + * @return true if event should be propogated, false if + * it should be cancelled. + */ + public boolean eventPosted(EventObject event) { + _elements = ((ElementSelectionEvent)event).getSelectedElements(); + + if(event instanceof TargetSelectionEvent) { + _targets = ((TargetSelectionEvent)event).getSelectedTargets(); + } + else if(event instanceof ProjectSelectedEvent) { + _project = ((ProjectSelectedEvent)event).getSelectedProject(); + } + return true; + } + + /** Filter for ElementSelectionEvent objects. */ + private static class Filter implements BusFilter { + public boolean accept(EventObject event) { + return event instanceof ElementSelectionEvent; + } + } +} diff --git a/src/antidote/org/apache/tools/ant/gui/event/ElementSelectionEvent.java b/src/antidote/org/apache/tools/ant/gui/event/ElementSelectionEvent.java index d18dfdb81..d7da26dcf 100644 --- a/src/antidote/org/apache/tools/ant/gui/event/ElementSelectionEvent.java +++ b/src/antidote/org/apache/tools/ant/gui/event/ElementSelectionEvent.java @@ -57,6 +57,9 @@ import org.apache.tools.ant.gui.command.Command; import org.apache.tools.ant.gui.command.DisplayErrorCmd; import org.apache.tools.ant.gui.core.AppContext; +import java.lang.reflect.Array; +import java.util.*; + /** * Event indicating that the current set of selected targets has changed. * @@ -90,6 +93,29 @@ public class ElementSelectionEvent extends AntEvent { } + /** + * Get only those events of a specific type. + * + * @param type Specific type to get values for, or null if none. + */ + protected ACSElement[] getFiltered(Class type) { + ACSElement[] retval = null; + List vals = new ArrayList(1); + if(_selected != null) { + for(int i = 0; i < _selected.length; i++) { + if(type.isInstance(_selected[i])) { + vals.add(_selected[i]); + } + } + } + + if(vals.size() > 0) { + retval = (ACSElement[]) Array.newInstance(type, vals.size()); + vals.toArray(retval); + } + return retval; + } + /** * Factory method for creating the appropriate specialization of this * for communicating an element selection. @@ -116,7 +142,8 @@ public class ElementSelectionEvent extends AntEvent { retval = new PropertySelectionEvent(context, selected); } else if(type.isAssignableFrom(ACSProjectElement.class)) { - retval = new ProjectSelectionEvent(context, selected); + retval = new ProjectSelectedEvent( + context, (ACSProjectElement) selected[0]); } else { // For elements without a specific event diff --git a/src/antidote/org/apache/tools/ant/gui/event/EventBus.java b/src/antidote/org/apache/tools/ant/gui/event/EventBus.java index 1b1f24183..d37f83954 100644 --- a/src/antidote/org/apache/tools/ant/gui/event/EventBus.java +++ b/src/antidote/org/apache/tools/ant/gui/event/EventBus.java @@ -75,13 +75,13 @@ import javax.swing.SwingUtilities; * @author Simeon Fitch */ public class EventBus { - /** The default "monitoring" interrupt level, used by members who - * are only listeners/monitors of events. */ - public static final int MONITORING = 1; /** The default "vetoing" interrupt level, used by bus members * whose role is to veto request events or otherwise handle an * event before it is processed by the default handler. */ - public static final int VETOING = 5; + public static final int VETOING = 1; + /** The default "monitoring" interrupt level, used by members who + * are only listeners/monitors of events. */ + public static final int MONITORING = 5; /** The default "responding" interrupt level, for members who service * events in a default manner. */ public static final int RESPONDING = 10; diff --git a/src/antidote/org/apache/tools/ant/gui/event/NewProjectEvent.java b/src/antidote/org/apache/tools/ant/gui/event/NewProjectEvent.java deleted file mode 100644 index b654aaf7a..000000000 --- a/src/antidote/org/apache/tools/ant/gui/event/NewProjectEvent.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 - * . - */ -package org.apache.tools.ant.gui.event; -import org.apache.tools.ant.gui.core.AppContext; - -/** - * Event providing notification of a change in the current project. - * - * @version $Revision$ - * @author Simeon Fitch - */ -public class NewProjectEvent extends AntEvent { - - /** - * Standard ctor. - * - * @param context application context. - */ - public NewProjectEvent(AppContext context) { - super(context); - } -} diff --git a/src/antidote/org/apache/tools/ant/gui/event/ProjectSelectionEvent.java b/src/antidote/org/apache/tools/ant/gui/event/ProjectSelectedEvent.java similarity index 80% rename from src/antidote/org/apache/tools/ant/gui/event/ProjectSelectionEvent.java rename to src/antidote/org/apache/tools/ant/gui/event/ProjectSelectedEvent.java index 2d0527be4..86dab9c51 100644 --- a/src/antidote/org/apache/tools/ant/gui/event/ProjectSelectionEvent.java +++ b/src/antidote/org/apache/tools/ant/gui/event/ProjectSelectedEvent.java @@ -52,24 +52,38 @@ * . */ package org.apache.tools.ant.gui.event; -import org.apache.tools.ant.gui.acs.ACSElement; import org.apache.tools.ant.gui.core.AppContext; +import org.apache.tools.ant.gui.acs.ACSProjectElement; +import org.apache.tools.ant.gui.acs.ACSElement; /** - * Event fired when the project node is selected. + * Event providing notification of a change in the currently selected project. * * @version $Revision$ * @author Simeon Fitch */ -public class ProjectSelectionEvent extends ElementSelectionEvent { +public class ProjectSelectedEvent extends ElementSelectionEvent { + /** The selected project. */ + private ACSProjectElement _project = null; + /** * Standard ctor. * * @param context application context. - * @param selected the selected Elements. */ - public ProjectSelectionEvent(AppContext context, - ACSElement[] selected) { - super(context, selected); + public ProjectSelectedEvent( + AppContext context, ACSProjectElement project) { + super(context, new ACSElement[] { project }); + _project = project; + } + + /** + * Get the selected project, or null if there are no + * open projects. + * + * @return Selected project, or null if no projects selected. + */ + public ACSProjectElement getSelectedProject() { + return _project; } } diff --git a/src/antidote/org/apache/tools/ant/gui/event/PropertySelectionEvent.java b/src/antidote/org/apache/tools/ant/gui/event/PropertySelectionEvent.java index f66fd740b..5d2a53276 100644 --- a/src/antidote/org/apache/tools/ant/gui/event/PropertySelectionEvent.java +++ b/src/antidote/org/apache/tools/ant/gui/event/PropertySelectionEvent.java @@ -53,6 +53,7 @@ */ package org.apache.tools.ant.gui.event; import org.apache.tools.ant.gui.acs.ACSElement; +import org.apache.tools.ant.gui.acs.ACSPropertyElement; import org.apache.tools.ant.gui.core.AppContext; /** @@ -72,4 +73,13 @@ public class PropertySelectionEvent extends ElementSelectionEvent { ACSElement[] selected) { super(context, selected); } + + /** + * Get the selected properties. + * + */ + public ACSPropertyElement[] getSelectedProperties() { + return (ACSPropertyElement[]) getFiltered(ACSPropertyElement.class); + } + } diff --git a/src/antidote/org/apache/tools/ant/gui/event/TargetSelectionEvent.java b/src/antidote/org/apache/tools/ant/gui/event/TargetSelectionEvent.java index 8a04e24d0..8ae33e2a6 100644 --- a/src/antidote/org/apache/tools/ant/gui/event/TargetSelectionEvent.java +++ b/src/antidote/org/apache/tools/ant/gui/event/TargetSelectionEvent.java @@ -53,6 +53,7 @@ */ 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; /** @@ -69,7 +70,16 @@ public class TargetSelectionEvent extends ElementSelectionEvent { * @param selected the selected Elements. */ public TargetSelectionEvent(AppContext context, - ACSElement[] selected) { + ACSElement[] selected) { super(context, selected); } + + /** + * Get the selected targets. + * + */ + public ACSTargetElement[] getSelectedTargets() { + return (ACSTargetElement[]) getFiltered(ACSTargetElement.class); + } + } diff --git a/src/antidote/org/apache/tools/ant/gui/event/TaskSelectionEvent.java b/src/antidote/org/apache/tools/ant/gui/event/TaskSelectionEvent.java index ae1942262..69f703b20 100644 --- a/src/antidote/org/apache/tools/ant/gui/event/TaskSelectionEvent.java +++ b/src/antidote/org/apache/tools/ant/gui/event/TaskSelectionEvent.java @@ -53,6 +53,7 @@ */ package org.apache.tools.ant.gui.event; import org.apache.tools.ant.gui.acs.ACSElement; +import org.apache.tools.ant.gui.acs.ACSTaskElement; import org.apache.tools.ant.gui.core.AppContext; /** @@ -72,4 +73,13 @@ public class TaskSelectionEvent extends ElementSelectionEvent { ACSElement[] selected) { super(context, selected); } + + /** + * Get the selected tasks. + * + */ + public ACSTaskElement[] getSelectedTasks() { + return (ACSTaskElement[]) getFiltered(ACSTaskElement.class); + } + } diff --git a/src/antidote/org/apache/tools/ant/gui/modules/TargetMonitor.java b/src/antidote/org/apache/tools/ant/gui/modules/TargetMonitor.java index b453831ac..c2fa7544a 100644 --- a/src/antidote/org/apache/tools/ant/gui/modules/TargetMonitor.java +++ b/src/antidote/org/apache/tools/ant/gui/modules/TargetMonitor.java @@ -54,6 +54,7 @@ package org.apache.tools.ant.gui.modules; import org.apache.tools.ant.gui.core.*; import 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.acs.ElementTreeSelectionModel; import javax.swing.*; @@ -139,20 +140,21 @@ public class TargetMonitor extends AntModule { public boolean eventPosted(EventObject event) { ElementSelectionEvent e = (ElementSelectionEvent) event; String text = _defText; + ACSElement[] selected = e.getSelectedElements(); - ProjectProxy p = getContext().getProject(); - if(p != null) { - ElementTreeSelectionModel selections = - p.getTreeSelectionModel(); - ACSTargetElement[] targets = selections.getSelectedTargets(); - if(targets != null && targets.length > 0) { - StringBuffer buf = new StringBuffer(); - for(int i = 0; i < targets.length; i++) { - buf.append(targets[i].getName()); - if(i < targets.length - 1) { + if(selected != null && selected.length > 0) { + StringBuffer buf = new StringBuffer(); + + for(int i = 0; i < selected.length; i++) { + if(selected[i] instanceof ACSTargetElement) { + if(buf.length() > 0) { buf.append(", "); } + buf.append(((ACSTargetElement)selected[i]).getName()); } + } + + if(buf.length() > 0) { text = buf.toString(); } } diff --git a/src/antidote/org/apache/tools/ant/gui/modules/console/BuildConsole.java b/src/antidote/org/apache/tools/ant/gui/modules/console/BuildConsole.java index a66eb3983..6b7353541 100644 --- a/src/antidote/org/apache/tools/ant/gui/modules/console/BuildConsole.java +++ b/src/antidote/org/apache/tools/ant/gui/modules/console/BuildConsole.java @@ -153,7 +153,7 @@ public class BuildConsole extends AntModule { * it should be cancelled. */ public boolean eventPosted(EventObject event) { - if(event instanceof NewProjectEvent) { + if(event instanceof ProjectSelectedEvent) { clearDisplay(); return true; } @@ -215,7 +215,7 @@ public class BuildConsole extends AntModule { */ public boolean accept(EventObject event) { return event instanceof AntBuildEvent || - event instanceof NewProjectEvent; + event instanceof ProjectSelectedEvent; } } diff --git a/src/antidote/org/apache/tools/ant/gui/modules/edit/ElementNavigator.java b/src/antidote/org/apache/tools/ant/gui/modules/edit/ElementNavigator.java index 756e77846..93261edb0 100644 --- a/src/antidote/org/apache/tools/ant/gui/modules/edit/ElementNavigator.java +++ b/src/antidote/org/apache/tools/ant/gui/modules/edit/ElementNavigator.java @@ -54,7 +54,12 @@ 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 javax.swing.*; +import javax.swing.event.TreeSelectionListener; +import javax.swing.event.TreeSelectionEvent; import java.awt.GridLayout; import java.awt.Dimension; import java.awt.event.MouseAdapter; @@ -71,6 +76,8 @@ public class ElementNavigator extends AntModule { /** Navigation via a tree widget. */ private JTree _tree = null; + /** The selection model being used. */ + private ElementTreeSelectionModel _selections = null; /** * Default ctor. @@ -94,11 +101,13 @@ public class ElementNavigator extends AntModule { _tree.setModel(null); _tree.setCellRenderer(new ElementTreeCellRenderer()); _tree.addMouseListener(new PopupHandler()); + _tree.putClientProperty("JTree.lineStyle", "Angled"); JScrollPane scroller = new JScrollPane(_tree); add(scroller); setPreferredSize(new Dimension(200, 100)); setMinimumSize(new Dimension(200, 100)); + } /** Class for handling project events. */ @@ -123,7 +132,11 @@ public class ElementNavigator extends AntModule { * it should be cancelled. */ public boolean eventPosted(EventObject event) { - ProjectProxy project = getContext().getProject(); + ACSProjectElement project = null; + if(event instanceof ProjectSelectedEvent) { + ProjectSelectedEvent e = (ProjectSelectedEvent) event; + project = e.getSelectedProject(); + } if(project == null) { // The project has been closed. @@ -131,15 +144,29 @@ public class ElementNavigator extends AntModule { // different version of Swing... _tree.setModel(null); _tree.setSelectionModel(null); + // Send an empty selection event to notify others that + // nothing is selected. + ElementSelectionEvent.createEvent(getContext(), null); } else { - _tree.setModel(project.getTreeModel()); - _tree.setSelectionModel(project.getTreeSelectionModel()); + _tree.setModel(new ElementTreeModel(project)); + _selections = new ElementTreeSelectionModel(); + _selections.addTreeSelectionListener(new SelectionForwarder()); + _tree.setSelectionModel(_selections); } return true; } } + /** Forwards selection events to the event bus. */ + private class SelectionForwarder implements TreeSelectionListener { + public void valueChanged(TreeSelectionEvent e) { + getContext().getEventBus().postEvent( + ElementSelectionEvent.createEvent( + getContext(), _selections.getSelectedElements())); + } + } + /** Class providing filtering for project events. */ private static class Filter implements BusFilter { /** @@ -149,7 +176,8 @@ public class ElementNavigator extends AntModule { * @return True if event should be given to BusMember, false otherwise. */ public boolean accept(EventObject event) { - return event instanceof NewProjectEvent; + return event instanceof ProjectSelectedEvent || + event instanceof ProjectClosedEvent; } } diff --git a/src/antidote/org/apache/tools/ant/gui/modules/edit/PropertyEditor.java b/src/antidote/org/apache/tools/ant/gui/modules/edit/PropertyEditor.java index 7371378f6..0afab4834 100644 --- a/src/antidote/org/apache/tools/ant/gui/modules/edit/PropertyEditor.java +++ b/src/antidote/org/apache/tools/ant/gui/modules/edit/PropertyEditor.java @@ -112,12 +112,16 @@ public class PropertyEditor extends AntModule { _customizer = null; } - if(items != null && items.length == 1) { + if(items != null && items.length > 0) { + // The last selection element is the the one the + // user most recently selected. + ACSElement item = items[items.length - 1]; + try { - BeanInfo info = Introspector.getBeanInfo(items[0].getClass()); + BeanInfo info = Introspector.getBeanInfo(item.getClass()); _customizer = (Customizer) info.getBeanDescriptor(). getCustomizerClass().newInstance(); - _customizer.setObject(items[0]); + _customizer.setObject(item); _container.add(BorderLayout.CENTER, (Component) _customizer); } catch(Exception ex) { @@ -126,7 +130,7 @@ public class PropertyEditor extends AntModule { } } - _container.revalidate(); + _container.repaint(); } 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 a38cb2b08..8ea583a30 100644 --- a/src/antidote/org/apache/tools/ant/gui/resources/action.properties +++ b/src/antidote/org/apache/tools/ant/gui/resources/action.properties @@ -29,7 +29,7 @@ save.disableOn= \ org.apache.tools.ant.gui.event.ProjectClosedEvent, \ org.apache.tools.ant.gui.event.BuildStartedEvent save.enableOn= \ - org.apache.tools.ant.gui.event.NewProjectEvent, \ + org.apache.tools.ant.gui.event.ProjectSelectedEvent, \ org.apache.tools.ant.gui.event.BuildFinishedEvent saveas.name=Save As... @@ -41,7 +41,7 @@ saveas.disableOn= \ org.apache.tools.ant.gui.event.ProjectClosedEvent, \ org.apache.tools.ant.gui.event.BuildStartedEvent saveas.enableOn= \ - org.apache.tools.ant.gui.event.NewProjectEvent, \ + org.apache.tools.ant.gui.event.ProjectSelectedEvent, \ org.apache.tools.ant.gui.event.BuildFinishedEvent close.name=Close @@ -53,7 +53,7 @@ close.disableOn= \ org.apache.tools.ant.gui.event.ProjectClosedEvent, \ org.apache.tools.ant.gui.event.BuildStartedEvent close.enableOn= \ - org.apache.tools.ant.gui.event.NewProjectEvent, \ + org.apache.tools.ant.gui.event.ProjectSelectedEvent, \ org.apache.tools.ant.gui.event.BuildFinishedEvent exit.name=Exit @@ -79,7 +79,7 @@ startBuild.accelerator=control B startBuild.command=org.apache.tools.ant.gui.command.BuildCmd startBuild.enabled=false startBuild.enableOn=\ - org.apache.tools.ant.gui.event.NewProjectEvent, \ + org.apache.tools.ant.gui.event.ProjectSelectedEvent, \ org.apache.tools.ant.gui.event.BuildFinishedEvent startBuild.disableOn=\ org.apache.tools.ant.gui.event.BuildStartedEvent, \ @@ -102,7 +102,7 @@ newTarget.icon=new-target.gif newTarget.enabled=false newTarget.separator=true newTarget.enableOn=\ - org.apache.tools.ant.gui.event.ProjectSelectionEvent + org.apache.tools.ant.gui.event.ProjectSelectedEvent newTarget.disableOn=\ org.apache.tools.ant.gui.event.TargetSelectionEvent, \ org.apache.tools.ant.gui.event.TaskSelectionEvent, \ @@ -126,7 +126,7 @@ newProperty.shortDescription=Create a new property under the selected element newProperty.icon=new-property.gif newProperty.enabled=false newProperty.enableOn=\ - org.apache.tools.ant.gui.event.ProjectSelectionEvent, \ + org.apache.tools.ant.gui.event.ProjectSelectedEvent, \ org.apache.tools.ant.gui.event.TargetSelectionEvent, \ org.apache.tools.ant.gui.event.TaskSelectionEvent newProperty.disableOn=\