diff --git a/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElement.java b/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElement.java
index 4df8ef864..d531d5503 100644
--- a/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElement.java
+++ b/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElement.java
@@ -62,7 +62,7 @@ import java.util.StringTokenizer;
* @version $Revision$
* @author Simeon Fitch
*/
-public class ACSTargetElement extends ACSNamedElement {
+public class ACSTargetElement extends ACSNamedElement implements Cloneable{
/** Dependency property name. */
public static final String DEPENDS = "depends";
@@ -152,4 +152,31 @@ public class ACSTargetElement extends ACSNamedElement {
setAttribute(UNLESS, val);
firePropertyChange(UNLESS, old, val);
}
+
+ /**
+ * Copys the depends of a given target to the current.
+ *
+ * @param Source target for the copy operation.
+ */
+ public void copyDependsFromTarget(ACSTargetElement newTarget) {
+ setDepends(newTarget.getDepends());
+ }
+
+ /**
+ * Copys the depends of a given target to the current.
+ * I can't override clone, because I need an ACSTargetElement
+ * to be returned!
+ *
+ * @return A clones target element
+ */
+ public ACSTargetElement getClone() {
+ ACSTargetElement retVal = null;
+ try {
+ retVal = (ACSTargetElement)clone();
+ retVal.setDepends(getDepends());
+ } catch (java.lang.CloneNotSupportedException ex) {
+ // Cannot occur, for ACSTarget implements Clonable!
+ }
+ return retVal;
+ }
}
diff --git a/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElementBeanInfo.java b/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElementBeanInfo.java
index 949ae126b..1e17d4a20 100644
--- a/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElementBeanInfo.java
+++ b/src/antidote/org/apache/tools/ant/gui/acs/ACSTargetElementBeanInfo.java
@@ -103,7 +103,8 @@ public class ACSTargetElementBeanInfo extends BaseBeanInfo {
new PropertyDescriptor(ACSTargetElement.DESCRIPTION,
ACSTargetElement.class),
new PropertyDescriptor(ACSTargetElement.DEPENDS,
- ACSTargetElement.class),
+ ACSTargetElement.class,
+ "getClone", "copyDependsFromTarget"),
new PropertyDescriptor(ACSTargetElement.IF,
ACSTargetElement.class),
new PropertyDescriptor(ACSTargetElement.UNLESS,
@@ -140,6 +141,11 @@ public class ACSTargetElementBeanInfo extends BaseBeanInfo {
/** Customizer for this bean info. */
public static class Customizer extends DynamicCustomizer {
+ static {
+ PropertyEditorManager.registerEditor(
+ org.apache.tools.ant.gui.acs.ACSTargetElement.class, org.apache.tools.ant.gui.modules.edit.DependentTargetPropertyEditor.class);
+ }
+
public Customizer() {
super(ACSTargetElement.class);
}
diff --git a/src/antidote/org/apache/tools/ant/gui/modules/edit/DependentTargetChooser.java b/src/antidote/org/apache/tools/ant/gui/modules/edit/DependentTargetChooser.java
new file mode 100755
index 000000000..9af1e9c86
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/modules/edit/DependentTargetChooser.java
@@ -0,0 +1,423 @@
+/*
+ * 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 ConstrIBUTORS 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.modules.edit;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.awt.BorderLayout;
+import java.awt.FlowLayout;
+import java.awt.GridBagLayout;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.awt.Frame;
+import java.awt.Dimension;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JButton;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+import javax.swing.ImageIcon;
+import javax.swing.JTable;
+import javax.swing.table.TableColumn;
+
+import org.apache.tools.ant.gui.util.WindowUtils;
+import org.apache.tools.ant.gui.acs.ACSProjectElement;
+import org.apache.tools.ant.gui.acs.ACSTargetElement;
+
+/**
+ * Dialog for choosing dependent targes comfortable.
+ *
+ * @version $Revision$
+ * @author Christoph Wilhelms
+ */
+public class DependentTargetChooser extends JDialog {
+ // "Business"-Object
+ private ACSTargetElement _target = null;
+ // Tables
+ private JTable _srcTable = null;
+ private JTable _dstTable = null;
+ private JButton _append = null;
+ private JButton _remove = null;
+ private JButton _moveUp = null;
+ private JButton _moveDown = null;
+ // Major Elements;
+ private JPanel _commandButtonPanel = null;
+ private JPanel _selectionPanel = null;
+ // CommandButtons
+ private JButton _ok = null;
+ private JButton _cancel = null;
+
+ private static ActionHandler _handler = null;
+
+ /**
+ * Constructor needs a parent Frame
+ */
+ public DependentTargetChooser (Frame parentFrame) {
+ this (parentFrame, null);
+ }
+
+ /**
+ * Constructor needs a parent Frame, target can be set later
+ */
+ public DependentTargetChooser (Frame parentFrame, ACSTargetElement target) {
+ super(parentFrame, true);
+
+ _handler = new ActionHandler(); // get the ActionHandler ready
+
+ // Dialog settings
+ setTitle("Select dependent targets");
+ setDefaultCloseOperation(HIDE_ON_CLOSE);
+
+ // Container
+ JPanel container = new JPanel();
+ this.setContentPane(container);
+ container.setLayout(new BorderLayout());
+
+ // Populate container
+ container.add(getCommandButtonPanel(), BorderLayout.SOUTH);
+ container.add(getSelectionPanel(), BorderLayout.CENTER);
+
+ // Apply model - must be done this late, because it relies
+ // on an instntiated GUI
+ setTarget(target);
+
+ // Set an initial size and pack it
+ container.setPreferredSize(new Dimension(500,200));
+ pack();
+ }
+
+ /**
+ * Lazily get the selectionPanel with 2 tables and 4 buttons
+ * @return the created JPanel
+ */
+ private JPanel getSelectionPanel() {
+ if (_selectionPanel == null) {
+ _selectionPanel = new JPanel();
+ _selectionPanel.setLayout(new GridBagLayout());
+
+ // LEFT Table
+ JScrollPane srcSP = new JScrollPane();
+ srcSP.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ srcSP.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+ _srcTable = createTargetsTable();
+ srcSP.setViewportView(_srcTable);
+
+ GridBagConstraints srcSPConstr = new GridBagConstraints();
+ srcSPConstr.fill = GridBagConstraints.BOTH;
+ srcSPConstr.anchor = GridBagConstraints.CENTER;
+ srcSPConstr.gridx = 0; srcSPConstr.gridy = 0;
+ srcSPConstr.weightx = 1.0; srcSPConstr.weighty = 2.0;
+ srcSPConstr.gridwidth = 1; srcSPConstr.gridheight = 2;
+ srcSPConstr.insets = new Insets(5,5,0,5);
+ _selectionPanel.add(srcSP, srcSPConstr);
+
+ // Append Button
+ _append = new JButton();
+ _append.setIcon(new ImageIcon(getClass().getResource("/org/apache/tools/ant/gui/resources/enter.gif")));
+ _append.setPreferredSize(new Dimension(28, 28));
+ _append.setMaximumSize(new Dimension(28, 28));
+ _append.setMinimumSize(new Dimension(28, 28));
+ _append.addActionListener(_handler);
+
+ GridBagConstraints appendConstr = new GridBagConstraints();
+ appendConstr.fill = GridBagConstraints.NONE;
+ appendConstr.anchor = GridBagConstraints.SOUTH;
+ appendConstr.gridx = 1; appendConstr.gridy = 0;
+ appendConstr.weightx = 0.0; appendConstr.weighty = 1.0;
+ appendConstr.gridwidth = 1; appendConstr.gridheight = 1;
+ appendConstr.insets = new Insets(0,0,2,0);
+ _selectionPanel.add(_append, appendConstr);
+
+ // Remove Button
+ _remove = new JButton();
+ _remove.setIcon(new ImageIcon(getClass().getResource("/org/apache/tools/ant/gui/resources/exit.gif")));
+ _remove.setPreferredSize(new Dimension(28, 28));
+ _remove.setMaximumSize(new Dimension(28, 28));
+ _remove.setMinimumSize(new Dimension(28, 28));
+ _remove.addActionListener(_handler);
+ GridBagConstraints removeConstr = new GridBagConstraints();
+ removeConstr.fill = GridBagConstraints.NONE;
+ removeConstr.anchor = GridBagConstraints.NORTH;
+ removeConstr.gridx = 1; removeConstr.gridy = 1;
+ removeConstr.weightx = 0.0; removeConstr.weighty = 1.0;
+ removeConstr.gridwidth = 1; removeConstr.gridheight = 1;
+ removeConstr.insets = new Insets(3,0,0,0);
+ _selectionPanel.add(_remove, removeConstr);
+
+ // RIGHT Table
+ JScrollPane dstSP = new JScrollPane();
+ dstSP.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ dstSP.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+ _dstTable = createTargetsTable();
+ dstSP.setViewportView(_dstTable);
+
+ GridBagConstraints dstSPConstr = new GridBagConstraints();
+ dstSPConstr.fill = GridBagConstraints.BOTH;
+ dstSPConstr.anchor = GridBagConstraints.CENTER;
+ dstSPConstr.gridx = 2; dstSPConstr.gridy = 0;
+ dstSPConstr.weightx = 1.0; dstSPConstr.weighty = 2.0;
+ dstSPConstr.gridwidth = 1; dstSPConstr.gridheight = 2;
+ dstSPConstr.insets = new Insets(5,5,0,5);
+ _selectionPanel.add(dstSP, dstSPConstr);
+
+ // Move Up Button
+ _moveUp = new JButton();
+ _moveUp.setIcon(new ImageIcon(getClass().getResource("/org/apache/tools/ant/gui/resources/up.gif")));
+ _moveUp.setPreferredSize(new Dimension(28, 28));
+ _moveUp.setMaximumSize(new Dimension(28, 28));
+ _moveUp.setMinimumSize(new Dimension(28, 28));
+ _moveUp.addActionListener(_handler);
+ GridBagConstraints moveUpConstr = new GridBagConstraints();
+ moveUpConstr.fill = GridBagConstraints.NONE;
+ moveUpConstr.anchor = GridBagConstraints.CENTER;
+ moveUpConstr.gridx = 3; moveUpConstr.gridy = 0;
+ moveUpConstr.weightx = 0.0; moveUpConstr.weighty = 1.0;
+ moveUpConstr.gridwidth = 1; moveUpConstr.gridheight = 1;
+ moveUpConstr.insets = new Insets(0,0,0,5);
+ _selectionPanel.add(_moveUp, moveUpConstr);
+
+ // Move Up Button
+ _moveDown = new JButton();
+ _moveDown.setIcon(new ImageIcon(getClass().getResource("/org/apache/tools/ant/gui/resources/down.gif")));
+ _moveDown.setPreferredSize(new Dimension(28, 28));
+ _moveDown.setMaximumSize(new Dimension(28, 28));
+ _moveDown.setMinimumSize(new Dimension(28, 28));
+ _moveDown.addActionListener(_handler);
+ GridBagConstraints moveDownConstr = new GridBagConstraints();
+ moveDownConstr.fill = GridBagConstraints.NONE;
+ moveDownConstr.anchor = GridBagConstraints.CENTER;
+ moveDownConstr.gridx = 3; moveDownConstr.gridy = 1;
+ moveDownConstr.weightx = 0.0; moveDownConstr.weighty = 1.0;
+ moveDownConstr.gridwidth = 1; moveDownConstr.gridheight = 1;
+ moveDownConstr.insets = new Insets(0,0,0,5);
+ _selectionPanel.add(_moveDown, moveDownConstr);
+ }
+ return _selectionPanel;
+ }
+
+ /**
+ * Lazily get the commandButtonPanel
+ * @return the created JPanel
+ */
+ private JPanel getCommandButtonPanel() {
+ if (_commandButtonPanel == null) {
+ _commandButtonPanel = new JPanel();
+ FlowLayout btnLayout = new FlowLayout();
+ btnLayout.setAlignment(FlowLayout.RIGHT);
+ _commandButtonPanel.setLayout(btnLayout);
+
+ _ok = new JButton("OK");
+ _ok.addActionListener(_handler);
+ getRootPane().setDefaultButton(_ok);
+ _cancel = new JButton("Cancel");
+ _cancel.addActionListener(_handler);
+
+ _commandButtonPanel.add(_ok);
+ _commandButtonPanel.add(_cancel);
+ }
+ return _commandButtonPanel;
+ }
+
+
+ /**
+ * Writer method for the model-element
+ * @param ACSTargetElement the new Target model element.
+ */
+ public void setTarget(ACSTargetElement newTarget) {
+ _target = newTarget;
+
+ // fill source-TableModel with "sister-targets"
+ TargetsTableModel srcModel = (TargetsTableModel)_srcTable.getModel();
+ srcModel.setTargets(getCoTargets(newTarget));
+ srcModel.fireTableDataChanged();
+
+ // fill dest-TableModel with selected depends-targets
+ TargetsTableModel dstModel = (TargetsTableModel)_dstTable.getModel();
+ dstModel.setTargets(fillDependsList(newTarget));
+ dstModel.fireTableDataChanged();
+ }
+
+ /**
+ * Fills a List with all sister- or depending-targets of a single target
+ * @return filled or empty List
+ */
+ private List fillDependsList(ACSTargetElement aTarget) {
+ List retVal = new ArrayList();
+
+ String[] dependNames = aTarget.getDepends();
+ int length = dependNames.length;
+ ArrayList allTargets = getCoTargets (aTarget);
+ int allLen = allTargets.size();
+
+ for (int i = 0; i < length; i++)
+ {
+ for (int j = 0; j < allLen; j++) {
+ ACSTargetElement currentElement = (ACSTargetElement)allTargets.get(j);
+ if (currentElement.getName().equalsIgnoreCase(dependNames[i].trim())) retVal.add(currentElement);
+ }
+ }
+ return retVal;
+ }
+
+ private ArrayList getCoTargets (ACSTargetElement aTarget) {
+ ACSProjectElement parentProject = null;
+ // Caution is the mother of wisdom ;-)
+ if (aTarget.getParentNode() instanceof ACSProjectElement)
+ parentProject = (ACSProjectElement) aTarget.getParentNode();
+ else throw new IllegalArgumentException("Target not part of Project");
+
+ NodeList allNodes = parentProject.getChildNodes();
+ ArrayList retVal = new ArrayList();
+ int length = allNodes.getLength();
+ for (int i = 0; i < length; i++)
+ {
+ Node node = allNodes.item(i);
+ if (node instanceof ACSTargetElement) {
+ ACSTargetElement currentElement = ((ACSTargetElement)node);
+ // ... leave out the current target TODO: avoid cyclic relations!
+ if (currentElement != aTarget) retVal.add(currentElement);
+ }
+ }
+ return retVal;
+ }
+
+ /**
+ * Checks if a String is part of an existing dependent task list
+ * @return true, if it is a dependent target
+ */
+ private boolean checkDepends(String name, ACSTargetElement aTarget) {
+ String[] depend = aTarget.getDepends();
+ for( int i= 0; i < depend.length; i++) {
+ if (name.equalsIgnoreCase(depend[i])) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Creates a target-table with two columns - we need two of them!
+ * @return created JTable
+ */
+ private JTable createTargetsTable() {
+ JTable table = new JTable();
+ table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+ table.setAutoCreateColumnsFromModel(false);
+ table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ // Coulumn showing the Target
+ TableColumn targetCol = new TableColumn();
+ targetCol.setHeaderValue("Target");
+ targetCol.setModelIndex(0);
+ targetCol.setPreferredWidth(150);
+ targetCol.setMaxWidth(150);
+ targetCol.setResizable(true);
+ // Coulumn showing the description of targets
+ TableColumn descrCol = new TableColumn();
+ descrCol.setHeaderValue("Description");
+ descrCol.setModelIndex(1);
+ descrCol.setPreferredWidth(250);
+ descrCol.setResizable(false);
+ table.addColumn(targetCol);
+ table.addColumn(descrCol);
+ table.setModel(new TargetsTableModel());
+
+ return table;
+ }
+
+
+ /**
+ * Ihis handler is the ActionListener for each button.
+ */
+ private class ActionHandler implements ActionListener {
+ /**
+ * ActionListener Interface ethod
+ * @param ActionEvent
+ */
+ public void actionPerformed(ActionEvent e) {
+ // Get some initial values needed later
+ TargetsTableModel srcModel = (TargetsTableModel)_srcTable.getModel();
+ TargetsTableModel dstModel = (TargetsTableModel)_dstTable.getModel();
+ int srcRow = _srcTable.getSelectedRow();
+ int dstRow = _dstTable.getSelectedRow();
+ // Evaluate EventSource
+ if (e.getSource()==_ok) {
+ // OK: take the selected targets and leave
+ _target.setDepends( dstModel.getTargetsAsStringArray() );
+ dispose();
+ } else if (e.getSource()==_cancel) {
+ // just close dialog
+ dispose();
+ } else if (e.getSource()==_moveUp) {
+ // Move dependent target up (one row)
+ dstModel.moveTarget(dstRow, -1);
+ _dstTable.getSelectionModel().setSelectionInterval(dstRow - 1, dstRow - 1);
+ } else if (e.getSource()==_moveDown) {
+ // Move dependent target down (one row)
+ dstModel.moveTarget(dstRow, 1);
+ _dstTable.getSelectionModel().setSelectionInterval(dstRow + 1, dstRow + 1);
+ } else if (e.getSource()==_append) {
+ // Append selected target to depends
+ if (srcRow >= 0) dstModel.addTarget(srcModel.getTarget(srcRow));
+ } else if (e.getSource()==_remove) {
+ // Remove dependent target
+ if (dstRow >= 0) dstModel.removeTarget(dstRow);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/antidote/org/apache/tools/ant/gui/modules/edit/DependentTargetPropertyEditor.java b/src/antidote/org/apache/tools/ant/gui/modules/edit/DependentTargetPropertyEditor.java
new file mode 100755
index 000000000..c3cc1eadc
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/modules/edit/DependentTargetPropertyEditor.java
@@ -0,0 +1,327 @@
+/*
+ * 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.modules.edit;
+
+import java.util.StringTokenizer;
+
+import java.awt.Component;
+import java.awt.BorderLayout;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.KeyEvent;
+import java.awt.Point;
+import java.awt.Dimension;
+import java.awt.Toolkit;
+
+import javax.swing.JPanel;
+import javax.swing.JButton;
+import javax.swing.JTextField;
+import javax.swing.JOptionPane;
+import javax.swing.BorderFactory;
+import javax.swing.border.BevelBorder;
+
+import org.apache.tools.ant.gui.customizer.AbstractPropertyEditor;
+import org.apache.tools.ant.gui.acs.ACSTargetElement;
+
+/**
+ * PropertyEditor for DependentTargets
+ *
+ * @version $Revision$
+ * @author Christoph Wilhelms
+ */
+public class DependentTargetPropertyEditor extends AbstractPropertyEditor {
+ private JTextField _textField = null;
+ private JButton _button = null;
+ private JPanel _widget = null;
+ private ACSTargetElement _value = null;
+ private EventHandler _handler = new EventHandler();
+ private static DependentTargetChooser _dialog = null;
+
+ /**
+ * Gets the editor component: A panel containing a textfield an a button.
+ * @return the property editor component
+ */
+ public Component getChild() {
+ if (_widget == null) // Lazy get
+ {
+ _widget = new JPanel();
+ _widget.setLayout(new BorderLayout());
+ _widget.add(getTextField(), BorderLayout.CENTER);
+ _widget.add(getButton(), BorderLayout.EAST);
+ }
+ return _widget;
+ }
+
+ /**
+ * Lazily create the textfield, to make sure its only instantiated once.
+ * @return the button
+ */
+ private JTextField getTextField() {
+ if (_textField == null) {
+ _textField = new JTextField();
+ _textField.setText(getAsText());
+ _textField.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
+ _textField.addFocusListener(_handler);
+ _textField.addKeyListener(_handler);
+ // We dont really need the next line in Antidote context, just for testpurpose!
+ _textField.setPreferredSize(new Dimension(150, _textField.getPreferredSize().height));
+ }
+ // Transfer Tooltip from Panel to TextField - this hat to be done at every get!
+ _textField.setToolTipText( _widget.getToolTipText());
+
+ return _textField;
+ }
+
+ /**
+ * Lazily create the button, to make sure its only instantiated once.
+ * @return the button
+ */
+ private JButton getButton() {
+ if (_button == null) {
+ _button = new JButton();
+ _button.setText("..."); // Probably an Image is more nice, but ... is standart, I think.
+ _button.setPreferredSize(new Dimension(getTextField().getPreferredSize().height, getTextField().getPreferredSize().height));
+ _button.addActionListener(_handler);
+ }
+ return _button;
+ }
+
+ /**
+ * Sets the model for the component. Used to comunicate externally.
+ * @param The target element the editior works with.
+ */
+ public void setValue(Object newValue) {
+ if(!(newValue instanceof ACSTargetElement)) {
+ throw new IllegalArgumentException(
+ "Value must be of type ACSTargetElement.");
+ }
+ _value = (ACSTargetElement)newValue;
+
+ // Directly show the targets.
+ getTextField().setText(getAsText());
+ }
+
+ /**
+ * Sets the model for the component. Used to comunicate externally.
+ * @return The target element the editior works with.
+ */
+ public Object getValue() {
+ return _value;
+ }
+
+ /**
+ * Sets the depends for the target as text.
+ * @param A String containing all targetnames, separated by ","
+ */
+ public void setAsText(String newValue) {
+ String vals = getTextField().getText();
+ StringTokenizer tok = new StringTokenizer(vals,",");
+ String[] depends = new String[tok.countTokens()];
+ for(int i = 0; i < depends.length; i++) {
+ depends[i] = tok.nextToken().trim();
+ }
+ // Directly supply the target with the new depends.
+ ((ACSTargetElement)getValue()).setDepends(depends);;
+ }
+
+ /**
+ * Gets the depends for the target as text.
+ * @return A String containing all targetnames, separated by ","
+ */
+ public String getAsText() {
+ if (_value == null) return "";
+ String[] dep = _value.getDepends();
+ String retVal = "";
+ for (int i = 0; i < dep.length; i++) {
+ retVal += dep[i];
+ if (i < dep.length - 1) retVal += ", ";
+ }
+ return retVal;
+ }
+
+ /**
+ * Creates and shows the dialog for selecting dependent targets.
+ */
+ private void showSelectionDialog() {
+ // Create the dialog lazyly - it is static, for we want only ONE instance!
+ if (_dialog == null) {
+ _dialog = new DependentTargetChooser(JOptionPane.getFrameForComponent(getChild()), (ACSTargetElement)getValue());
+ }
+ else {
+ // Supply dialog with target - it needs nothing else ;-) - but the
+ // target will be modified by the dialog.
+ _dialog.setTarget((ACSTargetElement)getValue());
+ }
+ String oldValue = getTextField().getText();
+ // Set the position of the dialog right under the Editor, if possible
+ DependentTargetPropertyEditor.setWindowRelativeToComponent (_dialog, getChild());
+ _dialog.show();
+ // after the modal dialog is disposed make shure that the propertyChangeEvent
+ // will be thrown and the textfield becomes updated!
+ Object newValue = (Object)getAsText();
+
+ getTextField().setText(getAsText());
+ firePropertyChange(newValue, oldValue);
+ }
+
+ /**
+ * Handler for ButtonAction, Focus- and KeyListening. I can't use the FocusHandler
+ * in superclass, for I have a different Object in Property Change!
+ */
+ private class EventHandler implements ActionListener, FocusListener, KeyListener {
+ /* ActionListener methods */
+ public void actionPerformed(ActionEvent e) {
+ if (e.getSource() == _button) showSelectionDialog();
+ }
+ /* FocusListener methods */
+ public void focusLost(FocusEvent e) {
+ Object oldValue = (Object)getAsText();
+ String newValue = getTextField().getText();
+ setAsText(newValue);
+ firePropertyChange(newValue, oldValue);
+ }
+ public void focusGained(FocusEvent e) {
+ }
+ /* KeyListener methods */
+ public void keyPressed(KeyEvent e) {
+ }
+ public void keyTyped(KeyEvent e) {
+ }
+ public void keyReleased(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_F4) {
+ showSelectionDialog();
+ }
+ }
+ }
+
+ /**
+ * Places a window, depending of it's size, relative to a component and it's size
+ * TODO: move to WindowUtilities
+ */
+ public static void setWindowRelativeToComponent (java.awt.Window window, Component theComp) {
+ int compX = theComp.getLocationOnScreen().x;
+ int compY = theComp.getLocationOnScreen().y;
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ Dimension dialogSize = window.getSize();
+ int x = 0, y = 0;
+
+ // Window should be aligned LEFT with component
+ x = compX;
+ // If there is not enough space to align LEFT, align RIGTH
+ if (x + dialogSize.width > screenSize.getWidth()) {
+ x = compX - (dialogSize.width - theComp.getWidth());
+ }
+ // If there is not enough space to align LEFT, make sure that it
+ // will be display completely.
+ if (x < 0) x = 0;
+
+ // Window should be located BELOW component
+ y = compY + theComp.getHeight();
+ // If there is not enough space Window BELOW component, place ABOVE component
+ if (y + dialogSize.height > screenSize.getHeight() ) {
+ y = compY - dialogSize.height;
+ }
+ // If there is not enough space Window ABOVE component make sure that it
+ // will be display completely.
+ if (y < 0) y = 0;
+
+ window.setLocation(x, y);
+ }
+
+ /** main just for Test reasons */
+ public static void main(String[] args) {
+ javax.swing.JFrame f = new javax.swing.JFrame();
+ f.setDefaultCloseOperation(3 /*JFrame.EXIT_ON_CLOSE*/);
+
+ org.apache.tools.ant.gui.core.AppContext context = new org.apache.tools.ant.gui.core.AppContext(f);
+ try {
+ context.getProjectManager().open(new java.io.File("G:\\build.xml"));
+ } catch (Exception e) {
+ System.out.println("No buildfile found");
+ }
+
+ JPanel c = new JPanel();
+ c.setLayout(new java.awt.FlowLayout());
+ f.setContentPane(c);
+
+ org.w3c.dom.NodeList all2ndLevelNodes = context.getProjectManager().getOpen()[0].getChildNodes();
+
+ int i= 0;
+ while (i < all2ndLevelNodes.getLength()) {
+ org.w3c.dom.Node node = all2ndLevelNodes.item(i);
+ if (node instanceof ACSTargetElement) {
+ ACSTargetElement newTarget = ((ACSTargetElement)node);
+ DependentTargetPropertyEditor a = new DependentTargetPropertyEditor();
+ c.add(a.getChild());
+ a.setValue(newTarget);
+ }
+ i++;
+ }
+ f.pack();
+
+ f.addWindowListener(new java.awt.event.WindowListener() {
+ public void windowOpened(java.awt.event.WindowEvent e) {}
+ public void windowIconified(java.awt.event.WindowEvent e) {}
+ public void windowDeiconified(java.awt.event.WindowEvent e) {}
+ public void windowActivated(java.awt.event.WindowEvent e) {}
+ public void windowDeactivated(java.awt.event.WindowEvent e) {}
+ public void windowClosing(java.awt.event.WindowEvent e) {}
+ public void windowClosed(java.awt.event.WindowEvent e) {System.exit(0);}
+ });
+ f.show();
+ }
+}
\ No newline at end of file
diff --git a/src/antidote/org/apache/tools/ant/gui/modules/edit/TargetsTableModel.java b/src/antidote/org/apache/tools/ant/gui/modules/edit/TargetsTableModel.java
new file mode 100755
index 000000000..cd6eb62a3
--- /dev/null
+++ b/src/antidote/org/apache/tools/ant/gui/modules/edit/TargetsTableModel.java
@@ -0,0 +1,189 @@
+/*
+ * 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.modules.edit;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.util.List;
+import java.util.ArrayList;
+
+import javax.swing.table.AbstractTableModel;
+
+import org.apache.tools.ant.gui.acs.ACSProjectElement;
+import org.apache.tools.ant.gui.acs.ACSTargetElement;
+
+/**
+ * This is a TableModel containing the co-targets of a distinct target.
+ *
+ * @version $Revision$
+ * @author Christoph Wilhelms
+ */
+public class TargetsTableModel extends AbstractTableModel {
+ // model data
+ private List _delegate = new ArrayList();
+ private ACSTargetElement _mainTarget = null;
+
+ /**
+ * Default constructor
+ */
+ public TargetsTableModel() {
+ super();
+ }
+
+ /**
+ * @param int columnIndex
+ * @return String.class
+ */
+ public Class getColumnClass(int columnIndex) {
+ return String.class;
+ }
+
+ /**
+ * @return 2
+ */
+ public int getColumnCount() {
+ return 2;
+ }
+
+ /**
+ * @return number of containing element
+ */
+ public int getRowCount() {
+ return _delegate.size();
+ }
+
+ /**
+ * @param row and column in table
+ * @return the requested object to be shown.
+ */
+ public Object getValueAt(int row, int col) {
+ ACSTargetElement rowObj = (ACSTargetElement)_delegate.get(row);
+ switch (col) {
+ case 0: return rowObj.getName();
+ case 1: return rowObj.getDescription();
+ default: return "";
+ }
+ }
+
+ /**
+ * @return false for no cell is editable.
+ */
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+
+ /**
+ * Change the entire model.
+ * @param List of ACSTargetElements
+ */
+ public void setTargets(List newTargets) {
+ _delegate = newTargets;
+ fireTableDataChanged();
+ }
+
+ /**
+ * Access a single element.
+ * @param rowIndex
+ * @return ACSTargetElement
+ */
+ public ACSTargetElement getTarget(int index) {
+ return (ACSTargetElement)_delegate.get(index);
+ }
+
+ /**
+ * Remove a single element.
+ * @param int rowIndex
+ */
+ public void removeTarget(int index) {
+ _delegate.remove(index);
+ fireTableRowsDeleted(index -1, index);
+ }
+
+ /**
+ * Add a new element to list.
+ * @param ACSTargetElement newTarget to be added to the list.
+ */
+ public void addTarget(ACSTargetElement newTarget) {
+ _delegate.add(newTarget);
+ fireTableRowsInserted(_delegate.size()-1, _delegate.size());
+ }
+
+ /**
+ * Moves a Target
+ * @param int rowindex in List
+ * @param int delta to move (negative to move up)
+ */
+ public void moveTarget(int index, int delta) {
+ if (index + delta < 0) return;
+ else if (index + delta > _delegate.size()) return;
+ Object backObj = _delegate.get(index + delta);
+ _delegate.set(index + delta, _delegate.get(index) );
+ _delegate.set(index, backObj);
+ fireTableRowsUpdated(index + delta, index);
+ }
+
+ /**
+ * @return a StringArray (String[]) containing the names of all targets.
+ */
+ public String[] getTargetsAsStringArray() {
+ int length = _delegate.size();
+ String[] retVal = new String[length];
+
+ for (int i = 0; i < length; i++) {
+ retVal[i] = ((ACSTargetElement)_delegate.get(i)).getName();
+ }
+ return retVal;
+ }
+}
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/down.gif b/src/antidote/org/apache/tools/ant/gui/resources/down.gif
new file mode 100755
index 000000000..c4ea1a7e0
Binary files /dev/null and b/src/antidote/org/apache/tools/ant/gui/resources/down.gif differ
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/enter.gif b/src/antidote/org/apache/tools/ant/gui/resources/enter.gif
new file mode 100755
index 000000000..1153c7940
Binary files /dev/null and b/src/antidote/org/apache/tools/ant/gui/resources/enter.gif differ
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/exit.gif b/src/antidote/org/apache/tools/ant/gui/resources/exit.gif
new file mode 100755
index 000000000..70a31cece
Binary files /dev/null and b/src/antidote/org/apache/tools/ant/gui/resources/exit.gif differ
diff --git a/src/antidote/org/apache/tools/ant/gui/resources/up.gif b/src/antidote/org/apache/tools/ant/gui/resources/up.gif
new file mode 100755
index 000000000..9de036526
Binary files /dev/null and b/src/antidote/org/apache/tools/ant/gui/resources/up.gif differ