chrisw 2003/01/13 05:31:24
Modified: src/java/org/apache/tools/ant/gui/core ActionManager.java
src/java/org/apache/tools/ant/gui/event
ElementSelectionEvent.java
src/java/org/apache/tools/ant/gui/modules/edit
ElementNavigator.java
src/java/org/apache/tools/ant/gui/resources
action.properties antidote.properties
Added: src/java/org/apache/tools/ant/gui/event
IntrospectedElementSelectionEvent.java
src/java/org/apache/tools/ant/gui/modules/edit
AttributePropertyEditor.java
src/java/org/apache/tools/ant/gui/resources add-element.gif
delete.gif new-element.gif
src/java/org/apache/tools/ant/gui/xml DOMAttributes.java
Log:
Introducing Introspection.
Revision Changes Path
1.2 +115 -116
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/core/ActionManager.java
Index: ActionManager.java
===================================================================
RCS file:
/home/cvs/jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/core/ActionManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ActionManager.java 8 Apr 2001 23:42:11 -0000 1.1
+++ ActionManager.java 13 Jan 2003 13:31:24 -0000 1.2
@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights
+ * Copyright (c) 2000 - 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,43 +67,43 @@
* ResourceBundle.
*
* @version $Revision$
- * @author Simeon Fitch
+ * @author Simeon Fitch, Christoph Wilhelms
*/
public class ActionManager {
/** Parameters for the Command constructor. */
private static final Class[] COMMAND_CTOR_PARAMS = { AppContext.class };
private static final Class[] COMMAND_CTOR_PARAMS_WITH_EVENT =
- { AppContext.class, EventObject.class };
-
+ { AppContext.class, EventObject.class };
+
/** Externalized resources. */
private ResourceManager _resources = null;
-
+
/** Array of action identifiers. */
private String[] _actionIDs = null;
-
+
/** Look table of all defined actions. */
private Map _actions = new HashMap();
-
+
/** Event bus. */
private EventBus _bus = null;
/** Class for storing the event type to action type
* mapping for setting enabled state. */
private EventToActionMapper _mapper = null;
-
-
- /**
- * Standard ctor.
- *
- * @param bus Event bus to post events to.
+
+
+ /**
+ * Standard ctor.
+ *
+ * @param bus Event bus to post events to.
* @param resources Location of resources.
- */
+ */
public ActionManager(EventBus bus, ResourceManager resources) {
_bus = bus;
_resources = resources;
bus.addMember(EventBus.RESPONDING, new Enabler());
-
+
_mapper = new EventToActionMapper();
-
+
// Configure the set of actions.
String[] names = _resources.getStringArray("actions");
_actionIDs = new String[names.length];
@@ -111,31 +111,31 @@
_actionIDs[i] = names[i];
AntAction action = new AntAction(_resources, _bus,
_actionIDs[i]);
_actions.put(_actionIDs[i], action);
-
+
// For each action we need to add the reverse event trigger
// lookup.
_mapper.addAction(action);
}
}
-
- /**
- * Create a menubar for the application based on the configuration file.
- *
- * @return Menubar.
- */
+
+ /**
+ * Create a menubar for the application based on the configuration file.
+ *
+ * @return Menubar.
+ */
public JMenuBar createMenuBar() {
JMenuBar retval = new JMenuBar();
Map menus = new HashMap();
-
+
String toTok = _resources.getString("menus");
StringTokenizer tok = new StringTokenizer(toTok, ", ");
while(tok.hasMoreTokens()) {
String name = tok.nextToken();
JMenu menu = new JMenu(name);
-
+
// XXX should be in config file
menu.setMnemonic(name.charAt(0));
-
+
// XXX need to i18n here...
if(name.equalsIgnoreCase("help")) {
try {
@@ -152,7 +152,7 @@
}
menus.put(name, menu);
}
-
+
for(int i = 0; i < _actionIDs.length; i++) {
AntAction action = (AntAction) _actions.get(_actionIDs[i]);
String parent = action.getParentMenuName();
@@ -165,13 +165,13 @@
retval.add(menu);
menus.put(parent, menu);
}
-
+
// See if we should add a separator.
if(action.isPreceededBySeparator() &&
- menu.getMenuComponentCount() > 0) {
+ menu.getMenuComponentCount() > 0) {
menu.addSeparator();
}
-
+
if(!action.isToggle()) {
JMenuItem item = menu.add(action);
item.setAccelerator(action.getAccelerator());
@@ -179,34 +179,34 @@
}
else {
JCheckBoxMenuItem b =
- new JCheckBoxMenuItem(action.getName());
+ new JCheckBoxMenuItem(action.getName());
b.setActionCommand(action.getID());
b.addActionListener(action);
-
+
action.addPropertyChangeListener(
- new PropertyWatcher(b));
-
+ new PropertyWatcher(b));
+
// XXX eck. This is a 1.3 feature. Fix ME!
// Need to provide binding between action and widget.
-// b.setAction(action);
+ // b.setAction(action);
addNiceStuff(b, action);
menu.add(b);
}
-
+
}
}
-
+
return retval;
}
-
- /**
- * Create a tool bar based on the current configuration.
- *
- * @return Toolbar ready for action.
- */
+
+ /**
+ * Create a tool bar based on the current configuration.
+ *
+ * @return Toolbar ready for action.
+ */
public JToolBar createToolBar() {
JToolBar retval = new JToolBar();
-
+
for(int i = 0; i < _actionIDs.length; i++) {
AntAction action = (AntAction) _actions.get(_actionIDs[i]);
@@ -220,93 +220,92 @@
if(action.isPreceededBySeparator()) {
retval.addSeparator();
}
-
+
JButton button = retval.add(action);
button.setText(null);
-
+
// Watch for CHECKED changes
action.addPropertyChangeListener(
- new PropertyWatcher(button));
-
+ new PropertyWatcher(button));
+
if(action.isToggle()) {
ButtonModel model = new CheckableButtonModel();
button.setModel(model);
}
-
+
addNiceStuff(button, action);
}
}
-
+
return retval;
}
-
- /**
- * Create a popup menu with the given actionIDs.
- * XXX check this for object leak. Does the button
- * get added to the action as a listener? There are also some
- * changes to this behavior in 1.3.
- *
- * @param actionIDs List of action IDs for actions
- * to appear in popup menu.
- * @param defaultID Use this action ID if the item
- * from the list is not found.
- * @return Popup menu to display.
- */
+
+ /**
+ * Create a popup menu with the given actionIDs.
+ * XXX check this for object leak. Does the button
+ * get added to the action as a listener? There are also some
+ * changes to this behavior in 1.3.
+ *
+ * @param actionIDs List of action IDs for actions
+ * to appear in popup menu.
+ * @param defaultID Use this action ID if the item
+ * from the list is not found.
+ * @return Popup menu to display.
+ */
public JPopupMenu createPopup(String[] actionIDs, String defaultID) {
-
+
JPopupMenu retval = new JPopupMenu();
-
+
for(int i = 0; i < actionIDs.length; i++) {
AntAction action = (AntAction) _actions.get(actionIDs[i]);
// If the ID is not found, use the default.
if (action == null && defaultID != null) {
- action = (AntAction) _actions.get(defaultID);
+ action = (AntAction) _actions.get("default");
AbstractButton button = retval.add(action);
// Set the button text to the action ID.
button.setText(actionIDs[i]);
addNiceStuff(button, action);
} else {
- if(action.isPopupPreceededBySeparator() &&
- retval.getComponentCount() > 0) {
- retval.addSeparator();
- }
-
AbstractButton button = retval.add(action);
addNiceStuff(button, action);
+
+ if(action.isPopupPreceededBySeparator() &&
retval.getComponentCount() > 0) {
+ retval.addSeparator();
+ }
}
}
-
+
return retval;
}
-
- /**
- * Get the command assocaited with the Action with the given id.
- *
- * @param actionID Id of action to get command for.
- * @return Command associated with action, or null if none available.
- */
+
+ /**
+ * Get the command assocaited with the Action with the given id.
+ *
+ * @param actionID Id of action to get command for.
+ * @return Command associated with action, or null if none available.
+ */
public Command getActionCommand(String actionID,
- AppContext context,
- EventObject event) {
+ AppContext context,
+ EventObject event) {
Command retval = null;
AntAction action = (AntAction) _actions.get(actionID);
if(action != null) {
Class clazz = action.getCommandClass();
if(clazz != null) {
try {
- Constructor ctor =
- clazz.getConstructor(COMMAND_CTOR_PARAMS);
+ Constructor ctor =
+ clazz.getConstructor(COMMAND_CTOR_PARAMS);
retval = (Command) ctor.newInstance(
- new Object[] { context });
+ new Object[] { context });
}
catch(Exception ex) {
try {
Constructor ctor = clazz.getConstructor(
- COMMAND_CTOR_PARAMS_WITH_EVENT);
+ COMMAND_CTOR_PARAMS_WITH_EVENT);
retval = (Command) ctor.newInstance(
- new Object[] { context, event });
+ new Object[] { context, event });
}
catch (Exception ex2) {
// XXX log me.
@@ -317,47 +316,47 @@
}
return retval;
}
-
-
- /**
- * Get the Action with the given id.
- *
- * @param actionID Id of action to get command for.
- * @return AntAction associated with the given id.
- */
+
+
+ /**
+ * Get the Action with the given id.
+ *
+ * @param actionID Id of action to get command for.
+ * @return AntAction associated with the given id.
+ */
public AntAction getAction(String actionID) {
return (AntAction) _actions.get(actionID);
}
- /**
- * Add tool tip, Mnemonic, etc.
- *
- * @param button Button to work on.
- * @param action Associated action.
- */
+ /**
+ * Add tool tip, Mnemonic, etc.
+ *
+ * @param button Button to work on.
+ * @param action Associated action.
+ */
private void addNiceStuff(AbstractButton button, AntAction action) {
// Set the action command so that it is consitent
// no matter what language the display is in.
button.setActionCommand(action.getID());
-
+
// XXX this should be moved to the config file.
String label = button.getText();
if(label != null) {
button.setMnemonic(label.charAt(0));
}
-
+
String tip = action.getShortDescription();
if(tip != null) {
button.setToolTipText(tip);
}
}
-
-
+
+
/** Class for updating the enabled status of icons based
* on the events seen. */
private class Enabler implements BusMember {
private final Filter _filter = new Filter();
-
+
/**
* Get the filter to that is used to determine if an event should
* to to the member.
@@ -367,7 +366,7 @@
public BusFilter getBusFilter() {
return _filter;
}
-
+
/**
* Receives all events.
*
@@ -380,7 +379,7 @@
return true;
}
}
-
+
/** Class providing filtering for project events. */
private static class Filter implements BusFilter {
/**
@@ -393,20 +392,20 @@
return true;
}
}
-
+
/** Class which's hooks the action to toggle buttons. */
private static class PropertyWatcher implements PropertyChangeListener {
private AbstractButton _target;
-
- /**
- * Standard ctor.
- *
- * @param target Button to update
- */
+
+ /**
+ * Standard ctor.
+ *
+ * @param target Button to update
+ */
public PropertyWatcher(AbstractButton target) {
_target = target;
}
-
+
/**
* Change the Selected stated of the button if the CHECKED
* property is set on the <code>action</code>
1.2 +167 -164
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/event/ElementSelectionEvent.java
Index: ElementSelectionEvent.java
===================================================================
RCS file:
/home/cvs/jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/event/ElementSelectionEvent.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ElementSelectionEvent.java 8 Apr 2001 23:42:13 -0000 1.1
+++ ElementSelectionEvent.java 13 Jan 2003 13:31:24 -0000 1.2
@@ -1,164 +1,167 @@
-/*
- * 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 [EMAIL PROTECTED]
- *
- * 5. Products derived from this software may not be called "Apache"
- * nor may "Apache" appear in their names without prior written
- * permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.apache.tools.ant.gui.event;
-import org.apache.tools.ant.gui.acs.*;
-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.
- *
- * @version $Revision$
- * @author Simeon Fitch
- */
-public class ElementSelectionEvent extends AntEvent {
-
- /** New set of selected elements. */
- private ACSElement[] _selected = null;
-
- /**
- * Standard ctor.
- *
- * @param context application context.
- * @param selected the selected Elements.
- */
- protected ElementSelectionEvent(AppContext context,
- ACSElement[] selected) {
- super(context);
- _selected = selected;
- }
-
- /**
- * Current set of selected elements.
- *
- * @return selected element set.
- */
- public ACSElement[] getSelectedElements() {
- return _selected;
- }
-
-
- /**
- * 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.
- *
- * @param context App context.
- * @param selected The set of selected events. The last elemetn in the
- * array is used to determine the specialization of this
- * that should be returned.
- * @return Event to communicate selection to.
- */
- public static ElementSelectionEvent createEvent(AppContext context,
- ACSElement[] selected) {
- ElementSelectionEvent retval = null;
-
- if(selected != null && selected.length > 0) {
- Class type = selected[selected.length - 1].getClass();
- if(ACSTargetElement.class.isAssignableFrom(type)) {
- retval = new TargetSelectionEvent(context, selected);
- }
- else if(ACSTaskElement.class.isAssignableFrom(type)) {
- retval = new TaskSelectionEvent(context, selected);
- }
- else if(ACSPropertyElement.class.isAssignableFrom(type)) {
- retval = new PropertySelectionEvent(context, selected);
- }
- else if(ACSProjectElement.class.isAssignableFrom(type)) {
- retval = new ProjectSelectedEvent(
- context, (ACSProjectElement) selected[0]);
- }
- else if(ACSDtdDefinedElement.class.isAssignableFrom(type)) {
- retval = new DtdDefinedElementSelectionEvent(
- context, selected);
- }
- else {
- // For elements without a specific event
- // type just send and instance of this.
- retval = new ElementSelectionEvent(context, selected);
- }
- }
- else {
- retval = new NullSelectionEvent(context);
- }
-
- return retval;
- }
-}
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 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 [EMAIL PROTECTED]
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+
+package org.apache.tools.ant.gui.event;
+
+import org.apache.tools.ant.gui.acs.*;
+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.
+ *
+ * @version $Revision$
+ * @author Simeon Fitch, Christoph Wilhelms
+ */
+
+public class ElementSelectionEvent extends AntEvent {
+
+ /** New set of selected elements. */
+ private ACSElement[] _selected = null;
+
+ /**
+ * Standard ctor.
+ *
+ * @param context application context.
+ * @param selected the selected Elements.
+ */
+ protected ElementSelectionEvent(AppContext context, ACSElement[]
selected) {
+ super(context);
+ _selected = selected;
+ }
+
+ /**
+ * Current set of selected elements.
+ *
+ * @return selected element set.
+ */
+ public ACSElement[] getSelectedElements() {
+ return _selected;
+ }
+
+ /**
+ * 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.
+ *
+ * @param context App context.
+ * @param selected The set of selected events. The last elemetn in the
+ * array is used to determine the specialization of this
+ * that should be returned.
+ * @return Event to communicate selection to.
+ */
+ public static ElementSelectionEvent createEvent(AppContext context,
ACSElement[] selected) {
+ ElementSelectionEvent retval = null;
+
+ if(selected != null && selected.length > 0) {
+ Class type = selected[selected.length - 1].getClass();
+ if(ACSTargetElement.class.isAssignableFrom(type)) {
+ retval = new TargetSelectionEvent(context, selected);
+ }
+ else if(ACSTaskElement.class.isAssignableFrom(type)) {
+ retval = new TaskSelectionEvent(context, selected);
+ }
+ else if(ACSPropertyElement.class.isAssignableFrom(type)) {
+ retval = new PropertySelectionEvent(context, selected);
+ }
+ else if(ACSProjectElement.class.isAssignableFrom(type)) {
+ retval = new ProjectSelectedEvent(
+ context, (ACSProjectElement) selected[0]);
+ }
+ else if(ACSDtdDefinedElement.class.isAssignableFrom(type)) {
+ retval = new DtdDefinedElementSelectionEvent(
+ context, selected);
+ }
+ else if(ACSIntrospectedElement.class.isAssignableFrom(type)) {
+ retval = new IntrospectedElementSelectionEvent(
+ context, selected);
+ }
+ else {
+ // For elements without a specific event
+ // type just send and instance of this.
+ retval = new ElementSelectionEvent(context, selected);
+ }
+ }
+ else {
+ retval = new NullSelectionEvent(context);
+ }
+ return retval;
+ }
+}
\ No newline at end of file
1.1
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/event/IntrospectedElementSelectionEvent.java
Index: IntrospectedElementSelectionEvent.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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 [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.gui.event;
import org.apache.tools.ant.gui.core.AppContext;
import org.apache.tools.ant.gui.acs.ACSElement;
import org.apache.tools.ant.gui.acs.ACSIntrospectedElement;
/**
* Event indicating that an introspected element was selected.
*
* @version $Revision: 1.1 $
*
* @author Christoph Wilhelms<a href="mailto:[EMAIL PROTECTED]">[EMAIL
PROTECTED]</a>
*
*/
public class IntrospectedElementSelectionEvent extends ElementSelectionEvent {
/**
* Standard ctor.
*
* @param context application context.
* @param selected the selected Elements.
*/
public IntrospectedElementSelectionEvent(AppContext context, ACSElement[]
selected) {
super(context, selected);
}
/**
* Get the selected properties.
*/
public ACSIntrospectedElement[] getSelectedProperties() {
return (ACSIntrospectedElement[])
getFiltered(ACSIntrospectedElement.class);
}
}
1.6 +3 -3
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/modules/edit/ElementNavigator.java
Index: ElementNavigator.java
===================================================================
RCS file:
/home/cvs/jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/modules/edit/ElementNavigator.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- ElementNavigator.java 10 Jul 2001 19:48:31 -0000 1.5
+++ ElementNavigator.java 13 Jan 2003 13:31:24 -0000 1.6
@@ -1,7 +1,7 @@
/*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 1999, 2000 The Apache Software Foundation. All rights
+ * Copyright (c) 2000 - 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -104,7 +104,7 @@
* Module for navigating build file elemenets.
*
* @version $Revision$
- * @author Simeon Fitch
+ * @author Simeon Fitch, Christoph Wilhelms
*/
public class ElementNavigator extends AntModule {
1.1
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/modules/edit/AttributePropertyEditor.java
Index: AttributePropertyEditor.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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 [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.gui.modules.edit;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import org.apache.tools.ant.gui.customizer.AbstractPropertyEditor;
import org.apache.tools.ant.gui.xml.DOMAttributes;
/**
* Custom property editor for introspected Attributes.
*
* @version $Revision: 1.1 $
* @author Christoph Wilhelms<a href="mailto:[EMAIL PROTECTED]">Christoph
Wilhelms</a>
*/
public class AttributePropertyEditor extends AbstractPropertyEditor {
/** Recommended size for widgets inside a JScrollPane, as communicated
* through the setPreferredScrollableViewportSize() method. */
protected static final Dimension VIEWPORT_SIZE = new Dimension(200, 150);
/** Container. */
private JPanel _widget = null;
/* The current properties being edited. */
private DOMAttributes _attributes = null;
/** The table editor for the properties. */
private JTable _table = null;
/** Displays possible attribute values. */
private JComboBox _combo = new JComboBox();
/**
* Default ctor.
*
*/
public AttributePropertyEditor() {
_widget = new JPanel(new BorderLayout());
_widget.addFocusListener(new FocusHandler(this));
_table = new JTable();
_table.setPreferredScrollableViewportSize(VIEWPORT_SIZE);
JScrollPane scroller = new JScrollPane(_table);
_widget.add(BorderLayout.CENTER, scroller);
}
/**
* Get the child editing component. Uses JComponent so we can have tool
* tips, etc.
*
* @return Child editing component.
*/
protected Component getChild() {
return _widget;
}
/**
* This method is intended for use when generating Java code to set
* the value of the property. It should return a fragment of Java code
* that can be used to initialize a variable with the current property
* value.
* <p>
* Example results are "2", "new Color(127,127,34)", "Color.orange", etc.
*
* @return A fragment of Java code representing an initializer for the
* current value.
*/
public String getJavaInitializationString() {
return "new ACSDtdDefinedAttributes()";
}
/**
* Set (or change) the object that is to be edited. Builtin types such
* as "int" must be wrapped as the corresponding object type such as
* "java.lang.Integer".
*
* @param value The new target object to be edited. Note that this
* object should not be modified by the PropertyEditor, rather
* the PropertyEditor should create a new object to hold any
* modified value.
*/
public void setValue(Object value) {
if(value == null) {
value = new DOMAttributes();
}
if(!(value instanceof DOMAttributes)) {
throw new IllegalArgumentException(
value.getClass().getName() +
" is not of type DOMAttributes.");
}
Object old = _attributes;
_attributes = (DOMAttributes)
((DOMAttributes) value).clone();
TableModel model = new TableModel();
_table.setModel(model);
// Setup the combo box
updateComboBox();
_combo.setEditable(true);
// Set the first column to use the combo box
TableColumn tableColumn = _table.getColumnModel().getColumn(0);
tableColumn.setCellEditor(new DefaultCellEditor(_combo));
// When the combo box is updated, update the table.
/*
_combo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox)e.getSource();
String newSelection = (String)cb.getSelectedItem();
// Should we update the table?
if (newSelection != null && _table.getEditingRow() > 0) {
_table.getModel().setValueAt(newSelection,
_table.getEditingRow(), _table.getEditingColumn() );
}
}
});
*/
_table.clearSelection();
}
/**
* Fills the combobox with possible values
*/
private void updateComboBox() {
_combo.removeAllItems();
ArrayList array = new ArrayList();
String[] valueArray = _attributes.getAttributes();
if (valueArray != null) {
for(int i = 0; i < valueArray.length; i++) {
if (_attributes.getProperty(valueArray[i]) == null) {
array.add(valueArray[i]);
}
}
}
Collections.sort(array);
for(int i = 0; i < array.size(); i++) {
_combo.addItem(array.get(i));
}
}
/**
* @return The value of the property. Builtin types
* such as "int" will be wrapped as the corresponding
* object type such as "java.lang.Integer".
*/
public Object getValue() {
return _attributes;
}
/**
* Set the property value by parsing a given String. May raise
* java.lang.IllegalArgumentException if either the String is
* badly formatted or if this kind of property can't be expressed
* as text.
* @param text The string to be parsed.
*/
public void setAsText(String text) throws IllegalArgumentException {
throw new IllegalArgumentException("Cannot be expressed as a String");
}
/**
* @return The property value as a human editable string.
* <p> Returns null if the value can't be expressed
* as an editable string.
* <p> If a non-null value is returned, then the PropertyEditor should
* be prepared to parse that string back in setAsText().
*/
public String getAsText() {
return null;
}
/** Table model view of the Properties object. */
private class TableModel extends AbstractTableModel {
private static final int NAME = 0;
private static final int VALUE = 1;
private List _keys = null;
public TableModel() {
// We need to store the property keys in an array
// so that the ordering is preserved.
_keys = new ArrayList(_attributes.keySet());
Collections.sort(_keys);
}
/**
* Get the number of rows.
*
* @return Number of rows.
*/
public int getRowCount() {
return _attributes.size() + 1;
}
/**
* Get the number of columns.
*
* @return 2
*/
public int getColumnCount() {
return 2;
}
/**
* Get the editing and display class of the given column.
*
* @return String.class
*/
public Class getColumnClass(int column) {
return String.class;
}
/**
* Get the header name of the column.
*
* @param column Column index.
* @return Name of the column.
*/
public String getColumnName(int column) {
// XXX fix me.
return column == NAME ? "Name" : "Value";
}
/**
* Determine if the given cell is editable.
*
* @param row Cell row.
* @param column Cell column.
* @return true
*/
public boolean isCellEditable(int row, int column) {
return true;
}
/**
* Get the object at the given table coordinates.
*
* @param row Table row.
* @param column Table column.
* @return Object at location, or null if none.
*/
public Object getValueAt(int row, int column) {
if(row < _attributes.size()) {
switch(column) {
case NAME:
return _keys.get(row);
case VALUE:
return _attributes.getProperty((String)_keys.get(row));
}
}
return null;
}
/**
* Set the table value at the given location.
*
* @param value Value to set.
* @param row Row.
* @param column Column.
*/
public void setValueAt(Object value, int row, int column) {
String k = null;
String v = null;
// Get the current key and value.
String currKey = (String) getValueAt(row, NAME);
String currValue = null;
if(currKey != null) {
currValue = _attributes.getProperty(currKey);
}
switch(column) {
case NAME:
k = (String) value;
// Update or add the key value.
if(row < _keys.size()) {
_keys.set(row, k);
}
else {
_keys.add(k);
}
// Remove the old key.
if(currKey != null) {
_attributes.remove(currKey);
}
v = currValue == null ? "" : currValue;
break;
case VALUE:
v = String.valueOf(value);
k = currKey;
// Should we create a temp key?
if( (k == null || k.length() == 0 ) && v.length() != 0 ) {
k = "key-for-" + v;
}
break;
}
// If there is a key, update the list.
if(k != null && k.length() > 0) {
_attributes.setProperty(k, v);
}
// Has something changed?
if( (k != null && v != null) && (currKey != null) &&
(!k.equals(currKey) || !v.equals(currValue) ) ) {
fireTableRowsUpdated(row, row);
// Fire change in outer class.
firePropertyChange(null, _attributes);
// Reset the combobox
updateComboBox();
}
}
}
}
1.2 +19 -6
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/resources/action.properties
Index: action.properties
===================================================================
RCS file:
/home/cvs/jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/resources/action.properties,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- action.properties 8 Apr 2001 23:42:15 -0000 1.1
+++ action.properties 13 Jan 2003 13:31:24 -0000 1.2
@@ -4,7 +4,7 @@
# Declare the list of known actions.
actions=\
new, open, save, saveas, close, exit, about, \
- newTarget, newElement, newProperty, deleteElement, \
+ default, newTarget, newElement, newProperty, deleteElement, \
startBuild, stopBuild, viewConsole
# Configure the decalred actions.
@@ -121,7 +121,7 @@
org.apache.tools.ant.gui.event.PropertySelectionEvent, \
org.apache.tools.ant.gui.event.ProjectClosedEvent, \
org.apache.tools.ant.gui.event.NullSelectionEvent, \
- org.apache.tools.ant.gui.event.DtdDefinedElementSelectionEvent
+ org.apache.tools.ant.gui.event.IntrospectedElementSelectionEvent
newTask.name=New Task
newTask.shortDescription=Create a new task under the selected target
@@ -135,7 +135,12 @@
org.apache.tools.ant.gui.event.TaskSelectionEvent, \
org.apache.tools.ant.gui.event.PropertySelectionEvent, \
org.apache.tools.ant.gui.event.NullSelectionEvent, \
- org.apache.tools.ant.gui.event.DtdDefinedElementSelectionEvent
+ org.apache.tools.ant.gui.event.IntrospectedElementSelectionEvent
+
+property.name=New Property
+property.shortDescription=Create a new property under the selected element
+property.icon=new-property.gif
+property.command=org.apache.tools.ant.gui.command.NewPropertyCmd
newProperty.name=New Property
newProperty.shortDescription=Create a new property under the selected element
@@ -151,11 +156,19 @@
org.apache.tools.ant.gui.event.PropertySelectionEvent, \
org.apache.tools.ant.gui.event.ProjectClosedEvent, \
org.apache.tools.ant.gui.event.NullSelectionEvent, \
- org.apache.tools.ant.gui.event.DtdDefinedElementSelectionEvent
+ org.apache.tools.ant.gui.event.IntrospectedElementSelectionEvent
+
+default.name=New Element
+default.shortDescription=Create a new element under the selected element
+default.icon=new-element.gif
+default.command=org.apache.tools.ant.gui.command.NewElementCmd
+default.enabled=true
+default.hidden=true
+default.popupSeparator=true
newElement.name=New Element
newElement.shortDescription=Create a new element under the selected element
-newElement.icon=default.gif
+newElement.icon=add-element.gif
newElement.command=org.apache.tools.ant.gui.command.NewElementCmd
newElement.enabled=true
newElement.hidden=true
@@ -163,7 +176,7 @@
deleteElement.name=Delete Element
deleteElement.shortDescription=Delete the selected element
-deleteElement.icon=default.gif
+deleteElement.icon=delete.gif
deleteElement.command=org.apache.tools.ant.gui.command.DeleteElementCmd
deleteElement.enabled=true
deleteElement.hidden=true
1.7 +11 -0
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/resources/antidote.properties
Index: antidote.properties
===================================================================
RCS file:
/home/cvs/jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/resources/antidote.properties,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- antidote.properties 4 Jan 2003 10:31:09 -0000 1.6
+++ antidote.properties 13 Jan 2003 13:31:24 -0000 1.7
@@ -109,6 +109,8 @@
org.apache.tools.ant.gui.acs.ACSPropertyElementBeanInfo.name=Name
org.apache.tools.ant.gui.acs.ACSPropertyElementBeanInfo.value=Value
org.apache.tools.ant.gui.acs.ACSPropertyElementBeanInfo.file=File
+org.apache.tools.ant.gui.acs.ACSPropertyElementBeanInfo.namedValues=\
+ Attributes
org.apache.tools.ant.gui.acs.ACSPropertyElementBeanInfo.icon=property.gif
org.apache.tools.ant.gui.acs.ACSTaskElementBeanInfo.beanName=Task
@@ -128,6 +130,15 @@
Attributes
org.apache.tools.ant.gui.acs.ACSDtdDefinedElementBeanInfo.xmlString=XML Code
org.apache.tools.ant.gui.acs.ACSDtdDefinedElementBeanInfo.icon=default.gif
+
+org.apache.tools.ant.gui.acs.ACSIntrospectedElementBeanInfo.beanName=
+org.apache.tools.ant.gui.acs.ACSIntrospectedElementBeanInfo.beanDescription=\
+ A scoped property
+org.apache.tools.ant.gui.acs.ACSIntrospectedElementBeanInfo.taskType=Type
+org.apache.tools.ant.gui.acs.ACSIntrospectedElementBeanInfo.namedValues=\
+ Attributes
+org.apache.tools.ant.gui.acs.ACSIntrospectedElementBeanInfo.xmlString=XML
Code
+org.apache.tools.ant.gui.acs.ACSIntrospectedElementBeanInfo.icon=default.gif
org.apache.tools.ant.gui.command.NewProjectCmd.defName=New Project
org.apache.tools.ant.gui.command.NewTargetCmd.defName=New Target
1.1
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/resources/add-element.gif
<<Binary file>>
1.1
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/resources/delete.gif
<<Binary file>>
1.1
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/resources/new-element.gif
<<Binary file>>
1.1
jakarta-ant-antidote/src/java/org/apache/tools/ant/gui/xml/DOMAttributes.java
Index: DOMAttributes.java
===================================================================
/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 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 [EMAIL PROTECTED]
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.tools.ant.gui.xml;
import java.io.IOException;
import java.util.Properties;
import java.util.Enumeration;
import java.util.Map;
import java.util.Iterator;
/**
* Represents the intospected/refelcted attributes.
*
* @version $Revision: 1.1 $
* @author Christoph Wilhelms<a href="mailto:[EMAIL PROTECTED]">[EMAIL
PROTECTED]</a>
*/
public class DOMAttributes extends Properties {
String[] _elements = null;
/**
* Default constructor
*/
public DOMAttributes() {
this(null);
}
/**
* Constructor
*
* @param element provides information about possible attributes.
*/
public DOMAttributes(Map elements) {
if (elements != null) {
String a[] = new String[elements.keySet().size()];
int i = 0;
Iterator it = elements.keySet().iterator();
while (it.hasNext()) {
a[i] = (String)it.next();
i++;
}
_elements = a;
}
}
/**
* Return the required attributes or null.
*/
public String[] getAttributes() {
if (_elements == null) {
return null;
}
return _elements;
}
/**
* To handle restricted attribs.
*/
public void setAttributes(String[] attribs) {
_elements = attribs;
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>