Hi All, I would like to submit a patch to the ANTIDOTE project which provides a generic ACS element. The elements children are determined by the supplied DTD.
The patch does contain two minor fixes:
1) Allow the root element of the tree to be selected.
2) Select the correct tree element before displaying
the popup menu.
The project.dtd and project-ext.dtd should be placed
in org/apache/tools/ant/gui/acs.
Cheers,
Nick
p.s. there were quite a few new files so I jarred them
to allow posting to the mailing list. please let me know
if I should break the fix into small units.
Index: ACSFactory.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/acs/ACSFac
tory.java,v
retrieving revision 1.8
diff -u -r1.8 ACSFactory.java
--- ACSFactory.java 2001/01/12 20:42:22 1.8
+++ ACSFactory.java 2001/03/27 14:20:11
@@ -60,9 +60,7 @@
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import com.sun.xml.parser.Parser;
-import com.sun.xml.tree.SimpleElementFactory;
-import com.sun.xml.tree.XmlDocument;
-import com.sun.xml.tree.XmlDocumentBuilder;
+import com.sun.xml.tree.*;
import java.util.Properties;
import java.util.Enumeration;
import com.sun.xml.parser.Resolver;
@@ -92,7 +90,7 @@
String name = (String)
enum.nextElement();
// XXX the name of the class needs to
be stored externally.
_elementMap.setProperty(
- name,
"org.apache.tools.ant.gui.acs.ACSTaskElement");
+ name,
"org.apache.tools.ant.gui.acs.ACSDtdDefinedElement");
}
// Then we add/override the local
definitions.
@@ -164,7 +162,6 @@
sax.parse(location.openStream(), null);
doc = builder.getDocument();
-
}
catch(ParserConfigurationException ex) {
ex.printStackTrace();
@@ -235,6 +232,22 @@
return retval;
}
+ /**
+ * Create a new element.
+ *
+ * @param node the Node to assign the property
to.
+ * @param name the new elements type.
+ * @return New, unnamed property.
+ */
+ public ACSElement createElement(ACSElement node,
String name) {
+ ACSElement retval = (ACSElement) node.
+ getOwnerDocument().createElement(name);
+ // XXX fixme.
+ indent(node, 1);
+ node.appendChild(retval);
+ return retval;
+ }
+
/**
* Insert a new line and indentation at the end
of the given
* node in preparation for a new element being
added.
Index: ACSNamedElement.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/acs/ACSNam
edElement.java,v
retrieving revision 1.3
diff -u -r1.3 ACSNamedElement.java
--- ACSNamedElement.java 2001/01/03 14:18:17 1.3
+++ ACSNamedElement.java 2001/03/27 14:20:39
@@ -62,7 +62,7 @@
* @version $Revision: 1.3 $
* @author Simeon Fitch
*/
-public class ACSNamedElement extends
ACSTreeNodeElement {
+public class ACSNamedElement extends
ACSDtdDefinedElement {
/** The 'name' property name. */
public static final String NAME = "name";
/** The discription property name. */
@@ -73,7 +73,6 @@
*
*/
public ACSNamedElement() {
-
}
/**
Index: ACSPropertyElement.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/acs/ACSPro
pertyElement.java,v
retrieving revision 1.4
diff -u -r1.4 ACSPropertyElement.java
--- ACSPropertyElement.java 2001/01/03 14:18:17 1.4
+++ ACSPropertyElement.java 2001/03/27 14:21:24
@@ -61,7 +61,7 @@
* @version $Revision: 1.4 $
* @author Simeon Fitch
*/
-public class ACSPropertyElement extends
ACSTreeNodeElement {
+public class ACSPropertyElement extends
ACSDtdDefinedElement {
/** The 'name' property name. */
public static final String NAME = "name";
/** The 'value' property name. */
Index: ActionManager.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/Actio
nManager.java,v
retrieving revision 1.5
diff -u -r1.5 ActionManager.java
--- ActionManager.java 2001/03/12 19:51:33 1.5
+++ ActionManager.java 2001/03/27 14:23:29
@@ -72,6 +72,8 @@
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 };
/** Externalized resources. */
private ResourceManager _resources = null;
@@ -207,6 +209,12 @@
for(int i = 0; i < _actionIDs.length; i++) {
AntAction action = (AntAction)
_actions.get(_actionIDs[i]);
+
+ // If the action is hidden do not display
it.
+ if(action.isHidden()) {
+ continue;
+ }
+
// If it has an icon, then we add it to
the toolbar.
if(action.getIcon() != null) {
if(action.isPreceededBySeparator()) {
@@ -232,51 +240,78 @@
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.
- *
+ * 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.
+ * 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)
{
+ 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(action != null) {
+
+ // If the ID is not found, use the
default.
+ if (action == null && defaultID != null)
{
+ action = (AntAction)
_actions.get(defaultID);
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);
}
}
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.
*/
- public Command getActionCommand(String actionID,
AppContext context) {
+ public Command getActionCommand(String actionID,
+ 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 =
+ Constructor ctor =
clazz.getConstructor(COMMAND_CTOR_PARAMS);
retval = (Command)
ctor.newInstance(
new Object[] { context });
}
catch(Exception ex) {
- // XXX log me.
- ex.printStackTrace();
+ try {
+ Constructor ctor =
clazz.getConstructor(
+
COMMAND_CTOR_PARAMS_WITH_EVENT);
+ retval = (Command)
ctor.newInstance(
+ new Object[] { context,
event });
+ }
+ catch (Exception ex2) {
+ // XXX log me.
+ ex.printStackTrace();
+ }
}
}
}
Index: AntAction.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/AntAc
tion.java,v
retrieving revision 1.4
diff -u -r1.4 AntAction.java
--- AntAction.java 2001/03/12 19:51:34 1.4
+++ AntAction.java 2001/03/27 14:24:02
@@ -73,6 +73,7 @@
/** Property name for the parent menu item. */
public static final String PARENT_MENU_NAME =
"parentMenuName";
public static final String SEPARATOR =
"separator";
+ public static final String POPUP_SEPARATOR =
"popupSeparator";
public static final String ACCELERATOR =
"accelerator";
public static final String ENABLED = "enabled";
public static final String ENABLE_ON =
"enableOn";
@@ -81,6 +82,7 @@
public static final String CHECKED_TRUE_ON =
"checkedTrueOn";
public static final String CHECKED_FALSE_ON =
"checkedFalseOn";
public static final String COMMAND = "command";
+ public static final String HIDDEN = "hidden";
/** Property resources. */
private ResourceManager _resources = null;
@@ -118,6 +120,8 @@
putValue(SHORT_DESCRIPTION,
getString("shortDescription"));
putValue(PARENT_MENU_NAME,
getString(PARENT_MENU_NAME));
putValue(SEPARATOR, getString(SEPARATOR));
+ putValue(POPUP_SEPARATOR,
getString(POPUP_SEPARATOR));
+ putValue(HIDDEN, getString(HIDDEN));
// Set the default enabled state.
@@ -268,6 +272,28 @@
return (Icon) getValue(SMALL_ICON);
}
+ /**
+ * Determine if a separator should appear before
the action
+ * when the popup menu is created.
+ *
+ * @return True if add separator, false
otherwise.
+ */
+ public boolean isPopupPreceededBySeparator() {
+ return Boolean.valueOf(
+
String.valueOf(getValue(POPUP_SEPARATOR))).booleanValue();
+ }
+
+ /**
+ * Determine if the action is hidden and should
not
+ * be displayed from a button.
+ *
+ * @return True the action is hidden.
+ */
+ public boolean isHidden() {
+ return Boolean.valueOf(
+
String.valueOf(getValue(HIDDEN))).booleanValue();
+ }
+
/**
* Get the accelerator keystroke.
*
Index: EventResponder.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/core/Event
Responder.java,v
retrieving revision 1.2
diff -u -r1.2 EventResponder.java
--- EventResponder.java 2001/01/03 14:18:20 1.2
+++ EventResponder.java 2001/03/27 14:25:08
@@ -113,9 +113,8 @@
*/
public boolean eventPosted(EventObject event)
{
String command =
((ActionEvent)event).getActionCommand();
-
Command cmd =
-
_context.getActions().getActionCommand(command,
_context);
+
_context.getActions().getActionCommand(command,
_context, event);
if(cmd != null) {
cmd.run();
return false;
Index: ElementNavigator.java
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/modules/ed
it/ElementNavigator.java,v
retrieving revision 1.5
diff -u -r1.5 ElementNavigator.java
--- ElementNavigator.java 2001/01/12 19:02:46 1.5
+++ ElementNavigator.java 2001/03/27 14:18:47
@@ -138,6 +138,9 @@
// The project node has changed.
model.fireNodeChanged((ACSElement)event.getSource());
}
+ else if(event instanceof
RefreshDisplayEvent && model != null) {
+ _tree.updateUI();
+ }
else if(event instanceof NewElementEvent
&& model != null) {
ACSElement element =
((NewElementEvent)event).getNewElement();
model.fireNodeAdded(element);
@@ -145,6 +148,9 @@
_selections.setSelectionPath(path);
_tree.scrollPathToVisible(path);
}
+ else if(event instanceof
DeleteElementEvent && model != null) {
+ _tree.updateUI();
+ }
else {
ACSProjectElement project = null;
if(event instanceof
ProjectSelectedEvent) {
@@ -163,11 +169,31 @@
ElementSelectionEvent.createEvent(getContext(), null);
}
else {
- _tree.setModel(new
ElementTreeModel(project));
- _selections = new
ElementTreeSelectionModel();
-
_selections.addTreeSelectionListener(
- new SelectionForwarder());
-
_tree.setSelectionModel(_selections);
+ boolean updateModel = false;
+ TreeModel testModel =
_tree.getModel();
+
+ // Set the model if's not an
ElementTreeModel
+ if (testModel instanceof
ElementTreeModel) {
+ ElementTreeModel etm =
(ElementTreeModel) testModel;
+ ACSProjectElement
currentProject =
+ (ACSProjectElement)
etm.getRoot();
+
+ // Set the model if the
project is wrong
+ if (currentProject !=
project) {
+ updateModel = true;
+ }
+ } else {
+ updateModel = true;
+ }
+
+ // Should we update the tree
model
+ if (updateModel) {
+ _tree.setModel(new
ElementTreeModel(project));
+ _selections = new
ElementTreeSelectionModel();
+
_selections.addTreeSelectionListener(
+ new
SelectionForwarder());
+
_tree.setSelectionModel(_selections);
+ }
}
}
return true;
@@ -195,7 +221,9 @@
return event instanceof
ProjectSelectedEvent ||
event instanceof ProjectClosedEvent
||
event instanceof NewElementEvent ||
- event instanceof PropertyChangeEvent;
+ event instanceof PropertyChangeEvent
||
+ event instanceof DeleteElementEvent
||
+ event instanceof RefreshDisplayEvent;
}
}
@@ -203,11 +231,42 @@
private class PopupHandler extends MouseAdapter {
private void handle(MouseEvent e) {
if(e.isPopupTrigger()) {
- ActionManager mgr =
getContext().getActions();
- JPopupMenu menu = mgr.createPopup(
-
getContext().getResources().getStringArray(
- ElementNavigator.class,
"popupActions"));
- menu.show((JComponent)e.getSource(),
e.getX(), e.getY());
+ Object source = e.getSource();
+ String[] menuStr = null;
+ JTree tree = (JTree) source;
+
+ // Find the selected path.
+ TreePath selPath =
tree.getPathForLocation(
+ e.getX(), e.getY());
+ if (selPath == null) {
+ return;
+ }
+
+ // Update the selection.
+ tree.setSelectionPath(selPath);
+
+ // Find the selected object.
+ Object selObj =
selPath.getLastPathComponent();
+
+ String defaultID = null;
+
+ // Does the item provide its own
menu?
+ if (selObj instanceof
ACSInfoProvider) {
+ ACSInfoProvider ip =
(ACSInfoProvider) selObj;
+ menuStr = ip.getMenuString();
+ defaultID =
ip.getDefaultActionID();
+ } else {
+ // Get the menu from the prop
file.
+ menuStr =
getContext().getResources().getStringArray(
+ ElementNavigator.class,
defaultID);
+ }
+
+ // Should we create a menu?
+ if (menuStr != null && menuStr.length
!= 0) {
+ ActionManager mgr =
getContext().getActions();
+ JPopupMenu menu =
mgr.createPopup(menuStr, defaultID);
+
menu.show((JComponent)e.getSource(), e.getX(),
e.getY());
+ }
}
}
Index: action.properties
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/resources/
action.properties,v
retrieving revision 1.16
diff -u -r1.16 action.properties
--- action.properties 2001/03/12 19:51:42 1.16
+++ action.properties 2001/03/27 14:26:49
@@ -4,7 +4,7 @@
# Declare the list of known actions.
actions=\
new, open, save, saveas, close, exit, about, \
- newTarget, newTask, newProperty \
+ newTarget, newElement, newProperty,
deleteElement, \
startBuild, stopBuild, viewConsole
# Configure the decalred actions.
@@ -120,7 +120,8 @@
org.apache.tools.ant.gui.event.TaskSelectionEvent, \
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.NullSelectionEvent, \
+
org.apache.tools.ant.gui.event.DtdDefinedElementSelectionEvent
newTask.name=New Task
newTask.shortDescription=Create a new task under the
selected target
@@ -133,7 +134,8 @@
org.apache.tools.ant.gui.event.ProjectClosedEvent, \
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.NullSelectionEvent, \
+
org.apache.tools.ant.gui.event.DtdDefinedElementSelectionEvent
newProperty.name=New Property
newProperty.shortDescription=Create a new property
under the selected element
@@ -148,7 +150,24 @@
newProperty.disableOn=\
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.NullSelectionEvent, \
+
org.apache.tools.ant.gui.event.DtdDefinedElementSelectionEvent
+
+newElement.name=New Element
+newElement.shortDescription=Create a new element
under the selected element
+newElement.icon=default.gif
+newElement.command=org.apache.tools.ant.gui.command.NewElementCmd
+newElement.enabled=true
+newElement.hidden=true
+newElement.popupSeparator=true
+
+deleteElement.name=Delete Element
+deleteElement.shortDescription=Delete the selected
element
+deleteElement.icon=default.gif
+deleteElement.command=org.apache.tools.ant.gui.command.DeleteElementCmd
+deleteElement.enabled=true
+deleteElement.hidden=true
+deleteElement.popupSeparator=true
viewConsole.name=console
viewConsole.shortDescription=Displays or hides the
console pane
Index: antidote.properties
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/resources/
antidote.properties,v
retrieving revision 1.23
diff -u -r1.23 antidote.properties
--- antidote.properties 2001/03/08 15:37:50 1.23
+++ antidote.properties 2001/03/27 14:27:20
@@ -108,6 +108,14 @@
org.apache.tools.ant.gui.acs.ACSTaskElementBeanInfo.xmlString=XML
Code
org.apache.tools.ant.gui.acs.ACSTaskElementBeanInfo.icon=task.gif
+org.apache.tools.ant.gui.acs.ACSDtdDefinedElementBeanInfo.beanName=
+org.apache.tools.ant.gui.acs.ACSDtdDefinedElementBeanInfo.beanDescription=\
+ A scoped property
+org.apache.tools.ant.gui.acs.ACSDtdDefinedElementBeanInfo.taskType=Type
+org.apache.tools.ant.gui.acs.ACSDtdDefinedElementBeanInfo.namedValues=\
+ 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.command.NewProjectCmd.defName=New
Project
org.apache.tools.ant.gui.command.NewTargetCmd.defName=New
Target
Index: acs-element.properties
===================================================================
RCS file:
/home/cvspublic/jakarta-ant/src/antidote/org/apache/tools/ant/gui/acs/acs-el
ement.properties,v
retrieving revision 1.3
diff -u -r1.3 acs-element.properties
--- acs-element.properties 2000/12/14 23:03:25 1.3
+++ acs-element.properties 2001/03/27 14:30:12
@@ -3,10 +3,12 @@
#
# The default element
-*Element=org.apache.tools.ant.gui.acs.ACSDefaultElement
+*Element=org.apache.tools.ant.gui.acs.ACSDtdDefinedElement
# Specific elements.
project=org.apache.tools.ant.gui.acs.ACSProjectElement
property=org.apache.tools.ant.gui.acs.ACSPropertyElement
target=org.apache.tools.ant.gui.acs.ACSTargetElement
task=org.apache.tools.ant.gui.acs.ACSTaskElement
+
+
generic-element.jar
Description: Binary data
