You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by an...@apache.org on 2009/10/05 20:40:28 UTC

svn commit: r821956 [2/4] - in /cayenne/main/trunk/framework/cayenne-modeler/src: main/java/org/apache/cayenne/modeler/ main/java/org/apache/cayenne/modeler/action/ main/java/org/apache/cayenne/modeler/dialog/ main/java/org/apache/cayenne/modeler/dialo...

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAction.java Mon Oct  5 18:40:25 2009
@@ -25,6 +25,8 @@
 import java.util.ArrayList;
 
 import javax.swing.KeyStroke;
+import javax.swing.undo.CompoundEdit;
+import javax.swing.undo.UndoableEdit;
 
 import org.apache.cayenne.access.DataDomain;
 import org.apache.cayenne.access.DataNode;
@@ -49,6 +51,8 @@
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.dialog.ConfirmRemoveDialog;
+import org.apache.cayenne.modeler.undo.RemoveCompoundUndoableEdit;
+import org.apache.cayenne.modeler.undo.RemoveUndoableEdit;
 import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.project.ApplicationProject;
 import org.apache.cayenne.project.ProjectPath;
@@ -61,6 +65,8 @@
  */
 public class RemoveAction extends CayenneAction {
 
+    
+
     public static String getActionName() {
         return "Remove";
     }
@@ -113,30 +119,52 @@
         if (mediator.getCurrentObjEntity() != null) {
             if (dialog
                     .shouldDelete("ObjEntity", mediator.getCurrentObjEntity().getName())) {
+                application.getUndoManager().addEdit(
+                        new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator
+                                .getCurrentObjEntity()));
                 removeObjEntity(mediator.getCurrentDataMap(), mediator
                         .getCurrentObjEntity());
             }
         }
         else if (mediator.getCurrentDbEntity() != null) {
             if (dialog.shouldDelete("DbEntity", mediator.getCurrentDbEntity().getName())) {
+                application.getUndoManager().addEdit(
+                        new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator
+                                .getCurrentDbEntity()));
                 removeDbEntity(mediator.getCurrentDataMap(), mediator
                         .getCurrentDbEntity());
             }
         }
         else if (mediator.getCurrentQuery() != null) {
             if (dialog.shouldDelete("query", mediator.getCurrentQuery().getName())) {
+                application.getUndoManager().addEdit(
+                        new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator
+                                .getCurrentQuery()));
                 removeQuery(mediator.getCurrentDataMap(), mediator.getCurrentQuery());
             }
         }
         else if (mediator.getCurrentProcedure() != null) {
             if (dialog
                     .shouldDelete("procedure", mediator.getCurrentProcedure().getName())) {
+
+                application.getUndoManager().addEdit(
+                        new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator
+                                .getCurrentProcedure()));
+
                 removeProcedure(mediator.getCurrentDataMap(), mediator
                         .getCurrentProcedure());
+
             }
-        } 
+        }
         else if (mediator.getCurrentEmbeddable() != null) {
-            if (dialog.shouldDelete("embeddable", mediator.getCurrentEmbeddable().getClassName())) {
+            if (dialog.shouldDelete("embeddable", mediator
+                    .getCurrentEmbeddable()
+                    .getClassName())) {
+
+                application.getUndoManager().addEdit(
+                        new RemoveUndoableEdit(mediator.getCurrentDataMap(), mediator
+                                .getCurrentEmbeddable()));
+
                 removeEmbeddable(mediator.getCurrentDataMap(), mediator
                         .getCurrentEmbeddable());
             }
@@ -146,18 +174,35 @@
 
                 // In context of Data node just remove from Data Node
                 if (mediator.getCurrentDataNode() != null) {
+                    application.getUndoManager().addEdit(
+                            new RemoveUndoableEdit(application, mediator
+                                    .getCurrentDataNode(), mediator.getCurrentDataMap()));
+
                     removeDataMapFromDataNode(mediator.getCurrentDataNode(), mediator
                             .getCurrentDataMap());
+
                 }
                 else {
                     // Not under Data Node, remove completely
+                    application
+                            .getUndoManager()
+                            .addEdit(
+                                    new RemoveUndoableEdit(application, mediator
+                                            .getCurrentDataDomain(), mediator
+                                            .getCurrentDataMap()));
+
                     removeDataMap(mediator.getCurrentDataDomain(), mediator
                             .getCurrentDataMap());
+
                 }
             }
         }
         else if (mediator.getCurrentDataNode() != null) {
             if (dialog.shouldDelete("data node", mediator.getCurrentDataNode().getName())) {
+                application.getUndoManager().addEdit(
+                        new RemoveUndoableEdit(application, mediator
+                                .getCurrentDataDomain(), mediator.getCurrentDataNode()));
+
                 removeDataNode(mediator.getCurrentDataDomain(), mediator
                         .getCurrentDataNode());
             }
@@ -166,21 +211,32 @@
             if (dialog.shouldDelete("data domain", mediator
                     .getCurrentDataDomain()
                     .getName())) {
+
+                application.getUndoManager().addEdit(
+                        new RemoveUndoableEdit(application, mediator
+                                .getCurrentDataDomain()));
+
                 removeDomain(mediator.getCurrentDataDomain());
             }
         }
         else if (mediator.getCurrentPaths() != null) { // multiple deletion
             if (dialog.shouldDelete("selected objects")) {
                 ProjectPath[] paths = mediator.getCurrentPaths();
+
+                CompoundEdit compoundEdit = new RemoveCompoundUndoableEdit();
+
                 for (ProjectPath path : paths) {
-                    removeLastPathComponent(path);
+                    compoundEdit.addEdit(removeLastPathComponent(path));
                 }
+
+                application.getUndoManager().addEdit(compoundEdit);
+
             }
         }
-        
+
     }
 
-    private void removeDomain(DataDomain domain) {
+    public void removeDomain(DataDomain domain) {
         ApplicationProject project = (ApplicationProject) getCurrentProject();
         ProjectController mediator = getProjectController();
 
@@ -191,7 +247,7 @@
                 MapEvent.REMOVE));
     }
 
-    private void removeDataMap(DataDomain domain, DataMap map) {
+    public void removeDataMap(DataDomain domain, DataMap map) {
         ProjectController mediator = getProjectController();
 
         DataMapEvent e = new DataMapEvent(Application.getFrame(), map, MapEvent.REMOVE);
@@ -201,7 +257,7 @@
         mediator.fireDataMapEvent(e);
     }
 
-    private void removeDataNode(DataDomain domain, DataNode node) {
+    public void removeDataNode(DataDomain domain, DataNode node) {
         ProjectController mediator = getProjectController();
 
         DataNodeEvent e = new DataNodeEvent(Application.getFrame(), node, MapEvent.REMOVE);
@@ -214,7 +270,7 @@
     /**
      * Removes current DbEntity from its DataMap and fires "remove" EntityEvent.
      */
-    private void removeDbEntity(DataMap map, DbEntity ent) {
+    public void removeDbEntity(DataMap map, DbEntity ent) {
         ProjectController mediator = getProjectController();
 
         EntityEvent e = new EntityEvent(Application.getFrame(), ent, MapEvent.REMOVE);
@@ -227,7 +283,7 @@
     /**
      * Removes current Query from its DataMap and fires "remove" QueryEvent.
      */
-    private void removeQuery(DataMap map, Query query) {
+    public void removeQuery(DataMap map, Query query) {
         ProjectController mediator = getProjectController();
 
         QueryEvent e = new QueryEvent(Application.getFrame(), query, MapEvent.REMOVE, map);
@@ -240,7 +296,7 @@
     /**
      * Removes current Procedure from its DataMap and fires "remove" ProcedureEvent.
      */
-    private void removeProcedure(DataMap map, Procedure procedure) {
+    public void removeProcedure(DataMap map, Procedure procedure) {
         ProjectController mediator = getProjectController();
 
         ProcedureEvent e = new ProcedureEvent(
@@ -256,7 +312,7 @@
     /**
      * Removes current object entity from its DataMap.
      */
-    private void removeObjEntity(DataMap map, ObjEntity entity) {
+    public void removeObjEntity(DataMap map, ObjEntity entity) {
         ProjectController mediator = getProjectController();
 
         EntityEvent e = new EntityEvent(Application.getFrame(), entity, MapEvent.REMOVE);
@@ -270,29 +326,34 @@
 
         // clone to be able to remove within iterator...
         for (Query query : new ArrayList<Query>(map.getQueries())) {
-            AbstractQuery next = (AbstractQuery) query;
-            Object root = next.getRoot();
-
-            if (root == entity
-                    || (root instanceof String && root
-                            .toString()
-                            .equals(entity.getName()))) {
-                removeQuery(map, next);
+            if (query instanceof AbstractQuery) {
+                AbstractQuery next = (AbstractQuery) query;
+                Object root = next.getRoot();
+    
+                if (root == entity
+                        || (root instanceof String && root
+                                .toString()
+                                .equals(entity.getName()))) {
+                    removeQuery(map, next);
+                }
             }
         }
     }
 
-    private void removeEmbeddable(DataMap map, Embeddable embeddable) {
+    public void removeEmbeddable(DataMap map, Embeddable embeddable) {
         ProjectController mediator = getProjectController();
 
-        EmbeddableEvent e = new EmbeddableEvent(Application.getFrame(), embeddable, MapEvent.REMOVE);
+        EmbeddableEvent e = new EmbeddableEvent(
+                Application.getFrame(),
+                embeddable,
+                MapEvent.REMOVE);
         e.setDomain(mediator.findDomain(map));
-        
+
         map.removeEmbeddable(embeddable.getClassName());
         mediator.fireEmbeddableEvent(e, map);
     }
-    
-    private void removeDataMapFromDataNode(DataNode node, DataMap map) {
+
+    public void removeDataMapFromDataNode(DataNode node, DataMap map) {
         ProjectController mediator = getProjectController();
 
         DataNodeEvent e = new DataNodeEvent(Application.getFrame(), node);
@@ -353,39 +414,76 @@
     /**
      * Removes an object, depending on its type
      */
-    private void removeLastPathComponent(ProjectPath path) {
-        
+    private UndoableEdit removeLastPathComponent(ProjectPath path) {
         Object lastObject = path.getObject();
 
+        UndoableEdit undo = null;
+
         if (lastObject instanceof DataDomain) {
+            undo = new RemoveUndoableEdit(application, (DataDomain) lastObject);
             removeDomain((DataDomain) lastObject);
         }
         else if (lastObject instanceof DataMap) {
             Object parent = path.getObjectParent();
 
-            if (parent instanceof DataDomain)
+            if (parent instanceof DataDomain) {
+                undo = new RemoveUndoableEdit(
+                        application,
+                        (DataDomain) parent,
+                        (DataMap) lastObject);
+
                 removeDataMap((DataDomain) parent, (DataMap) lastObject);
-            else
-                // if(parent instanceof DataNode)
+            }
+            else { // if(parent instanceof DataNode)
+                undo = new RemoveUndoableEdit(
+                        application,
+                        (DataNode) parent,
+                        (DataMap) lastObject);
+
                 removeDataMapFromDataNode((DataNode) parent, (DataMap) lastObject);
+            }
         }
         else if (lastObject instanceof DataNode) {
+            undo = new RemoveUndoableEdit(application, (DataDomain) path
+                    .getObjectParent(), (DataNode) lastObject);
+
             removeDataNode((DataDomain) path.getObjectParent(), (DataNode) lastObject);
         }
         else if (lastObject instanceof DbEntity) {
+            undo = new RemoveUndoableEdit(
+                    (DataMap) path.getObjectParent(),
+                    (DbEntity) lastObject);
+
             removeDbEntity((DataMap) path.getObjectParent(), (DbEntity) lastObject);
         }
         else if (lastObject instanceof ObjEntity) {
+            undo = new RemoveUndoableEdit(
+                    (DataMap) path.getObjectParent(),
+                    (ObjEntity) lastObject);
+
             removeObjEntity((DataMap) path.getObjectParent(), (ObjEntity) lastObject);
         }
         else if (lastObject instanceof Query) {
+            undo = new RemoveUndoableEdit(
+                    (DataMap) path.getObjectParent(),
+                    (Query) lastObject);
+
             removeQuery((DataMap) path.getObjectParent(), (Query) lastObject);
         }
         else if (lastObject instanceof Procedure) {
+            undo = new RemoveUndoableEdit(
+                    (DataMap) path.getObjectParent(),
+                    (Procedure) lastObject);
+
             removeProcedure((DataMap) path.getObjectParent(), (Procedure) lastObject);
         }
         else if (lastObject instanceof Embeddable) {
+            undo = new RemoveUndoableEdit(
+                    (DataMap) path.getObjectParent(),
+                    (Embeddable) lastObject);
             removeEmbeddable((DataMap) path.getObjectParent(), (Embeddable) lastObject);
         }
+
+        return undo;
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveAttributeAction.java Mon Oct  5 18:40:25 2009
@@ -22,6 +22,7 @@
 import java.awt.event.ActionEvent;
 
 import org.apache.cayenne.map.Attribute;
+import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbAttribute;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.Embeddable;
@@ -34,6 +35,7 @@
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.dialog.ConfirmRemoveDialog;
+import org.apache.cayenne.modeler.undo.RemoveAttributeUndoableEdit;
 import org.apache.cayenne.modeler.util.ProjectUtil;
 import org.apache.cayenne.project.ProjectPath;
 
@@ -43,6 +45,8 @@
  */
 public class RemoveAttributeAction extends RemoveAction implements MultipleObjectsAction {
 
+    
+
     private final static String ACTION_NAME = "Remove Attribute";
 
     /**
@@ -78,8 +82,10 @@
     @Override
     public void performAction(ActionEvent e, boolean allowAsking) {
         ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
+        ProjectController mediator = getProjectController();
 
         EmbeddableAttribute[] embAttrs = getProjectController().getCurrentEmbAttrs();
+
         ObjAttribute[] attrs = getProjectController().getCurrentObjAttributes();
 
         if (embAttrs != null && embAttrs.length > 0) {
@@ -88,14 +94,35 @@
                     embAttrs[0].getName()))
                     || (embAttrs.length > 1 && dialog
                             .shouldDelete("selected EmbAttributes"))) {
-                removeEmbeddableAttributes();
+
+                Embeddable embeddable = mediator.getCurrentEmbeddable();
+
+                EmbeddableAttribute[] eAttrs = getProjectController()
+                        .getCurrentEmbAttrs();
+
+                application.getUndoManager().addEdit(
+                        new RemoveAttributeUndoableEdit(embeddable, eAttrs));
+
+                removeEmbeddableAttributes(embeddable, eAttrs);
+
             }
         }
         else if (attrs != null && attrs.length > 0) {
             if ((attrs.length == 1 && dialog.shouldDelete("ObjAttribute", attrs[0]
                     .getName()))
                     || (attrs.length > 1 && dialog.shouldDelete("selected ObjAttributes"))) {
-                removeObjAttributes();
+
+                ObjEntity entity = mediator.getCurrentObjEntity();
+                ObjAttribute[] attribs = mediator.getCurrentObjAttributes();
+
+                application.getUndoManager().addEdit(
+                        new RemoveAttributeUndoableEdit(
+                                mediator.getCurrentDataDomain(),
+                                mediator.getCurrentDataMap(),
+                                entity,
+                                attribs));
+
+                removeObjAttributes(entity, attribs);
             }
         }
         else {
@@ -105,16 +132,27 @@
                         .getName()))
                         || (dbAttrs.length > 1 && dialog
                                 .shouldDelete("selected DbAttributes"))) {
-                    removeDbAttributes();
+
+                    DbEntity entity = mediator.getCurrentDbEntity();
+                    DbAttribute[] attribs = mediator.getCurrentDbAttributes();
+
+                    ProjectPath[] paths = getProjectController().getCurrentPaths();
+
+                    application.getUndoManager().addEdit(
+                            new RemoveAttributeUndoableEdit(
+                                    mediator.getCurrentDataDomain(),
+                                    mediator.getCurrentDataMap(),
+                                    entity,
+                                    attribs));
+
+                    removeDbAttributes(mediator.getCurrentDataMap(), entity, attribs);
                 }
             }
         }
     }
 
-    protected void removeDbAttributes() {
+    public void removeDbAttributes(DataMap dataMap, DbEntity entity, DbAttribute[] attribs) {
         ProjectController mediator = getProjectController();
-        DbEntity entity = mediator.getCurrentDbEntity();
-        DbAttribute[] attribs = mediator.getCurrentDbAttributes();
 
         for (DbAttribute attrib : attribs) {
             entity.removeAttribute(attrib.getName());
@@ -124,17 +162,15 @@
                     attrib,
                     entity,
                     MapEvent.REMOVE);
+
             mediator.fireDbAttributeEvent(e);
         }
 
-        ProjectUtil.cleanObjMappings(mediator.getCurrentDataMap());
+        ProjectUtil.cleanObjMappings(dataMap);
     }
 
-    protected void removeObjAttributes() {
+    public void removeObjAttributes(ObjEntity entity, ObjAttribute[] attribs) {
         ProjectController mediator = getProjectController();
-        ObjEntity entity = mediator.getCurrentObjEntity();
-
-        ObjAttribute[] attribs = mediator.getCurrentObjAttributes();
 
         for (ObjAttribute attrib : attribs) {
             entity.removeAttribute(attrib.getName());
@@ -147,11 +183,10 @@
         }
     }
 
-    protected void removeEmbeddableAttributes() {
+    public void removeEmbeddableAttributes(
+            Embeddable embeddable,
+            EmbeddableAttribute[] attrs) {
         ProjectController mediator = getProjectController();
-        Embeddable embeddable = mediator.getCurrentEmbeddable();
-
-        EmbeddableAttribute[] attrs = getProjectController().getCurrentEmbAttrs();
 
         for (EmbeddableAttribute attrib : attrs) {
             embeddable.removeAttribute(attrib.getName());

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveCallbackMethodAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveCallbackMethodAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveCallbackMethodAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveCallbackMethodAction.java Mon Oct  5 18:40:25 2009
@@ -28,6 +28,9 @@
  * @version 1.0 Oct 30, 2007
  */
 public class RemoveCallbackMethodAction extends AbstractRemoveCallbackMethodAction {
+    
+    
+
     /**
      * unique action name
      */

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerAction.java Mon Oct  5 18:40:25 2009
@@ -33,6 +33,8 @@
  * @version 1.0 Oct 30, 2007
  */
 public class RemoveEntityListenerAction extends RemoveAction {
+    
+    
     /**
      * unique action name
      */
@@ -73,15 +75,17 @@
 
             if (dialog.shouldDelete("entity listener", getProjectController()
                     .getCurrentListenerClass())) {
-                removeEntityListener();
+                
+                ObjEntity objEnt = getProjectController().getCurrentObjEntity();
+                String listenerClass = getProjectController().getCurrentListenerClass();
+                
+                removeEntityListener(objEnt, listenerClass);
             }
         }
     }
 
-    protected void removeEntityListener() {
-        ObjEntity objEnt = getProjectController().getCurrentObjEntity();
-        String listenerClass = getProjectController().getCurrentListenerClass();
-
+    public void removeEntityListener(ObjEntity objEnt, String listenerClass) {
+      
         objEnt.removeEntityListener(listenerClass);
 
         getProjectController().fireEntityListenerEvent(

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerForDataMapAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerForDataMapAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerForDataMapAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveEntityListenerForDataMapAction.java Mon Oct  5 18:40:25 2009
@@ -20,6 +20,7 @@
 
 import java.awt.event.ActionEvent;
 
+import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.dialog.ConfirmRemoveDialog;
@@ -32,6 +33,8 @@
  * @version 1.0 Oct 30, 2007
  */
 public class RemoveEntityListenerForDataMapAction extends RemoveAction {
+    
+    
     /**
      * unique action name
      */
@@ -70,15 +73,16 @@
         if (getProjectController().getCurrentListenerClass() != null) {
             if (dialog.shouldDelete("entity listener", getProjectController()
                     .getCurrentListenerClass())) {
-                removeDefaultEntityListener();
+                
+                String listenerClass = getProjectController().getCurrentListenerClass();
+                removeEntityListener(getProjectController().getCurrentDataMap(), listenerClass);
             }
         }
     }
 
-    protected void removeDefaultEntityListener() {
-        String listenerClass = getProjectController().getCurrentListenerClass();
+    public void removeEntityListener(DataMap map, String listenerClass) {
         if (listenerClass != null) {
-            getProjectController().getCurrentDataMap().removeDefaultEntityListener(listenerClass);
+            map.removeDefaultEntityListener(listenerClass);
 
             getProjectController().fireEntityListenerEvent(
                     new EntityListenerEvent(

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveProcedureParameterAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveProcedureParameterAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveProcedureParameterAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveProcedureParameterAction.java Mon Oct  5 18:40:25 2009
@@ -17,11 +17,11 @@
  *  under the License.
  ****************************************************************/
 
-
 package org.apache.cayenne.modeler.action;
 
 import java.awt.event.ActionEvent;
 
+import org.apache.cayenne.map.Procedure;
 import org.apache.cayenne.map.ProcedureParameter;
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.map.event.ProcedureParameterEvent;
@@ -37,12 +37,12 @@
 public class RemoveProcedureParameterAction extends RemoveAction {
 
     private final static String ACTION_NAME = "Remove Parameter";
-    
+
     /**
      * Name of action if multiple rels are selected
      */
     private final static String ACTION_NAME_MULTIPLE = "Remove Parameters";
-    
+
     public static String getActionName(boolean multiple) {
         return multiple ? ACTION_NAME_MULTIPLE : ACTION_NAME;
     }
@@ -72,10 +72,14 @@
     public void performAction(ActionEvent e, boolean allowAsking) {
         ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
-        ProcedureParameter[] params = getProjectController().getCurrentProcedureParameters(); 
+        ProcedureParameter[] params = getProjectController()
+                .getCurrentProcedureParameters();
         if (params.length > 0) {
-            if ((params.length == 1 && dialog.shouldDelete("procedure parameter", params[0].getName()))
-               || (params.length > 1 && dialog.shouldDelete("selected procedure parameters"))) {
+            if ((params.length == 1 && dialog.shouldDelete(
+                    "procedure parameter",
+                    params[0].getName()))
+                    || (params.length > 1 && dialog
+                            .shouldDelete("selected procedure parameters"))) {
                 removeProcedureParameters();
             }
         }
@@ -84,14 +88,20 @@
     protected void removeProcedureParameters() {
         ProjectController mediator = getProjectController();
         ProcedureParameter[] parameters = mediator.getCurrentProcedureParameters();
+        removeProcedureParameters(mediator.getCurrentProcedure(), parameters);
+    }
+
+    public void removeProcedureParameters(
+            Procedure procedure,
+            ProcedureParameter[] parameters) {
+        ProjectController mediator = getProjectController();
 
         for (ProcedureParameter parameter : parameters) {
-            mediator.getCurrentProcedure().removeCallParameter(parameter.getName());
 
-            ProcedureParameterEvent e = new ProcedureParameterEvent(
-                    Application.getFrame(),
-                    parameter,
-                    MapEvent.REMOVE);
+            procedure.removeCallParameter(parameter.getName());
+
+            ProcedureParameterEvent e = new ProcedureParameterEvent(Application
+                    .getFrame(), parameter, MapEvent.REMOVE);
 
             mediator.fireProcedureParameterEvent(e);
         }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveRelationshipAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveRelationshipAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveRelationshipAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RemoveRelationshipAction.java Mon Oct  5 18:40:25 2009
@@ -17,7 +17,6 @@
  *  under the License.
  ****************************************************************/
 
-
 package org.apache.cayenne.modeler.action;
 
 import java.awt.event.ActionEvent;
@@ -32,101 +31,108 @@
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.dialog.ConfirmRemoveDialog;
+import org.apache.cayenne.modeler.undo.RemoveRelationshipUndoableEdit;
 import org.apache.cayenne.modeler.util.ProjectUtil;
 import org.apache.cayenne.project.ProjectPath;
 
 /**
- * Removes currently selected relationship from either the DbEntity or ObjEntity.
+ * Removes currently selected relationship from either the DbEntity or
+ * ObjEntity.
  * 
  */
-public class RemoveRelationshipAction extends RemoveAction implements MultipleObjectsAction {
+public class RemoveRelationshipAction extends RemoveAction implements
+		MultipleObjectsAction {
+
+	
+
+	private final static String ACTION_NAME = "Remove Relationship";
+
+	/**
+	 * Name of action if multiple rels are selected
+	 */
+	private final static String ACTION_NAME_MULTIPLE = "Remove Relationships";
+
+	public static String getActionName() {
+		return ACTION_NAME;
+	}
+
+	public String getActionName(boolean multiple) {
+		return multiple ? ACTION_NAME_MULTIPLE : ACTION_NAME;
+	}
+
+	public RemoveRelationshipAction(Application application) {
+		super(ACTION_NAME, application);
+	}
+
+	/**
+	 * Returns <code>true</code> if last object in the path contains a removable
+	 * relationship.
+	 */
+	@Override
+	public boolean enableForPath(ProjectPath path) {
+		if (path == null) {
+			return false;
+		}
+
+		return path.getObject() instanceof Relationship;
+	}
+
+	@Override
+	public void performAction(ActionEvent e, boolean allowAsking) {
+		ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
+		ProjectController mediator = getProjectController();
+
+		ObjRelationship[] rels = getProjectController()
+				.getCurrentObjRelationships();
+		if (rels != null && rels.length > 0) {
+			if ((rels.length == 1 && dialog.shouldDelete("ObjRelationship",
+					rels[0].getName()))
+					|| (rels.length > 1 && dialog
+							.shouldDelete("selected ObjRelationships"))) {
+				ObjEntity entity = mediator.getCurrentObjEntity();
+				removeObjRelationships(entity, rels);
+				Application.getInstance().getUndoManager().addEdit(
+						new RemoveRelationshipUndoableEdit(entity, rels));
+			}
+		} else {
+			DbRelationship[] dbRels = getProjectController()
+					.getCurrentDbRelationships();
+			if (dbRels != null && dbRels.length > 0) {
+				if ((dbRels.length == 1 && dialog.shouldDelete(
+						"DbRelationship", dbRels[0].getName()))
+						|| (dbRels.length > 1 && dialog
+								.shouldDelete("selected DbRelationships"))) {
+					DbEntity entity = mediator.getCurrentDbEntity();
+					removeDbRelationships(entity, dbRels);
+					Application.getInstance().getUndoManager().addEdit(
+							new RemoveRelationshipUndoableEdit(entity, dbRels));
+				}
+			}
+		}
+	}
+
+	public void removeObjRelationships(ObjEntity entity, ObjRelationship[] rels) {
+		ProjectController mediator = getProjectController();
+
+		for (ObjRelationship rel : rels) {
+			entity.removeRelationship(rel.getName());
+			RelationshipEvent e = new RelationshipEvent(Application.getFrame(),
+					rel, entity, MapEvent.REMOVE);
+			mediator.fireObjRelationshipEvent(e);
+		}
+	}
+
+	public void removeDbRelationships(DbEntity entity, DbRelationship[] rels) {
+		ProjectController mediator = getProjectController();
+
+		for (DbRelationship rel : rels) {
+			entity.removeRelationship(rel.getName());
+
+			RelationshipEvent e = new RelationshipEvent(Application.getFrame(),
+					rel, entity, MapEvent.REMOVE);
+			mediator.fireDbRelationshipEvent(e);
+		}
 
-    private final static String ACTION_NAME = "Remove Relationship";
-    
-    /**
-     * Name of action if multiple rels are selected
-     */
-    private final static String ACTION_NAME_MULTIPLE = "Remove Relationships";
-
-    public static String getActionName() {
-        return ACTION_NAME;
-    }
-    
-    public String getActionName(boolean multiple) {
-        return multiple ? ACTION_NAME_MULTIPLE : ACTION_NAME;
-    }
-
-    public RemoveRelationshipAction(Application application) {
-        super(ACTION_NAME, application);
-    }
-
-    /**
-     * Returns <code>true</code> if last object in the path contains a removable
-     * relationship.
-     */
-    @Override
-    public boolean enableForPath(ProjectPath path) {
-        if (path == null) {
-            return false;
-        }
-
-        return path.getObject() instanceof Relationship;
-    }
-
-    @Override
-    public void performAction(ActionEvent e, boolean allowAsking) {
-        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
-
-        ObjRelationship[] rels = getProjectController().getCurrentObjRelationships();
-        if (rels != null && rels.length > 0) {
-            if ((rels.length == 1 && dialog.shouldDelete("ObjRelationship", rels[0].getName()))
-                || (rels.length > 1 && dialog.shouldDelete("selected ObjRelationships"))) {
-                removeObjRelationships();
-            }
-        }
-        else {
-            DbRelationship[] dbRels = getProjectController().getCurrentDbRelationships();
-            if (dbRels != null && dbRels.length > 0) {
-                if ((dbRels.length == 1 && dialog.shouldDelete("DbRelationship", dbRels[0].getName()))
-                    || (dbRels.length > 1 && dialog.shouldDelete("selected DbRelationships"))) {
-                    removeDbRelationships();
-                }
-            }            
-        }
-    }
-
-    protected void removeObjRelationships() {
-        ProjectController mediator = getProjectController();
-        ObjEntity entity = mediator.getCurrentObjEntity();
-        ObjRelationship[] rels = mediator.getCurrentObjRelationships();
-
-        for (ObjRelationship rel : rels) {
-            entity.removeRelationship(rel.getName());
-            RelationshipEvent e = new RelationshipEvent(
-                    Application.getFrame(),
-                    rel,
-                    entity,
-                    MapEvent.REMOVE);
-            mediator.fireObjRelationshipEvent(e);
-        }
-    }
-
-    protected void removeDbRelationships() {
-        ProjectController mediator = getProjectController();
-        DbEntity entity = mediator.getCurrentDbEntity();
-        DbRelationship[] rels = mediator.getCurrentDbRelationships();
-
-        for (DbRelationship rel : rels) {
-            entity.removeRelationship(rel.getName());
-
-            RelationshipEvent e = new RelationshipEvent(
-                    Application.getFrame(),
-                    rel,
-                    entity,
-                    MapEvent.REMOVE);
-            mediator.fireDbRelationshipEvent(e);
-        }
-        
-        ProjectUtil.cleanObjMappings(mediator.getCurrentDataMap());
-    }
+		ProjectUtil.cleanObjMappings(mediator.getCurrentDataMap());
+	}
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RevertAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RevertAction.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RevertAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/RevertAction.java Mon Oct  5 18:40:25 2009
@@ -32,7 +32,9 @@
  */
 public class RevertAction extends CayenneAction {
 
-    public static String getActionName() {
+    
+
+	public static String getActionName() {
         return "Revert";
     }
 
@@ -72,5 +74,7 @@
                     .getAction(NewProjectAction.getActionName())
                     .performAction(e);
         }
+        
+        application.getUndoManager().discardAllEdits();
     }
 }

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/UndoAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/UndoAction.java?rev=821956&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/UndoAction.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/UndoAction.java Mon Oct  5 18:40:25 2009
@@ -0,0 +1,59 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+package org.apache.cayenne.modeler.action;
+
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+
+import javax.swing.KeyStroke;
+
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.util.CayenneAction;
+
+public class UndoAction extends CayenneAction {
+
+    @Override
+    public boolean isAlwaysOn() {
+        return false;
+    }
+
+    public static String getActionName() {
+        return "Undo";
+    }
+    
+    public UndoAction(Application application) {
+        super(getActionName(), application);
+    }
+    
+    @Override
+    public KeyStroke getAcceleratorKey() {
+        return KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
+    }
+    
+    @Override
+    public String getIconName() {
+        return "icon-undo.gif";
+    }
+
+    @Override
+    public void performAction(ActionEvent e) {
+        application.getUndoManager().undo();
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/AboutDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/AboutDialog.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/AboutDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/AboutDialog.java Mon Oct  5 18:40:25 2009
@@ -50,7 +50,7 @@
 // triad, though it might be beneficial to use strings file
 public class AboutDialog extends JFrame implements FocusListener, KeyListener, MouseListener {
 
-    private static final long serialVersionUID = 1L;
+    
     private JLabel license, info;
     private static String infoString;
     private static ImageIcon logoImage;

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/FindDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/FindDialog.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/FindDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/FindDialog.java Mon Oct  5 18:40:25 2009
@@ -47,6 +47,7 @@
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.ObjRelationship;
 import org.apache.cayenne.map.Relationship;
+import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.CayenneModelerFrame;
 import org.apache.cayenne.modeler.ProjectTreeModel;
 import org.apache.cayenne.modeler.editor.EditorView;
@@ -161,8 +162,11 @@
         table.getSelectionModel().setSelectionInterval(0, 0);
     }
 
-    public static void jumpToResult(Object[] path, EditorView editor) {
-
+    public static void jumpToResult(Object[] path) {
+    	EditorView editor = ((CayenneModelerFrame) Application.getInstance()
+                .getFrameController()
+                .getView()).getView();
+    	
         if (path[path.length - 1] instanceof Entity) {
 
             /** Make selection in a project tree, open correspondent entity tab */
@@ -239,10 +243,6 @@
 
     private class JumpToResultActionListener implements MouseListener {
 
-        private EditorView editor = ((CayenneModelerFrame) application
-                .getFrameController()
-                .getView()).getView();
-
         public void mouseClicked(MouseEvent e) {
             JTable table = (JTable) e.getSource();
             Integer selectedLine = table.getSelectionModel().getLeadSelectionIndex();
@@ -250,7 +250,7 @@
             Integer index = (Integer) FindDialogView.getLabelAndObjectIndex().get(label);
 
             Object[] path = (Object[]) paths.get(index);
-            jumpToResult(path, editor);
+            jumpToResult(path);
         }
 
         public void mouseEntered(MouseEvent e) {
@@ -268,10 +268,6 @@
 
     private class JumpToResultsKeyListener implements KeyListener {
 
-        private EditorView editor = ((CayenneModelerFrame) application
-                .getFrameController()
-                .getView()).getView();
-
         public void keyPressed(KeyEvent e) {
 
             if (e.getKeyCode() == KeyEvent.VK_ENTER) {
@@ -283,7 +279,7 @@
                         label);
 
                 Object[] path = (Object[]) paths.get(index);
-                jumpToResult(path, editor);
+                jumpToResult(path);
             }
         }
 

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java Mon Oct  5 18:40:25 2009
@@ -27,7 +27,6 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 
 import javax.swing.JButton;
@@ -48,6 +47,7 @@
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.map.event.RelationshipEvent;
 import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.undo.RelationshipUndoableEdit;
 import org.apache.cayenne.modeler.util.CayenneDialog;
 import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
@@ -67,342 +67,390 @@
  */
 public class ResolveDbRelationshipDialog extends CayenneDialog {
 
-    protected DbRelationship relationship;
-    protected DbRelationship reverseRelationship;
-
-    protected JTextField name;
-    protected JTextField reverseName;
-    protected CayenneTable table;
-    protected JButton addButton;
-    protected JButton removeButton;
-    protected JButton saveButton;
-    protected JButton cancelButton;
-
-    private boolean cancelPressed;
-
-    public ResolveDbRelationshipDialog(DbRelationship relationship) {
-
-        super(Application.getFrame(), "", true);
-
-        initView();
-        initController();
-        initWithModel(relationship);
-
-        this.pack();
-        this.centerWindow();
-    }
-
-    /**
-     * Creates graphical components.
-     */
-    private void initView() {
-
-        // create widgets
-        name = new JTextField(25);
-        reverseName = new JTextField(25);
-        addButton = new JButton("Add");
-        removeButton = new JButton("Remove");
-        saveButton = new JButton("Done");
-        cancelButton = new JButton("Cancel");
-
-        table = new AttributeTable();
-        table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-
-        // assemble
-        getContentPane().setLayout(new BorderLayout());
-
-        CellConstraints cc = new CellConstraints();
-        PanelBuilder builder = new PanelBuilder(
-                new FormLayout(
-                        "right:max(50dlu;pref), 3dlu, fill:min(150dlu;pref), 3dlu, fill:min(50dlu;pref)",
-                        "p, 3dlu, p, 3dlu, p, 9dlu, p, 3dlu, top:14dlu, 3dlu, top:p:grow"));
-        builder.setDefaultDialogBorder();
-
-        builder.addSeparator("DbRelationship Information", cc.xywh(1, 1, 5, 1));
-        builder.addLabel("Relationship:", cc.xy(1, 3));
-        builder.add(name, cc.xywh(3, 3, 1, 1));
-        builder.addLabel("Reverse Relationship", cc.xy(1, 5));
-        builder.add(reverseName, cc.xywh(3, 5, 1, 1));
-
-        builder.addSeparator("Joins", cc.xywh(1, 7, 5, 1));
-        builder.add(new JScrollPane(table), cc.xywh(1, 9, 3, 3, "fill, fill"));
-
-        JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEADING));
-        buttons.add(addButton);
-        buttons.add(removeButton);
-
-        builder.add(buttons, cc.xywh(5, 9, 1, 3));
-
-        getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
-        getContentPane().add(PanelFactory.createButtonPanel(new JButton[] {
-                saveButton, cancelButton
-        }), BorderLayout.SOUTH);
-    }
-
-    private void initWithModel(DbRelationship aRelationship) {
-        // sanity check
-        if (aRelationship.getSourceEntity() == null) {
-            throw new CayenneRuntimeException("Null source entity: " + aRelationship);
-        }
-
-        if (aRelationship.getTargetEntity() == null) {
-            throw new CayenneRuntimeException("Null target entity: " + aRelationship);
-        }
-
-        if (aRelationship.getSourceEntity().getDataMap() == null) {
-            throw new CayenneRuntimeException("Null DataMap: "
-                    + aRelationship.getSourceEntity());
-        }
-
-        // Once assigned, can reference relationship directly. Would it be
-        // OK to assign relationship at the very top of this method?
-        relationship = aRelationship;
-        reverseRelationship = relationship.getReverseRelationship();
-
-        // init UI components
-        setTitle("DbRelationship Info: "
-                + relationship.getSourceEntity().getName()
-                + " to "
-                + relationship.getTargetEntityName());
-
-        table.setModel(new DbJoinTableModel(relationship, getMediator(), this, true));
-        TableColumn sourceColumn = table.getColumnModel().getColumn(
-                DbJoinTableModel.SOURCE);
-        sourceColumn.setMinWidth(150);
-        JComboBox comboBox = CayenneWidgetFactory.createComboBox(ModelerUtil
-                .getDbAttributeNames(getMediator(), (DbEntity) relationship
-                        .getSourceEntity()), true);
-        
-        AutoCompletion.enable(comboBox);
-        sourceColumn.setCellEditor(CayenneWidgetFactory.createCellEditor(comboBox));
-
-        TableColumn targetColumn = table.getColumnModel().getColumn(
-                DbJoinTableModel.TARGET);
-        targetColumn.setMinWidth(150);
-        comboBox = CayenneWidgetFactory.createComboBox(ModelerUtil.getDbAttributeNames(
-                getMediator(),
-                (DbEntity) relationship.getTargetEntity()), true);
-        AutoCompletion.enable(comboBox);
-        
-        targetColumn.setCellEditor(CayenneWidgetFactory.createCellEditor(comboBox));
-
-        if (reverseRelationship != null) {
-            reverseName.setText(reverseRelationship.getName());
-        }
-
-        name.setText(relationship.getName());
-    }
-
-    private void initController() {
-        addButton.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                DbJoinTableModel model = (DbJoinTableModel) table.getModel();
-                model.addRow(new DbJoin(relationship));
-                table.select(model.getRowCount() - 1);
-            }
-        });
-
-        removeButton.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                DbJoinTableModel model = (DbJoinTableModel) table.getModel();
-                stopEditing();
-                int row = table.getSelectedRow();
-                model.removeRow(model.getJoin(row));
-            }
-        });
-
-        saveButton.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                cancelPressed = false;
-                save();
-            }
-        });
-
-        cancelButton.addActionListener(new ActionListener() {
-
-            public void actionPerformed(ActionEvent e) {
-                cancelPressed = true;
-                setVisible(false);
-            }
-        });
-    }
-
-    public boolean isCancelPressed() {
-        return cancelPressed;
-    }
-
-    private void stopEditing() {
-        // Stop whatever editing may be taking place
-        int col_index = table.getEditingColumn();
-        if (col_index >= 0) {
-            TableColumn col = table.getColumnModel().getColumn(col_index);
-            col.getCellEditor().stopCellEditing();
-        }
-    }
-
-    private void save() {
-        // extract names...
-        String sourceEntityName = name.getText();
-        if (sourceEntityName.length() == 0) {
-            sourceEntityName = null;
-        }
-
-        if (sourceEntityName == null) {
-            sourceEntityName = NamedObjectFactory.createName(
-                    DbRelationship.class,
-                    relationship.getSourceEntity());
-        }
-
-        if (!validateName(relationship.getSourceEntity(), relationship, sourceEntityName)) {
-            return;
-        }
-
-        String targetEntityName = reverseName.getText().trim();
-        if (targetEntityName.length() == 0) {
-            targetEntityName = null;
-        }
-
-        if (targetEntityName == null) {
-            targetEntityName = NamedObjectFactory.createName(
-                    DbRelationship.class,
-                    relationship.getTargetEntity());
-        }
-
-        // check if reverse name is valid
-        DbJoinTableModel model = (DbJoinTableModel) table.getModel();
-        boolean updatingReverse = model.getObjectList().size() > 0;
-
-        if (updatingReverse
-                && !validateName(
-                        relationship.getTargetEntity(),
-                        reverseRelationship,
-                        targetEntityName)) {
-            return;
-        }
-
-        // handle name update
-        if (!Util.nullSafeEquals(sourceEntityName, relationship.getName())) {
-            String oldName = relationship.getName();
-            ProjectUtil.setRelationshipName(
-                    relationship.getSourceEntity(),
-                    relationship,
-                    sourceEntityName);
-
-            getMediator().fireDbRelationshipEvent(
-                    new RelationshipEvent(this, relationship, relationship
-                            .getSourceEntity(), oldName));
-        }
-
-        model.commit();
-
-        // check "to dep pk" setting,
-        // maybe this is no longer valid
-        if (relationship.isToDependentPK() && !relationship.isValidForDepPk()) {
-            relationship.setToDependentPK(false);
-        }
-
-        // If new reverse DbRelationship was created, add it to the target
-        // Don't create reverse with no joins - makes no sense...
-        if (updatingReverse) {
-
-            // If didn't find anything, create reverseDbRel
-            if (reverseRelationship == null) {
-                reverseRelationship = new DbRelationship(targetEntityName);
-                reverseRelationship.setSourceEntity(relationship.getTargetEntity());
-                reverseRelationship.setTargetEntity(relationship.getSourceEntity());
-                reverseRelationship.setToMany(!relationship.isToMany());
-                relationship.getTargetEntity().addRelationship(reverseRelationship);
-
-                // fire only if the relationship is to the same entity...
-                // this is needed to update entity view...
-                if (relationship.getSourceEntity() == relationship.getTargetEntity()) {
-                    getMediator().fireDbRelationshipEvent(
-                            new RelationshipEvent(
-                                    this,
-                                    reverseRelationship,
-                                    reverseRelationship.getSourceEntity(),
-                                    MapEvent.ADD));
-                }
-            }
-            else if (!Util
-                    .nullSafeEquals(targetEntityName, reverseRelationship.getName())) {
-                String oldName = reverseRelationship.getName();
-                ProjectUtil.setRelationshipName(
-                        reverseRelationship.getSourceEntity(),
-                        reverseRelationship,
-                        targetEntityName);
-
-                getMediator().fireDbRelationshipEvent(
-                        new RelationshipEvent(
-                                this,
-                                reverseRelationship,
-                                reverseRelationship.getSourceEntity(),
-                                oldName));
-            }
-
-            Collection reverseJoins = getReverseJoins();
-            reverseRelationship.setJoins(reverseJoins);
-
-            // check if joins map to a primary key of this entity
-            if (!relationship.isToDependentPK() && reverseRelationship.isValidForDepPk()) {
-                reverseRelationship.setToDependentPK(true);
-            }
-        }
-
-        getMediator()
-                .fireDbRelationshipEvent(
-                        new RelationshipEvent(this, relationship, relationship
-                                .getSourceEntity()));
-        dispose();
-    }
-
-    private boolean validateName(Entity entity, Relationship aRelationship, String newName) {
-        Relationship existing = entity.getRelationship(newName);
-        if (existing != null && (aRelationship == null || aRelationship != existing)) {
-            JOptionPane.showMessageDialog(
-                    this,
-                    "There is an existing relationship named \""
-                            + newName
-                            + "\". Select a different name.");
-            return false;
-        }
-
-        return true;
-    }
-
-    private Collection getReverseJoins() {
-        Collection<DbJoin> joins = relationship.getJoins();
-
-        if ((joins == null) || (joins.size() == 0)) {
-            return Collections.EMPTY_LIST;
-        }
-
-        List reverseJoins = new ArrayList(joins.size());
-
-        // Loop through the list of attribute pairs, create reverse pairs
-        // and put them to the reverse list.
-        for (DbJoin pair : joins) {
-            DbJoin reverseJoin = pair.createReverseJoin();
-
-            // since reverse relationship is not yet initialized,
-            // reverse join will not have it set automatically
-            reverseJoin.setRelationship(reverseRelationship);
-            reverseJoins.add(reverseJoin);
-        }
-
-        return reverseJoins;
-    }
-
-    final class AttributeTable extends CayenneTable {
-
-        final Dimension preferredSize = new Dimension(203, 100);
-
-        @Override
-        public Dimension getPreferredScrollableViewportSize() {
-            return preferredSize;
-        }
-    }
+	
+	protected DbRelationship relationship;
+	protected DbRelationship reverseRelationship;
+
+	protected JTextField name;
+	protected JTextField reverseName;
+	protected CayenneTable table;
+	protected JButton addButton;
+	protected JButton removeButton;
+	protected JButton saveButton;
+	protected JButton cancelButton;
+
+	private boolean cancelPressed;
+
+	private RelationshipUndoableEdit undo;
+
+	private boolean editable = true;
+
+	public ResolveDbRelationshipDialog(DbRelationship relationship) {
+		this(relationship, true);
+	}
+
+	public ResolveDbRelationshipDialog(DbRelationship relationship,
+			boolean editable) {
+		super(Application.getFrame(), "", true);
+		this.editable = editable;
+
+		initView();
+		initController();
+		initWithModel(relationship);
+
+		this.undo = new RelationshipUndoableEdit(relationship);
+
+		this.pack();
+		this.centerWindow();
+
+	}
+
+	/**
+	 * Creates graphical components.
+	 */
+	private void initView() {
+
+		// create widgets
+		name = CayenneWidgetFactory.createTextField(25);
+		reverseName = CayenneWidgetFactory.createTextField(25);
+
+		addButton = new JButton("Add");
+		addButton.setEnabled(this.editable);
+		
+		removeButton = new JButton("Remove");
+		removeButton.setEnabled(this.editable);
+		
+		saveButton = new JButton("Done");
+		
+		cancelButton = new JButton("Cancel");
+		cancelButton.setEnabled(this.editable);
+
+		table = new AttributeTable();
+		table.getSelectionModel().setSelectionMode(
+				ListSelectionModel.SINGLE_SELECTION);
+
+		// assemble
+		getContentPane().setLayout(new BorderLayout());
+
+		CellConstraints cc = new CellConstraints();
+		PanelBuilder builder = new PanelBuilder(
+				new FormLayout(
+						"right:max(50dlu;pref), 3dlu, fill:min(150dlu;pref), 3dlu, fill:min(50dlu;pref)",
+						"p, 3dlu, p, 3dlu, p, 9dlu, p, 3dlu, top:14dlu, 3dlu, top:p:grow"));
+		builder.setDefaultDialogBorder();
+
+		builder.addSeparator("DbRelationship Information", cc.xywh(1, 1, 5, 1));
+		builder.addLabel("Relationship:", cc.xy(1, 3));
+		builder.add(name, cc.xywh(3, 3, 1, 1));
+		builder.addLabel("Reverse Relationship", cc.xy(1, 5));
+		builder.add(reverseName, cc.xywh(3, 5, 1, 1));
+
+		builder.addSeparator("Joins", cc.xywh(1, 7, 5, 1));
+		builder.add(new JScrollPane(table), cc.xywh(1, 9, 3, 3, "fill, fill"));
+
+		JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEADING));
+
+		buttons.add(addButton);
+		buttons.add(removeButton);
+
+		builder.add(buttons, cc.xywh(5, 9, 1, 3));
+
+		getContentPane().add(builder.getPanel(), BorderLayout.CENTER);
+		getContentPane().add(
+				PanelFactory.createButtonPanel(new JButton[] { saveButton,
+						cancelButton }), BorderLayout.SOUTH);
+	}
+
+	private void initWithModel(DbRelationship aRelationship) {
+		// sanity check
+		if (aRelationship.getSourceEntity() == null) {
+			throw new CayenneRuntimeException("Null source entity: "
+					+ aRelationship);
+		}
+
+		if (aRelationship.getTargetEntity() == null) {
+			throw new CayenneRuntimeException("Null target entity: "
+					+ aRelationship);
+		}
+
+		if (aRelationship.getSourceEntity().getDataMap() == null) {
+			throw new CayenneRuntimeException("Null DataMap: "
+					+ aRelationship.getSourceEntity());
+		}
+
+		// Once assigned, can reference relationship directly. Would it be
+		// OK to assign relationship at the very top of this method?
+		relationship = aRelationship;
+		reverseRelationship = relationship.getReverseRelationship();
+
+		// init UI components
+		setTitle("DbRelationship Info: "
+				+ relationship.getSourceEntity().getName() + " to "
+				+ relationship.getTargetEntityName());
+
+		table.setModel(new DbJoinTableModel(relationship, getMediator(), this,
+				true));
+		TableColumn sourceColumn = table.getColumnModel().getColumn(
+				DbJoinTableModel.SOURCE);
+		sourceColumn.setMinWidth(150);
+		JComboBox comboBox = CayenneWidgetFactory.createComboBox(ModelerUtil
+				.getDbAttributeNames(getMediator(), (DbEntity) relationship
+						.getSourceEntity()), true);
+
+		AutoCompletion.enable(comboBox);
+		sourceColumn.setCellEditor(CayenneWidgetFactory
+				.createCellEditor(comboBox));
+
+		TableColumn targetColumn = table.getColumnModel().getColumn(
+				DbJoinTableModel.TARGET);
+		targetColumn.setMinWidth(150);
+		comboBox = CayenneWidgetFactory.createComboBox(ModelerUtil
+				.getDbAttributeNames(getMediator(), (DbEntity) relationship
+						.getTargetEntity()), true);
+		AutoCompletion.enable(comboBox);
+
+		targetColumn.setCellEditor(CayenneWidgetFactory
+				.createCellEditor(comboBox));
+
+		if (reverseRelationship != null) {
+			reverseName.setText(reverseRelationship.getName());
+		}
+
+		name.setText(relationship.getName());
+	}
+
+	private void initController() {
+		addButton.addActionListener(new ActionListener() {
+
+			public void actionPerformed(ActionEvent e) {
+				DbJoinTableModel model = (DbJoinTableModel) table.getModel();
+
+				DbJoin join = new DbJoin(relationship);
+				model.addRow(join);
+
+				undo.addDbJoinAddUndo(join);
+
+				table.select(model.getRowCount() - 1);
+			}
+		});
+
+		removeButton.addActionListener(new ActionListener() {
+
+			public void actionPerformed(ActionEvent e) {
+				DbJoinTableModel model = (DbJoinTableModel) table.getModel();
+				stopEditing();
+				int row = table.getSelectedRow();
+
+				DbJoin join = model.getJoin(row);
+				undo.addDbJoinRemoveUndo(join);
+
+				model.removeRow(join);
+			}
+		});
+
+		saveButton.addActionListener(new ActionListener() {
+
+			public void actionPerformed(ActionEvent e) {
+				cancelPressed = false;
+				
+				if (editable) {
+					save();
+				}
+				
+				dispose();
+			}
+		});
+
+		cancelButton.addActionListener(new ActionListener() {
+
+			public void actionPerformed(ActionEvent e) {
+				cancelPressed = true;
+				setVisible(false);
+			}
+		});
+	}
+
+	public boolean isCancelPressed() {
+		return cancelPressed;
+	}
+
+	private void stopEditing() {
+		// Stop whatever editing may be taking place
+		int col_index = table.getEditingColumn();
+		if (col_index >= 0) {
+			TableColumn col = table.getColumnModel().getColumn(col_index);
+			col.getCellEditor().stopCellEditing();
+		}
+	}
+
+	private void save() {
+
+		// extract names...
+		String sourceEntityName = name.getText();
+		if (sourceEntityName.length() == 0) {
+			sourceEntityName = null;
+		}
+
+		if (sourceEntityName == null) {
+			sourceEntityName = NamedObjectFactory.createName(
+					DbRelationship.class, relationship.getSourceEntity());
+		}
+
+		if (!validateName(relationship.getSourceEntity(), relationship,
+				sourceEntityName)) {
+			return;
+		}
+
+		String targetEntityName = reverseName.getText().trim();
+		if (targetEntityName.length() == 0) {
+			targetEntityName = null;
+		}
+
+		if (targetEntityName == null) {
+			targetEntityName = NamedObjectFactory.createName(
+					DbRelationship.class, relationship.getTargetEntity());
+		}
+
+		// check if reverse name is valid
+		DbJoinTableModel model = (DbJoinTableModel) table.getModel();
+		boolean updatingReverse = model.getObjectList().size() > 0;
+
+		if (updatingReverse
+				&& !validateName(relationship.getTargetEntity(),
+						reverseRelationship, targetEntityName)) {
+			return;
+		}
+
+		// handle name update
+		if (!Util.nullSafeEquals(sourceEntityName, relationship.getName())) {
+			String oldName = relationship.getName();
+
+			ProjectUtil.setRelationshipName(relationship.getSourceEntity(),
+					relationship, sourceEntityName);
+
+			undo.addNameUndo(relationship, oldName, sourceEntityName);
+
+			getMediator().fireDbRelationshipEvent(
+					new RelationshipEvent(this, relationship, relationship
+							.getSourceEntity(), oldName));
+		}
+
+		model.commit();
+
+		// check "to dep pk" setting,
+		// maybe this is no longer valid
+		if (relationship.isToDependentPK() && !relationship.isValidForDepPk()) {
+			relationship.setToDependentPK(false);
+		}
+
+		// If new reverse DbRelationship was created, add it to the target
+		// Don't create reverse with no joins - makes no sense...
+		if (updatingReverse) {
+
+			// If didn't find anything, create reverseDbRel
+			if (reverseRelationship == null) {
+				reverseRelationship = new DbRelationship(targetEntityName);
+				reverseRelationship.setSourceEntity(relationship
+						.getTargetEntity());
+				reverseRelationship.setTargetEntity(relationship
+						.getSourceEntity());
+				reverseRelationship.setToMany(!relationship.isToMany());
+				relationship.getTargetEntity().addRelationship(
+						reverseRelationship);
+
+				// fire only if the relationship is to the same entity...
+				// this is needed to update entity view...
+				if (relationship.getSourceEntity() == relationship
+						.getTargetEntity()) {
+					getMediator().fireDbRelationshipEvent(
+							new RelationshipEvent(this, reverseRelationship,
+									reverseRelationship.getSourceEntity(),
+									MapEvent.ADD));
+				}
+			} else if (!Util.nullSafeEquals(targetEntityName,
+					reverseRelationship.getName())) {
+
+				String oldName = reverseRelationship.getName();
+
+				ProjectUtil.setRelationshipName(reverseRelationship
+						.getSourceEntity(), reverseRelationship,
+						targetEntityName);
+
+				undo
+						.addNameUndo(reverseRelationship, oldName,
+								targetEntityName);
+
+				getMediator()
+						.fireDbRelationshipEvent(
+								new RelationshipEvent(this,
+										reverseRelationship,
+										reverseRelationship.getSourceEntity(),
+										oldName));
+			}
+
+			Collection reverseJoins = getReverseJoins();
+			reverseRelationship.setJoins(reverseJoins);
+
+			// check if joins map to a primary key of this entity
+			if (!relationship.isToDependentPK()
+					&& reverseRelationship.isValidForDepPk()) {
+				reverseRelationship.setToDependentPK(true);
+			}
+		}
+
+		if (undo.hasEdits()) {
+			Application.getInstance().getUndoManager().addEdit(undo);
+		}
+
+		getMediator().fireDbRelationshipEvent(
+				new RelationshipEvent(this, relationship, relationship
+						.getSourceEntity()));
+	}
+
+	private boolean validateName(Entity entity, Relationship aRelationship,
+			String newName) {
+		Relationship existing = entity.getRelationship(newName);
+		if (existing != null
+				&& (aRelationship == null || aRelationship != existing)) {
+			JOptionPane.showMessageDialog(this,
+					"There is an existing relationship named \"" + newName
+							+ "\". Select a different name.");
+			return false;
+		}
+
+		return true;
+	}
+
+	private Collection getReverseJoins() {
+		Collection<DbJoin> joins = relationship.getJoins();
+
+		if ((joins == null) || (joins.size() == 0)) {
+			return Collections.EMPTY_LIST;
+		}
+
+		List reverseJoins = new ArrayList(joins.size());
+
+		// Loop through the list of attribute pairs, create reverse pairs
+		// and put them to the reverse list.
+		for (DbJoin pair : joins) {
+			DbJoin reverseJoin = pair.createReverseJoin();
+
+			// since reverse relationship is not yet initialized,
+			// reverse join will not have it set automatically
+			reverseJoin.setRelationship(reverseRelationship);
+			reverseJoins.add(reverseJoin);
+		}
+
+		return reverseJoins;
+	}
+
+	final class AttributeTable extends CayenneTable {
+
+		final Dimension preferredSize = new Dimension(203, 100);
+
+		@Override
+		public Dimension getPreferredScrollableViewportSize() {
+			return preferredSize;
+		}
+	}
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/autorelationship/InferRelationshipsController.java Mon Oct  5 18:40:25 2009
@@ -34,6 +34,8 @@
 import org.apache.cayenne.modeler.ClassLoadingService;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
+import org.apache.cayenne.modeler.undo.CreateRelationshipUndoableEdit;
+import org.apache.cayenne.modeler.undo.InferRelationshipsUndoableEdit;
 import org.apache.cayenne.modeler.util.CayenneController;
 import org.apache.cayenne.modeler.util.NamingStrategyPreferences;
 import org.apache.cayenne.swing.BindingBuilder;
@@ -175,9 +177,13 @@
     }
 
     public void generateAction() {
+        
         ProjectController mediator = application
                 .getFrameController()
                 .getProjectController();
+        
+        InferRelationshipsUndoableEdit undoableEdit = new InferRelationshipsUndoableEdit();
+        
         for (InferRelationships temp : selectedEntities) {
             DbRelationship rel = new DbRelationship(uniqueRelName(temp.getSource(), temp
                     .getName()));
@@ -194,6 +200,8 @@
             rel.addJoin(join);
             rel.setToMany(temp.isToMany());
             temp.getSource().addRelationship(rel);
+            
+            undoableEdit.addEdit(new CreateRelationshipUndoableEdit(temp.getSource(), new DbRelationship[] { rel }));
         }
         JOptionPane.showMessageDialog(this.getView(), getSelectedEntitiesSize()
                 + " relationships generated");

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryTypeController.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryTypeController.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryTypeController.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/query/QueryTypeController.java Mon Oct  5 18:40:25 2009
@@ -25,6 +25,7 @@
 import org.apache.cayenne.map.event.QueryEvent;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.event.QueryDisplayEvent;
+import org.apache.cayenne.modeler.undo.CreateQueryUndoableEdit;
 import org.apache.cayenne.project.NamedObjectFactory;
 import org.apache.cayenne.query.AbstractQuery;
 import org.apache.cayenne.query.EJBQLQuery;
@@ -39,89 +40,89 @@
  */
 public class QueryTypeController extends BasicController {
 
-    public static final String CANCEL_CONTROL = "cayenne.modeler.queryType.cancel.button";
-    public static final String CREATE_CONTROL = "cayenne.modeler.queryType.create.button";
-    public static final String OBJECT_QUERY_CONTROL = "cayenne.modeler.queryType.selectQuery.radio";
-    public static final String SQL_QUERY_CONTROL = "cayenne.modeler.queryType.sqlQuery.radio";
-    public static final String PROCEDURE_QUERY_CONTROL = "cayenne.modeler.queryType.procedureQuery.radio";    
-    public static final String EJBQL_QUERY_CONTROL = "cayenne.modeler.queryType.ejbqlQuery.radio";
-
-    protected ProjectController mediator;
-    protected DataMap dataMap;
-    protected DataDomain domain;
-    protected Query query;
-
-    public QueryTypeController(ProjectController mediator) {
-        this.mediator = mediator;
-        this.dataMap = mediator.getCurrentDataMap();
-        this.domain = mediator.getCurrentDataDomain();
-    }
-
-    @Override
-    protected void doHandleControl(Control control) throws ControlException {
-        if (control.matchesID(CANCEL_CONTROL)) {
-            shutdown();
-        }
-        else if (control.matchesID(CREATE_CONTROL)) {
-            createQuery();
-        }
-        else if (control.matchesID(OBJECT_QUERY_CONTROL)) {
-            // do nothing... need to match control
-        }
-        else if (control.matchesID(SQL_QUERY_CONTROL)) {
-            // do nothing... need to match control
-        }
-        else if (control.matchesID(PROCEDURE_QUERY_CONTROL)) {
-            // do nothing... need to match control
-        }
-         else if (control.matchesID(EJBQL_QUERY_CONTROL)) {
-            // do nothing... need to match control            
-        }
-    }
-
-    /**
-     * Creates and runs QueryTypeDialog.
-     */
-    @Override
-    public void startup() {
-        setModel(new QueryTypeModel(mediator.getCurrentDataMap()));
-        setView(new QueryTypeDialog());
-        showView();
-    }
-
-    /**
-     * Action method that creates a query for the specified query type.
-     */
-    public void createQuery() {
-        QueryTypeModel model = (QueryTypeModel) getModel();
-        
-        Query query = model.getSelectedQuery();
-        if (query == null) {
-            // wha?
-            return;
-        }
-
-        // update query...
-        String queryName = NamedObjectFactory.createName(Query.class, dataMap);
-        if(query instanceof EJBQLQuery) {
-            ((EJBQLQuery)query).setName(queryName);
-        } else {
-            ((AbstractQuery)query).setName(queryName);
-        }
-        dataMap.addQuery(query);
-
-        // notify listeners
-        fireQueryEvent(this, mediator, domain, dataMap, query);
-        shutdown();
-    }
-    
-    /**
-     * Fires events when a query was added
-     */
-    public static void fireQueryEvent(Object src, ProjectController mediator, DataDomain domain,
-            DataMap dataMap, Query query) {
-        mediator.fireQueryEvent(new QueryEvent(src, query, MapEvent.ADD, dataMap));
-        mediator
-                .fireQueryDisplayEvent(new QueryDisplayEvent(src, query, dataMap, domain));
-    }
+	public static final String CANCEL_CONTROL = "cayenne.modeler.queryType.cancel.button";
+	public static final String CREATE_CONTROL = "cayenne.modeler.queryType.create.button";
+	public static final String OBJECT_QUERY_CONTROL = "cayenne.modeler.queryType.selectQuery.radio";
+	public static final String SQL_QUERY_CONTROL = "cayenne.modeler.queryType.sqlQuery.radio";
+	public static final String PROCEDURE_QUERY_CONTROL = "cayenne.modeler.queryType.procedureQuery.radio";
+	public static final String EJBQL_QUERY_CONTROL = "cayenne.modeler.queryType.ejbqlQuery.radio";
+
+	protected ProjectController mediator;
+	protected DataMap dataMap;
+	protected DataDomain domain;
+	protected Query query;
+
+	public QueryTypeController(ProjectController mediator) {
+		this.mediator = mediator;
+		this.dataMap = mediator.getCurrentDataMap();
+		this.domain = mediator.getCurrentDataDomain();
+	}
+
+	@Override
+	protected void doHandleControl(Control control) throws ControlException {
+		if (control.matchesID(CANCEL_CONTROL)) {
+			shutdown();
+		} else if (control.matchesID(CREATE_CONTROL)) {
+			createQuery();
+		} else if (control.matchesID(OBJECT_QUERY_CONTROL)) {
+			// do nothing... need to match control
+		} else if (control.matchesID(SQL_QUERY_CONTROL)) {
+			// do nothing... need to match control
+		} else if (control.matchesID(PROCEDURE_QUERY_CONTROL)) {
+			// do nothing... need to match control
+		} else if (control.matchesID(EJBQL_QUERY_CONTROL)) {
+			// do nothing... need to match control
+		}
+	}
+
+	/**
+	 * Creates and runs QueryTypeDialog.
+	 */
+	@Override
+	public void startup() {
+		setModel(new QueryTypeModel(mediator.getCurrentDataMap()));
+		setView(new QueryTypeDialog());
+		showView();
+	}
+
+	/**
+	 * Action method that creates a query for the specified query type.
+	 */
+	public void createQuery() {
+		QueryTypeModel model = (QueryTypeModel) getModel();
+
+		Query query = model.getSelectedQuery();
+		if (query == null) {
+			// wha?
+			return;
+		}
+
+		// update query...
+		String queryName = NamedObjectFactory.createName(Query.class, dataMap);
+		if (query instanceof EJBQLQuery) {
+			((EJBQLQuery) query).setName(queryName);
+		} else {
+			((AbstractQuery) query).setName(queryName);
+		}
+		
+		dataMap.addQuery(query);
+
+		mediator.getApplication().getUndoManager().addEdit(
+				new CreateQueryUndoableEdit(domain, dataMap, query));
+
+		// notify listeners
+		fireQueryEvent(this, mediator, domain, dataMap, query);
+		shutdown();
+	}
+
+	/**
+	 * Fires events when a query was added
+	 */
+	public static void fireQueryEvent(Object src, ProjectController mediator,
+			DataDomain domain, DataMap dataMap, Query query) {
+		mediator.fireQueryEvent(new QueryEvent(src, query, MapEvent.ADD,
+				dataMap));
+		mediator.fireQueryDisplayEvent(new QueryDisplayEvent(src, query,
+				dataMap, domain));
+	}
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java Mon Oct  5 18:40:25 2009
@@ -42,6 +42,7 @@
 import org.apache.cayenne.modeler.dialog.datadomain.CacheSyncConfigController;
 import org.apache.cayenne.modeler.event.DomainDisplayEvent;
 import org.apache.cayenne.modeler.event.DomainDisplayListener;
+import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
 import org.apache.cayenne.modeler.util.ProjectUtil;
 import org.apache.cayenne.modeler.util.TextAdapter;
 import org.apache.cayenne.pref.Domain;
@@ -111,7 +112,7 @@
         this.objectValidation = new JCheckBox();
         this.externalTransactions = new JCheckBox();
 
-        this.queryCacheFactory = new JComboBox();
+        this.queryCacheFactory = CayenneWidgetFactory.createUndoableComboBox();
 
         this.sharedCache = new JCheckBox();
         this.remoteUpdates = new JCheckBox();
@@ -344,6 +345,7 @@
 
         Configuration configuration = ((ApplicationProject) Application.getProject())
                 .getConfiguration();
+        
         DataDomain domain = projectController.getCurrentDataDomain();
 
         DataDomain matchingDomain = configuration.getDomain(newName);

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapView.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapView.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataMapView.java Mon Oct  5 18:40:25 2009
@@ -107,7 +107,7 @@
         };
 
         location = new JLabel();
-        nodeSelector = CayenneWidgetFactory.createComboBox();
+        nodeSelector = CayenneWidgetFactory.createUndoableComboBox();
         nodeSelector.setRenderer(CellRenderers.listRendererWithIcons());
 
         updateDefaultSchema = new JButton("Update...");

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java Mon Oct  5 18:40:25 2009
@@ -37,7 +37,6 @@
 import org.apache.cayenne.map.EmbeddableAttribute;
 import org.apache.cayenne.map.event.EmbeddableAttributeEvent;
 import org.apache.cayenne.modeler.ProjectController;
-
 import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.modeler.util.CayenneTableModel;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureQueryView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureQueryView.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureQueryView.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureQueryView.java Mon Oct  5 18:40:25 2009
@@ -100,7 +100,7 @@
             }
         };
 
-        queryRoot = CayenneWidgetFactory.createComboBox();
+        queryRoot = CayenneWidgetFactory.createUndoableComboBox();
         queryRoot.setRenderer(CellRenderers.listRendererWithIcons());
         properties = new ProcedureQueryPropertiesPanel(mediator);
 
@@ -271,7 +271,7 @@
         }
 
         protected PanelBuilder createPanelBuilder() {
-            labelCase = CayenneWidgetFactory.createComboBox();
+            labelCase = CayenneWidgetFactory.createUndoableComboBox();
             labelCase.setRenderer(new LabelCapsRenderer());
 
             labelCase.addActionListener(new ActionListener() {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/RawQueryPropertiesPanel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/RawQueryPropertiesPanel.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/RawQueryPropertiesPanel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/RawQueryPropertiesPanel.java Mon Oct  5 18:40:25 2009
@@ -109,7 +109,7 @@
 
         dataObjects = new JCheckBox();
 
-        entities = CayenneWidgetFactory.createComboBox();
+        entities = CayenneWidgetFactory.createUndoableComboBox();
         entities.setRenderer(CellRenderers.listRendererWithIcons());
 
         this.setLayout(new BorderLayout());

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SQLTemplateMainTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SQLTemplateMainTab.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SQLTemplateMainTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SQLTemplateMainTab.java Mon Oct  5 18:40:25 2009
@@ -216,7 +216,7 @@
         }
 
         protected PanelBuilder createPanelBuilder() {
-            labelCase = CayenneWidgetFactory.createComboBox();
+            labelCase = CayenneWidgetFactory.createUndoableComboBox();
             labelCase.setRenderer(new LabelCapsRenderer());
 
             labelCase.addActionListener(new ActionListener() {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectPropertiesPanel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectPropertiesPanel.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectPropertiesPanel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectPropertiesPanel.java Mon Oct  5 18:40:25 2009
@@ -47,7 +47,6 @@
 import org.apache.cayenne.validation.ValidationException;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.velocity.texen.util.PropertiesUtil;
 
 /**
  * A panel that supports editing the properties of a GenericSelectQuery.
@@ -113,7 +112,7 @@
             }
         };
 
-        cacheStrategy = CayenneWidgetFactory.createComboBox();
+        cacheStrategy = CayenneWidgetFactory.createUndoableComboBox();
         cacheStrategy.setRenderer(new CacheStrategyRenderer());
         cacheGroups = new TextAdapter(new JTextField()) {
 

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryOrderingTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryOrderingTab.java?rev=821956&r1=821955&r2=821956&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryOrderingTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryOrderingTab.java Mon Oct  5 18:40:25 2009
@@ -26,7 +26,6 @@
 import java.awt.event.ActionListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.util.Iterator;
 
 import javax.swing.JButton;
 import javax.swing.JComponent;