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