cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kmen...@apache.org
Subject svn commit: r701839 [2/2] - in /cayenne/main/trunk: docs/doc/src/main/resources/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/exp/ framework/cayenne-...
Date Sun, 05 Oct 2008 18:07:18 GMT
Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java?rev=701839&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/action/PasteAction.java Sun Oct  5 11:07:16 2008
@@ -0,0 +1,551 @@
+/*****************************************************************
+ *   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.datatransfer.FlavorEvent;
+import java.awt.datatransfer.FlavorListener;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JOptionPane;
+import javax.swing.KeyStroke;
+
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbAttribute;
+import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.map.DbRelationship;
+import org.apache.cayenne.map.ObjAttribute;
+import org.apache.cayenne.map.ObjEntity;
+import org.apache.cayenne.map.ObjRelationship;
+import org.apache.cayenne.map.Procedure;
+import org.apache.cayenne.map.ProcedureParameter;
+import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
+import org.apache.cayenne.modeler.dialog.query.QueryTypeController;
+import org.apache.cayenne.modeler.util.CayenneAction;
+import org.apache.cayenne.modeler.util.CayenneTransferable;
+import org.apache.cayenne.project.ProjectPath;
+import org.apache.cayenne.query.AbstractQuery;
+import org.apache.cayenne.query.Query;
+
+/**
+ * Action for pasting entities, queries etc. from the system buffer
+ * @author Andrey Razumovsky
+ */
+public class PasteAction extends CayenneAction implements FlavorListener {
+    private static final String COPY_PREFIX = "Copy of ";
+    
+    public static String getActionName() {
+        return "Paste";
+    }
+
+    /**
+     * Constructor for PasteAction
+     */
+    public PasteAction(Application application) {
+        super(getActionName(), application);
+        
+        //add listener, so that button state would update event if clipboard was filled by other app
+        Toolkit.getDefaultToolkit().getSystemClipboard().addFlavorListener(this);
+    }
+
+    @Override
+    public String getIconName() {
+        return "icon-paste.gif";
+    }
+    
+    @Override
+    public KeyStroke getAcceleratorKey() {
+        return KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
+    }
+
+    /**
+     * Performs pasting items from the system buffer
+     */
+    @Override
+    public void performAction(ActionEvent e) {
+        try {
+            Object content = Toolkit.getDefaultToolkit().getSystemClipboard()
+                .getData(CayenneTransferable.CAYENNE_FLAVOR);
+            
+            Object currentObject = getProjectController().getCurrentObject();
+            
+            if (content != null && currentObject != null) {
+                if (content instanceof List) {
+                    for (Object o : (List) content) {
+                        paste(currentObject, o);
+                    }
+                }
+                else {
+                    paste(currentObject, content);
+                }
+            }
+        }
+        catch (UnsupportedFlavorException ufe) {
+            //do nothing
+        }
+        catch (Exception ex) {
+            ErrorDebugDialog.guiException(ex);
+        }
+    }
+
+    /**
+     * Pastes single object
+     */
+    protected void paste(Object where, Object content) {
+        final ProjectController mediator = getProjectController();
+        final DataDomain domain = mediator.getCurrentDataDomain();
+        
+        /**
+         * Add a little intelligence - if a tree leaf is selected, we can paste to a parent datamap
+         */
+        if (isTreeLeaf(where) && isTreeLeaf(content)) {
+            where = mediator.getCurrentDataMap();
+        }
+        
+        if ((where instanceof DataDomain || where instanceof DataNode) && content instanceof DataMap) {
+            //paste DataMap to DataDomain or DataNode
+            DataMap dataMap = ((DataMap) content);
+            
+            dataMap.setName(getFreeName(
+                    new DataMapNameChecker(domain), dataMap.getName()));
+         
+            /**
+             * Update all names in the new DataMap, so that they would not conflict with names from
+             * other datamaps of this domain
+             */
+            
+            //add some intelligence - if we rename an entity, we should rename all links to it as well
+            Map<String, String> renamedDbEntities = new HashMap<String, String>();
+            Map<String, String> renamedObjEntities = new HashMap<String, String>();
+            
+            for (DbEntity dbEntity : dataMap.getDbEntities()) {
+                String oldName = dbEntity.getName();
+                dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity.getName()));
+                
+                if (!oldName.equals(dbEntity.getName())) {
+                    renamedDbEntities.put(oldName, dbEntity.getName());
+                }
+            }
+            for (ObjEntity objEntity : dataMap.getObjEntities()) {
+                String oldName = objEntity.getName();
+                objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity.getName()));
+                
+                if (!oldName.equals(objEntity.getName())) {
+                    renamedObjEntities.put(oldName, objEntity.getName());
+                }
+            }
+            for (Procedure procedure : dataMap.getProcedures()) {
+                procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure.getName()));
+            }
+            for (Query query : dataMap.getQueries()) {
+                ((AbstractQuery) query).setName(getFreeName(new QueryNameChecker(domain), query.getName()));
+            }
+            
+            // if an entity was renamed, we rename all links to it too
+            for (DbEntity dbEntity : dataMap.getDbEntities()) {
+                for (DbRelationship rel : dbEntity.getRelationships()) {
+                    if (renamedDbEntities.containsKey(rel.getTargetEntityName())) {
+                        rel.setTargetEntityName(renamedDbEntities.get(rel.getTargetEntityName()));
+                    }
+                }
+            }
+            for (ObjEntity objEntity : dataMap.getObjEntities()) {
+                if (renamedDbEntities.containsKey(objEntity.getDbEntityName())) {
+                    objEntity.setDbEntityName(renamedDbEntities.get(objEntity.getDbEntityName()));
+                }
+                
+                if (renamedObjEntities.containsKey(objEntity.getSuperEntityName())) {
+                    objEntity.setSuperEntityName(renamedDbEntities.get(objEntity.getSuperEntityName()));
+                }
+                
+                for (ObjRelationship rel : objEntity.getRelationships()) {
+                    if (renamedObjEntities.containsKey(rel.getTargetEntityName())) {
+                        rel.setTargetEntityName(renamedObjEntities.get(rel.getTargetEntityName()));
+                    }
+                }
+            }
+            
+            mediator.addDataMap(this, dataMap);
+        }
+        else if (where instanceof DataMap) {
+            //paste DbEntity to DataMap
+            final DataMap dataMap = ((DataMap) where); 
+            
+            if (content instanceof DbEntity) {
+                DbEntity dbEntity = (DbEntity) content;
+                dbEntity.setName(getFreeName(new DbEntityNameChecker(domain), dbEntity.getName()));
+                
+                dataMap.addDbEntity(dbEntity);
+                CreateDbEntityAction.fireDbEntityEvent(this, mediator, dbEntity);
+            }
+            else if (content instanceof ObjEntity) {
+                //paste ObjEntity to DataMap
+                ObjEntity objEntity = (ObjEntity) content;
+                objEntity.setName(getFreeName(new ObjEntityNameChecker(domain), objEntity.getName()));
+                
+                dataMap.addObjEntity(objEntity);
+                CreateObjEntityAction.fireObjEntityEvent(this, mediator, dataMap, objEntity);
+            }           
+            else if (content instanceof Query) {
+                //paste Query to DataMap
+                AbstractQuery query = (AbstractQuery) content;
+                
+                /**
+                 * Change Query root do current datamap's
+                 */
+                Object root = query.getRoot();
+                Object newRoot = root;
+                
+                if (root instanceof ObjEntity) {
+                    newRoot = dataMap.getObjEntity(((ObjEntity) root).getName());
+                }
+                else if (root instanceof DbEntity) {
+                    newRoot = dataMap.getDbEntity(((DbEntity) root).getName());
+                }
+                else if (root instanceof Procedure) {
+                    newRoot = dataMap.getProcedure(((Procedure) root).getName());
+                }
+                
+                if (newRoot == null) {
+                    JOptionPane.showMessageDialog(
+                            Application.getFrame(),
+                            "Query root cannot be resolved. Pasting has not been performed.",
+                            "Warning",
+                            JOptionPane.WARNING_MESSAGE);
+                    return;
+                }
+                    
+                query.setName(getFreeName(new QueryNameChecker(domain), query.getName()));
+                    
+                dataMap.addQuery(query);
+                QueryTypeController.fireQueryEvent(this, mediator, mediator.getCurrentDataDomain(), 
+                        dataMap, query);
+            }
+            else if (content instanceof Procedure) {
+                //paste Procedure to DataMap
+                Procedure procedure = (Procedure) content;
+                procedure.setName(getFreeName(new ProcedureNameChecker(domain), procedure.getName()));
+                
+                dataMap.addProcedure(procedure);
+                CreateProcedureAction.fireProcedureEvent(this, mediator, dataMap, procedure);
+            }
+        }
+        else if (where instanceof DbEntity) {
+            final DbEntity dbEntity = (DbEntity) where;
+            
+            //attrs and rels must be unique in entity namespace
+            FreeNameChecker checker = 
+                new FreeNameChecker() {
+                    public boolean isNameFree(String name) {
+                        return dbEntity.getAttribute(name) == null 
+                            && dbEntity.getRelationship(name) == null;
+                    }
+                };
+            
+            if (content instanceof DbAttribute) {
+                DbAttribute attr = (DbAttribute) content; 
+                attr.setName(getFreeName(checker, attr.getName()));          
+                
+                dbEntity.addAttribute(attr);
+                CreateAttributeAction.fireDbAttributeEvent(this, mediator, dbEntity, attr);
+            }
+            else if (content instanceof DbRelationship) {
+                DbRelationship rel = (DbRelationship) content; 
+                rel.setName(getFreeName(checker, rel.getName()));          
+                
+                dbEntity.addRelationship(rel);
+                CreateRelationshipAction.fireDbRelationshipEvent(this, mediator, dbEntity, rel);
+            }
+        }
+        else if (where instanceof ObjEntity) {
+            final ObjEntity objEntity = (ObjEntity) where;
+            
+            //attrs and rels must be unique in entity namespace
+            FreeNameChecker checker = 
+                new FreeNameChecker() {
+                    public boolean isNameFree(String name) {
+                        return objEntity.getAttribute(name) == null 
+                            && objEntity.getRelationship(name) == null;
+                    }
+                };
+            
+            if (content instanceof ObjAttribute) {
+                ObjAttribute attr = (ObjAttribute) content; 
+                attr.setName(getFreeName(checker, attr.getName()));          
+                
+                objEntity.addAttribute(attr);
+                CreateAttributeAction.fireObjAttributeEvent(this, mediator, objEntity, attr);
+            }
+            else if (content instanceof ObjRelationship) {
+                ObjRelationship rel = (ObjRelationship) content; 
+                rel.setName(getFreeName(checker, rel.getName()));          
+                
+                objEntity.addRelationship(rel);
+                CreateRelationshipAction.fireObjRelationshipEvent(this, mediator, objEntity, rel);
+            }
+        }
+        else if (where instanceof Procedure) {
+            //paste param to procedure
+            final Procedure procedure = (Procedure) where;
+            
+            if (content instanceof ProcedureParameter) {
+                ProcedureParameter param = (ProcedureParameter) content;
+                
+                param.setName(getFreeName(
+                        new FreeNameChecker()
+                        {
+                            public boolean isNameFree(String name) {
+                                for (ProcedureParameter existingParam : procedure.getCallParameters()) {
+                                    if (name.equals(existingParam.getName())) {
+                                        return false;
+                                    }
+                                }
+                                
+                                return true;
+                            }
+                        }, param.getName()));
+                
+                procedure.addCallParameter(param);
+                CreateProcedureParameterAction.fireProcedureParameterEvent(this, mediator, procedure, param);
+            }
+            
+        }
+    }
+    
+    /**
+     * Finds avaliable name for an object
+     */
+    private String getFreeName(FreeNameChecker checker, String defName) {
+        String name = defName;
+        
+        for (int i = 0; !checker.isNameFree(name); 
+            name = COPY_PREFIX + defName + (i == 0 ? "" : " (" + i + ")"), i++);
+        
+        return name;
+    }
+    
+    /**
+     * Returns <code>true</code> if last object in the path contains a removable object.
+     */
+    @Override
+    public boolean enableForPath(ProjectPath path) {
+        if (path == null) {
+            return false;
+        }
+        
+        return getState();
+    }
+    
+    /**
+     * Enables or disables the action, judging last selected component
+     */
+    public void updateState() {
+        setEnabled(getState());
+    }
+    
+    /**
+     * Returns desired enable state for this action
+     */
+    private boolean getState() {
+        try {
+            Object content = Toolkit.getDefaultToolkit().getSystemClipboard()
+                .getData(CayenneTransferable.CAYENNE_FLAVOR);
+            
+            if (content instanceof List) {
+                content = ((List) content).get(0);
+            }
+            
+            Object currentObject = getProjectController().getCurrentObject();
+            
+            if (currentObject == null) {
+                return false; 
+            }
+            
+            /**
+             * Checking all avaliable pairs source-pasting object 
+             */
+            
+            return (
+                    (currentObject instanceof DataDomain || currentObject instanceof DataNode) && 
+                    content instanceof DataMap) ||
+                    
+                    (currentObject instanceof DataMap && isTreeLeaf(content)) ||
+                        
+                    (currentObject instanceof DbEntity && (
+                        content instanceof DbAttribute || content instanceof DbRelationship
+                        || isTreeLeaf(content))) ||
+                        
+                    (currentObject instanceof ObjEntity && (
+                        content instanceof ObjAttribute || content instanceof ObjRelationship
+                        || isTreeLeaf(content))) ||
+                        
+                    (currentObject instanceof Procedure && (content instanceof ProcedureParameter
+                        || isTreeLeaf(content)) ||
+            
+                    (currentObject instanceof Query && isTreeLeaf(content)));
+        }
+        catch (Exception ex) {
+            return false;
+        }
+    }
+    
+    /**
+     * @return true if the object is in a lowest level of the tree
+     */
+    private boolean isTreeLeaf(Object content) {
+        return content instanceof DbEntity || content instanceof ObjEntity || 
+            content instanceof Procedure || content instanceof Query;  
+    }
+    
+    public void flavorsChanged(FlavorEvent e) {
+        updateState();
+    }
+    
+    /**
+     * Interface for checking that specified name is free in superior DataMap, Entity etc. and
+     * therefore can be used for new object 
+     */
+    interface FreeNameChecker {
+        boolean isNameFree(String name);
+    }
+    
+    /**
+     * FreeNameChecker implementation for choosing DataMap names 
+     */
+    class DataMapNameChecker implements FreeNameChecker {
+        DataDomain domain;
+        
+        public DataMapNameChecker(DataDomain domain) {
+            this.domain = domain;
+        }
+        
+        public boolean isNameFree(String name) {
+            return domain.getMap(name) == null;
+        }
+    }
+    
+    /**
+     * FreeNameChecker implementation for choosing DbEntity names 
+     */
+    class DbEntityNameChecker implements FreeNameChecker {
+        DataDomain domain;
+        
+        public DbEntityNameChecker(DataDomain domain) {
+            this.domain = domain;
+        }
+        
+        public boolean isNameFree(String name) {
+            /**
+             * Name mast be unique through all DataDomain, for EntityResolver to work
+             * correctly
+             */
+            for (DataMap map : domain.getDataMaps()) {
+                if (map.getDbEntity(name) != null) {
+                    return false;
+                }
+            }
+            
+            return true;
+        }
+    }
+    
+    /**
+     * FreeNameChecker implementation for choosing ObjEntity names 
+     */
+    class ObjEntityNameChecker implements FreeNameChecker {
+        DataDomain domain;
+        
+        public ObjEntityNameChecker(DataDomain domain) {
+            this.domain = domain;
+        }
+        
+        public boolean isNameFree(String name) {
+            /**
+             * Name mast be unique through all DataDomain, for EntityResolver to work
+             * correctly
+             */
+            for (DataMap map : domain.getDataMaps()) {
+                if (map.getObjEntity(name) != null) {
+                    return false;
+                }
+            }
+            
+            return true;
+        }
+    }
+    
+    /**
+     * FreeNameChecker implementation for choosing Procedure names 
+     */
+    class ProcedureNameChecker implements FreeNameChecker {
+        DataDomain domain;
+        
+        public ProcedureNameChecker(DataDomain domain) {
+            this.domain = domain;
+        }
+        
+        public boolean isNameFree(String name) {
+            /**
+             * Name mast be unique through all DataDomain, for EntityResolver to work
+             * correctly
+             */
+            for (DataMap map : domain.getDataMaps()) {
+                if (map.getNamespace().getProcedure(name) != null) {
+                    return false;
+                }
+            }
+            
+            return true;
+        }
+    }
+    
+    /**
+     * FreeNameChecker implementation for choosing Query names 
+     */
+    class QueryNameChecker implements FreeNameChecker {
+        DataDomain domain;
+        
+        public QueryNameChecker(DataDomain domain) {
+            this.domain = domain;
+        }
+        
+        public boolean isNameFree(String name) {
+            /**
+             * Name mast be unique through all DataDomain, for EntityResolver to work
+             * correctly
+             */
+            for (DataMap map : domain.getDataMaps()) {
+                if (map.getNamespace().getQuery(name) != null) {
+                    return false;
+                }
+            }
+            
+            return true;
+        }
+    }
+}

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=701839&r1=701838&r2=701839&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 Sun Oct  5 11:07:16 2008
@@ -82,16 +82,28 @@
         return KeyStroke.getKeyStroke(KeyEvent.VK_D, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask());
     }
 
-    public ConfirmRemoveDialog getConfirmDeleteDialog() {
-        return new ConfirmRemoveDialog();
+    /**
+     * Creates and returns dialog for delete prompt
+     * @param allowAsking If false, no question will be asked no matter what settings are 
+     */
+    public ConfirmRemoveDialog getConfirmDeleteDialog(boolean allowAsking) {
+        return new ConfirmRemoveDialog(allowAsking);
     }
-
+    
     @Override
     public void performAction(ActionEvent e) {
+        performAction(e, true);
+    }
+
+    /**
+     * Performs delete action
+     * @param allowAsking If false, no question will be asked no matter what settings are 
+     */
+    public void performAction(ActionEvent e, boolean allowAsking) {
 
         ProjectController mediator = getProjectController();
 
-        ConfirmRemoveDialog dialog = getConfirmDeleteDialog();
+        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
         if (mediator.getCurrentObjEntity() != null) {
             if (dialog.shouldDelete("ObjEntity", mediator.getCurrentObjEntity().getName())) {

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=701839&r1=701838&r2=701839&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 Sun Oct  5 11:07:16 2008
@@ -40,7 +40,7 @@
  * 
  * @author Garry Watkins
  */
-public class RemoveAttributeAction extends RemoveAction {
+public class RemoveAttributeAction extends RemoveAction implements MultipleObjectsAction {
 
     private final static String ACTION_NAME = "Remove Attribute";
     
@@ -53,7 +53,7 @@
         return ACTION_NAME;
     }
     
-    public static String getActionName(boolean multiple) {
+    public String getActionName(boolean multiple) {
         return multiple ? ACTION_NAME_MULTIPLE : ACTION_NAME;
     }
 
@@ -75,8 +75,8 @@
     }
 
     @Override
-    public void performAction(ActionEvent e) {
-        ConfirmRemoveDialog dialog = getConfirmDeleteDialog();
+    public void performAction(ActionEvent e, boolean allowAsking) {
+        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
         ObjAttribute[] attrs = getProjectController().getCurrentObjAttributes();
         if (attrs != null && attrs.length > 0) {

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=701839&r1=701838&r2=701839&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 Sun Oct  5 11:07:16 2008
@@ -66,8 +66,8 @@
      * base entity listener removing logic
      * @param e event
      */
-    public void performAction(ActionEvent e) {
-        ConfirmRemoveDialog dialog = getConfirmDeleteDialog();
+    public void performAction(ActionEvent e, boolean allowAsking) {
+        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
         if ((getProjectController().getCurrentObjEntity() != null) &&
             (getProjectController().getCurrentListenerClass() != null)) {

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=701839&r1=701838&r2=701839&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 Sun Oct  5 11:07:16 2008
@@ -65,8 +65,8 @@
      * base entity listener removing logic
      * @param e event
      */
-    public void performAction(ActionEvent e) {
-        ConfirmRemoveDialog dialog = getConfirmDeleteDialog();
+    public void performAction(ActionEvent e, boolean allowAsking) {
+        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
         if (getProjectController().getCurrentListenerClass() != null) {
             if (dialog.shouldDelete("entity listener", getProjectController()

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=701839&r1=701838&r2=701839&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 Sun Oct  5 11:07:16 2008
@@ -70,8 +70,8 @@
     }
 
     @Override
-    public void performAction(ActionEvent e) {
-        ConfirmRemoveDialog dialog = getConfirmDeleteDialog();
+    public void performAction(ActionEvent e, boolean allowAsking) {
+        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
         ProcedureParameter[] params = getProjectController().getCurrentProcedureParameters(); 
         if (params.length > 0) {

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=701839&r1=701838&r2=701839&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 Sun Oct  5 11:07:16 2008
@@ -40,7 +40,7 @@
  * 
  * @author Garry Watkins
  */
-public class RemoveRelationshipAction extends RemoveAction {
+public class RemoveRelationshipAction extends RemoveAction implements MultipleObjectsAction {
 
     private final static String ACTION_NAME = "Remove Relationship";
     
@@ -53,7 +53,7 @@
         return ACTION_NAME;
     }
     
-    public static String getActionName(boolean multiple) {
+    public String getActionName(boolean multiple) {
         return multiple ? ACTION_NAME_MULTIPLE : ACTION_NAME;
     }
 
@@ -75,8 +75,8 @@
     }
 
     @Override
-    public void performAction(ActionEvent e) {
-        ConfirmRemoveDialog dialog = getConfirmDeleteDialog();
+    public void performAction(ActionEvent e, boolean allowAsking) {
+        ConfirmRemoveDialog dialog = getConfirmDeleteDialog(allowAsking);
 
         ObjRelationship[] rels = getProjectController().getCurrentObjRelationships();
         if (rels != null && rels.length > 0) {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ConfirmRemoveDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ConfirmRemoveDialog.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ConfirmRemoveDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ConfirmRemoveDialog.java Sun Oct  5 11:07:16 2008
@@ -16,6 +16,15 @@
 public class ConfirmRemoveDialog {
     private boolean shouldDelete = true;
     
+    /**
+     * If false, no question will be asked no matter what settings are
+     */
+    private boolean allowAsking;
+    
+    public ConfirmRemoveDialog(boolean allowAsking) {
+        this.allowAsking = allowAsking;
+    }
+    
     private void showDialog(String name) {
 
         JCheckBox neverPromptAgainBox = new JCheckBox("Always delete without prompt.");
@@ -43,12 +52,13 @@
     }
 
     public boolean shouldDelete(String name) {
+        if (allowAsking) {
+            PreferenceDetail pref = Application.getInstance().getPreferenceDomain().getDetail(GeneralPreferences.DELETE_PROMPT_PREFERENCE, true);
 
-        PreferenceDetail pref = Application.getInstance().getPreferenceDomain().getDetail(GeneralPreferences.DELETE_PROMPT_PREFERENCE, true);
-
-        // See if the user has opted not to showDialog the delete dialog.
-        if ((pref == null) || (false == pref.getBooleanProperty(GeneralPreferences.DELETE_PROMPT_PREFERENCE))) {
-           showDialog(name);
+            // See if the user has opted not to showDialog the delete dialog.
+            if ((pref == null) || (false == pref.getBooleanProperty(GeneralPreferences.DELETE_PROMPT_PREFERENCE))) {
+                showDialog(name);
+            }
         }
 
         return shouldDelete;

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=701839&r1=701838&r2=701839&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 Sun Oct  5 11:07:16 2008
@@ -102,9 +102,17 @@
         dataMap.addQuery(query);
 
         // notify listeners
-        mediator.fireQueryEvent(new QueryEvent(this, query, MapEvent.ADD, dataMap));
-        mediator
-                .fireQueryDisplayEvent(new QueryDisplayEvent(this, query, dataMap, domain));
+        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/ObjEntityAttributeTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java Sun Oct  5 11:07:16 2008
@@ -46,14 +46,16 @@
 import org.apache.cayenne.map.event.ObjEntityListener;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CopyAttributeAction;
 import org.apache.cayenne.modeler.action.CreateAttributeAction;
+import org.apache.cayenne.modeler.action.CutAttributeAction;
 import org.apache.cayenne.modeler.action.ObjEntitySyncAction;
+import org.apache.cayenne.modeler.action.PasteAction;
 import org.apache.cayenne.modeler.action.RemoveAttributeAction;
 import org.apache.cayenne.modeler.event.AttributeDisplayEvent;
 import org.apache.cayenne.modeler.event.EntityDisplayEvent;
 import org.apache.cayenne.modeler.event.ObjEntityDisplayListener;
 import org.apache.cayenne.modeler.event.TablePopupHandler;
-import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
 import org.apache.cayenne.modeler.util.ModelerUtil;
@@ -89,6 +91,12 @@
         toolBar.add(app.getAction(ObjEntitySyncAction.getActionName()).buildButton());
         toolBar.addSeparator();
         toolBar.add(app.getAction(RemoveAttributeAction.getActionName()).buildButton());
+        
+        toolBar.addSeparator();
+        toolBar.add(app.getAction(CutAttributeAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(CopyAttributeAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(PasteAction.getActionName()).buildButton());
+        
         add(toolBar, BorderLayout.NORTH);
 
         table = new CayenneTable();
@@ -100,6 +108,11 @@
         JPopupMenu popup = new JPopupMenu();
         popup.add(app.getAction(RemoveAttributeAction.getActionName()).buildMenu());
         
+        popup.addSeparator();
+        popup.add(app.getAction(CutAttributeAction.getActionName()).buildMenu());
+        popup.add(app.getAction(CopyAttributeAction.getActionName()).buildMenu());
+        popup.add(app.getAction(PasteAction.getActionName()).buildMenu());
+        
         TablePopupHandler.install(table, popup);
 
         add(PanelFactory.createTablePanel(table, null), BorderLayout.CENTER);
@@ -116,24 +129,20 @@
                 processExistingSelection(e);
             }
         });
+        
+        mediator.getApplication().getActionManager().setupCCP(table, 
+                CutAttributeAction.getActionName(), CopyAttributeAction.getActionName());
     }
 
     /**
      * Selects a specified attribute.
      */
     public void selectAttributes(ObjAttribute[] attrs) {
-        CayenneAction removeAction = Application
-            .getInstance()
-            .getAction(RemoveAttributeAction.getActionName());
+        ModelerUtil.updateActions(attrs.length,  
+                RemoveAttributeAction.getActionName(),
+                CutAttributeAction.getActionName(),
+                CopyAttributeAction.getActionName());
         
-        if (attrs.length == 0) {
-            removeAction.setEnabled(false);
-            return;
-        }
-        // enable the remove button
-        removeAction.setEnabled(true);
-        removeAction.setName(RemoveAttributeAction.getActionName(attrs.length > 1));
-
         ObjAttributeTableModel model = (ObjAttributeTableModel) table.getModel();
         
         List listAttrs = model.getObjectList();

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java Sun Oct  5 11:07:16 2008
@@ -19,6 +19,34 @@
 
 package org.apache.cayenne.modeler.editor;
 
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Collection;
+import java.util.EventObject;
+import java.util.List;
+
+import javax.swing.DefaultCellEditor;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JTable;
+import javax.swing.JToolBar;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableColumn;
+
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DeleteRule;
 import org.apache.cayenne.map.ObjEntity;
@@ -29,30 +57,27 @@
 import org.apache.cayenne.map.event.RelationshipEvent;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CopyRelationshipAction;
 import org.apache.cayenne.modeler.action.CreateRelationshipAction;
+import org.apache.cayenne.modeler.action.CutRelationshipAction;
 import org.apache.cayenne.modeler.action.ObjEntitySyncAction;
+import org.apache.cayenne.modeler.action.PasteAction;
 import org.apache.cayenne.modeler.action.RemoveRelationshipAction;
 import org.apache.cayenne.modeler.dialog.objentity.ObjRelationshipInfoController;
 import org.apache.cayenne.modeler.event.EntityDisplayEvent;
 import org.apache.cayenne.modeler.event.ObjEntityDisplayListener;
 import org.apache.cayenne.modeler.event.RelationshipDisplayEvent;
 import org.apache.cayenne.modeler.event.TablePopupHandler;
-import org.apache.cayenne.modeler.util.*;
+import org.apache.cayenne.modeler.util.CayenneTable;
+import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
+import org.apache.cayenne.modeler.util.CellRenderers;
+import org.apache.cayenne.modeler.util.ModelerUtil;
+import org.apache.cayenne.modeler.util.PanelFactory;
+import org.apache.cayenne.modeler.util.UIUtil;
 import org.apache.cayenne.modeler.util.combo.AutoCompletion;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.table.DefaultTableCellRenderer;
-import javax.swing.table.TableColumn;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.Collection;
-import java.util.EventObject;
-import java.util.List;
-
 /**
  * Displays ObjRelationships for the edited ObjEntity.
  * 
@@ -112,10 +137,13 @@
 
         toolBar.addSeparator();
 
-        toolBar
-                .add(app
-                        .getAction(RemoveRelationshipAction.getActionName())
-                        .buildButton());
+        toolBar.add(app.getAction(RemoveRelationshipAction.getActionName()).buildButton());
+        
+        toolBar.addSeparator();
+        toolBar.add(app.getAction(CutRelationshipAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(CopyRelationshipAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(PasteAction.getActionName()).buildButton());
+        
         add(toolBar, BorderLayout.NORTH);
 
         table = new CayenneTable();
@@ -131,6 +159,11 @@
         popup.add(resolveMenu);
         popup.add(app.getAction(RemoveRelationshipAction.getActionName()).buildMenu());
         
+        popup.addSeparator();
+        popup.add(app.getAction(CutRelationshipAction.getActionName()).buildMenu());
+        popup.add(app.getAction(CopyRelationshipAction.getActionName()).buildMenu());
+        popup.add(app.getAction(PasteAction.getActionName()).buildMenu());
+        
         TablePopupHandler.install(table, popup);
 
         add(PanelFactory.createTablePanel(table, null), BorderLayout.CENTER);
@@ -175,23 +208,19 @@
                 processExistingSelection(e);
             }
         });
+        
+        mediator.getApplication().getActionManager().setupCCP(table, 
+                CutRelationshipAction.getActionName(), CopyRelationshipAction.getActionName());
     }
 
     /**
      * Selects a specified relationship in the relationships table.
      */
     public void selectRelationships(ObjRelationship[] rels) {
-        CayenneAction removeAction = Application
-            .getInstance()
-            .getAction(RemoveRelationshipAction.getActionName());
-        
-        if (rels.length == 0) {
-            removeAction.setEnabled(false);
-            return;
-        }
-        // enable the remove button
-        removeAction.setEnabled(true);
-        removeAction.setName(RemoveRelationshipAction.getActionName(rels.length > 1));
+        ModelerUtil.updateActions(rels.length,  
+                RemoveRelationshipAction.getActionName(),
+                CutRelationshipAction.getActionName(),
+                CopyRelationshipAction.getActionName());
 
         ObjRelationshipTableModel model = (ObjRelationshipTableModel) table.getModel();
 

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java Sun Oct  5 11:07:16 2008
@@ -49,13 +49,15 @@
 import org.apache.cayenne.map.event.ProcedureParameterListener;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CopyProcedureParameterAction;
 import org.apache.cayenne.modeler.action.CreateProcedureParameterAction;
+import org.apache.cayenne.modeler.action.CutProcedureParameterAction;
+import org.apache.cayenne.modeler.action.PasteAction;
 import org.apache.cayenne.modeler.action.RemoveProcedureParameterAction;
 import org.apache.cayenne.modeler.event.ProcedureDisplayEvent;
 import org.apache.cayenne.modeler.event.ProcedureDisplayListener;
 import org.apache.cayenne.modeler.event.ProcedureParameterDisplayEvent;
 import org.apache.cayenne.modeler.event.TablePopupHandler;
-import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.modeler.util.CayenneCellEditor;
 import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
@@ -136,6 +138,11 @@
         moveDown.setToolTipText("Move Parameter Down");
         toolBar.add(moveDown);
         
+        toolBar.addSeparator();
+        toolBar.add(app.getAction(CutProcedureParameterAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(CopyProcedureParameterAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(PasteAction.getActionName()).buildButton());
+        
         add(toolBar, BorderLayout.NORTH);
 
         // Create table with two columns and no rows.
@@ -157,9 +164,20 @@
         popup.add(moveUpMenu);
         popup.add(moveDownMenu);
         
+        popup.addSeparator();
+        popup.add(app.getAction(CutProcedureParameterAction.getActionName()).buildMenu());
+        popup.add(app.getAction(CopyProcedureParameterAction.getActionName()).buildMenu());
+        popup.add(app.getAction(PasteAction.getActionName()).buildMenu());
+        
         TablePopupHandler.install(table, popup);
         
         add(PanelFactory.createTablePanel(table, null), BorderLayout.CENTER);
+        
+        eventController.getApplication().getActionManager().setupCCP(table, 
+                CutProcedureParameterAction.getActionName(), 
+                CopyProcedureParameterAction
+                
+                .getActionName());
     }
     
     public void processExistingSelection(EventObject e) {
@@ -231,14 +249,10 @@
      * Selects a specified parameters.
      */
     public void selectParameters(ProcedureParameter[] parameters) {
-        if (parameters.length == 0) {
-            return;
-        }
-        
-        CayenneAction removeAction = Application
-            .getInstance()
-            .getAction(RemoveProcedureParameterAction.getActionName());
-        removeAction.setName(RemoveProcedureParameterAction.getActionName(parameters.length > 1));
+        ModelerUtil.updateActions(parameters.length,  
+                RemoveProcedureParameterAction.getActionName(),
+                CutProcedureParameterAction.getActionName(),
+                CopyProcedureParameterAction.getActionName());
 
         ProcedureParameterTableModel model =
             (ProcedureParameterTableModel) table.getModel();

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java Sun Oct  5 11:07:16 2008
@@ -39,18 +39,21 @@
 import org.apache.cayenne.map.event.DbAttributeListener;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CopyAttributeAction;
 import org.apache.cayenne.modeler.action.CreateAttributeAction;
 import org.apache.cayenne.modeler.action.CreateObjEntityAction;
+import org.apache.cayenne.modeler.action.CutAttributeAction;
 import org.apache.cayenne.modeler.action.DbEntitySyncAction;
+import org.apache.cayenne.modeler.action.PasteAction;
 import org.apache.cayenne.modeler.action.RemoveAttributeAction;
 import org.apache.cayenne.modeler.editor.ExistingSelectionProcessor;
 import org.apache.cayenne.modeler.event.AttributeDisplayEvent;
 import org.apache.cayenne.modeler.event.DbEntityDisplayListener;
 import org.apache.cayenne.modeler.event.EntityDisplayEvent;
 import org.apache.cayenne.modeler.event.TablePopupHandler;
-import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
+import org.apache.cayenne.modeler.util.ModelerUtil;
 import org.apache.cayenne.modeler.util.PanelFactory;
 import org.apache.cayenne.modeler.util.UIUtil;
 import org.apache.cayenne.modeler.util.combo.AutoCompletion;
@@ -90,6 +93,11 @@
 
         toolBar.addSeparator();
         toolBar.add(app.getAction(RemoveAttributeAction.getActionName()).buildButton());
+        
+        toolBar.addSeparator();
+        toolBar.add(app.getAction(CutAttributeAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(CopyAttributeAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(PasteAction.getActionName()).buildButton());
 
         add(toolBar, BorderLayout.NORTH);
         
@@ -102,9 +110,17 @@
         JPopupMenu popup = new JPopupMenu();
         popup.add(app.getAction(RemoveAttributeAction.getActionName()).buildMenu());
         
+        popup.addSeparator();
+        popup.add(app.getAction(CutAttributeAction.getActionName()).buildMenu());
+        popup.add(app.getAction(CopyAttributeAction.getActionName()).buildMenu());
+        popup.add(app.getAction(PasteAction.getActionName()).buildMenu());
+        
         TablePopupHandler.install(table, popup);
         
         add(PanelFactory.createTablePanel(table, null), BorderLayout.CENTER);
+        
+        mediator.getApplication().getActionManager().setupCCP(table, 
+                CutAttributeAction.getActionName(), CopyAttributeAction.getActionName());
     }
 
     public void valueChanged(ListSelectionEvent e) {
@@ -115,17 +131,10 @@
      * Selects specified attributes.
      */
     public void selectAttributes(DbAttribute[] attrs) {
-        CayenneAction removeAction = Application
-          .getInstance()
-          .getAction(RemoveAttributeAction.getActionName());
-        
-        if (attrs == null || attrs.length == 0) {
-            removeAction.setEnabled(false);
-            return;
-        }
-        // enable the remove button
-        removeAction.setEnabled(true);
-        removeAction.setName(RemoveAttributeAction.getActionName(attrs.length > 1));
+        ModelerUtil.updateActions(attrs.length,  
+                RemoveAttributeAction.getActionName(),
+                CutAttributeAction.getActionName(),
+                CopyAttributeAction.getActionName());
 
         DbAttributeTableModel model = (DbAttributeTableModel) table.getModel();
         

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java Sun Oct  5 11:07:16 2008
@@ -50,9 +50,12 @@
 import org.apache.cayenne.map.event.RelationshipEvent;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.CopyRelationshipAction;
 import org.apache.cayenne.modeler.action.CreateObjEntityAction;
 import org.apache.cayenne.modeler.action.CreateRelationshipAction;
+import org.apache.cayenne.modeler.action.CutRelationshipAction;
 import org.apache.cayenne.modeler.action.DbEntitySyncAction;
+import org.apache.cayenne.modeler.action.PasteAction;
 import org.apache.cayenne.modeler.action.RemoveRelationshipAction;
 import org.apache.cayenne.modeler.dialog.ResolveDbRelationshipDialog;
 import org.apache.cayenne.modeler.editor.ExistingSelectionProcessor;
@@ -60,7 +63,6 @@
 import org.apache.cayenne.modeler.event.EntityDisplayEvent;
 import org.apache.cayenne.modeler.event.RelationshipDisplayEvent;
 import org.apache.cayenne.modeler.event.TablePopupHandler;
-import org.apache.cayenne.modeler.util.CayenneAction;
 import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
 import org.apache.cayenne.modeler.util.CellRenderers;
@@ -139,10 +141,13 @@
 
         toolBar.addSeparator();
 
-        toolBar
-                .add(app
-                        .getAction(RemoveRelationshipAction.getActionName())
-                        .buildButton());
+        toolBar.add(app.getAction(RemoveRelationshipAction.getActionName()).buildButton());
+        
+        toolBar.addSeparator();
+        toolBar.add(app.getAction(CutRelationshipAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(CopyRelationshipAction.getActionName()).buildButton());
+        toolBar.add(app.getAction(PasteAction.getActionName()).buildButton());
+        
         add(toolBar, BorderLayout.NORTH);
 
         table = new CayenneTable();
@@ -157,9 +162,17 @@
         popup.add(resolveMenu);
         popup.add(app.getAction(RemoveRelationshipAction.getActionName()).buildMenu());
         
+        popup.addSeparator();
+        popup.add(app.getAction(CutRelationshipAction.getActionName()).buildMenu());
+        popup.add(app.getAction(CopyRelationshipAction.getActionName()).buildMenu());
+        popup.add(app.getAction(PasteAction.getActionName()).buildMenu());
+        
         TablePopupHandler.install(table, popup);
 
         add(PanelFactory.createTablePanel(table, null), BorderLayout.CENTER);
+        
+        mediator.getApplication().getActionManager().setupCCP(table, 
+                CutRelationshipAction.getActionName(), CopyRelationshipAction.getActionName());
     }
 
     public void valueChanged(ListSelectionEvent e) {
@@ -180,17 +193,10 @@
      * Selects a specified relationship in the relationships table.
      */
     public void selectRelationships(DbRelationship[] rels) {
-        CayenneAction removeAction = Application
-            .getInstance()
-            .getAction(RemoveRelationshipAction.getActionName());
-        
-        if (rels.length == 0) {
-            removeAction.setEnabled(false);
-            return;
-        }
-        // enable the remove button
-        removeAction.setEnabled(true);
-        removeAction.setName(RemoveRelationshipAction.getActionName(rels.length > 1));
+        ModelerUtil.updateActions(rels.length,  
+                RemoveRelationshipAction.getActionName(),
+                CutRelationshipAction.getActionName(),
+                CopyRelationshipAction.getActionName());
 
         DbRelationshipTableModel model = (DbRelationshipTableModel) table.getModel();
         

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneAction.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneAction.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneAction.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneAction.java Sun Oct  5 11:07:16 2008
@@ -20,6 +20,16 @@
 
 package org.apache.cayenne.modeler.util;
 
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenuItem;
+import javax.swing.KeyStroke;
+
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.dialog.ErrorDebugDialog;
@@ -27,9 +37,6 @@
 import org.apache.cayenne.project.ProjectPath;
 import org.apache.cayenne.util.Util;
 
-import javax.swing.*;
-import java.awt.event.ActionEvent;
-
 /**
  * Superclass of CayenneModeler actions that implements support for some common
  * functionality, exception handling, etc.

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTransferable.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTransferable.java?rev=701839&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTransferable.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTransferable.java Sun Oct  5 11:07:16 2008
@@ -0,0 +1,91 @@
+/*****************************************************************
+ *   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.util;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.util.List;
+
+import org.apache.cayenne.util.XMLEncoder;
+import org.apache.cayenne.util.XMLSerializable;
+
+/**
+ * CayenneTransferable is a data holder of Cayenne object(s), like
+ * Entities, Attributes, Relationships etc.
+ * @author Andrey Razumovsky
+ */
+public class CayenneTransferable implements Transferable {
+    /**
+     * Flavor used for copy-paste between Cayenne Modeler applications
+     */
+    public static final DataFlavor CAYENNE_FLAVOR = new DataFlavor(Serializable.class, "Cayenne Object");
+    
+    /**
+     * Supported flavors
+     */
+    private static final DataFlavor[] FLAVORS = new DataFlavor[] { CAYENNE_FLAVOR, DataFlavor.stringFlavor };
+    
+    /**
+     * Data in the buffer
+     */
+    private Object data;
+    
+    public CayenneTransferable(Object data) {
+        this.data = data;
+    }
+
+    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException,
+            IOException {
+        
+        if (flavor == CAYENNE_FLAVOR) {
+            return data;
+        }
+        else {
+            StringWriter out = new StringWriter();
+            XMLEncoder encoder = new XMLEncoder(new PrintWriter(out), "\t");
+            encoder.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
+            
+            if (data instanceof XMLSerializable) {
+                ((XMLSerializable) data).encodeAsXML(encoder);
+            }
+            else if (data instanceof List) {
+                for (Object o : (List) data) {
+                    ((XMLSerializable) o).encodeAsXML(encoder);
+                }
+            }
+            
+            return out.toString();
+        }
+        
+    }
+
+    public DataFlavor[] getTransferDataFlavors() {
+        return FLAVORS;
+    }
+
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        return flavor == CAYENNE_FLAVOR || flavor == DataFlavor.stringFlavor;
+    }
+
+}

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java?rev=701839&r1=701838&r2=701839&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/ModelerUtil.java Sun Oct  5 11:07:16 2008
@@ -37,8 +37,10 @@
 import org.apache.cayenne.access.types.ExtendedTypeMap;
 import org.apache.cayenne.map.DataMap;
 import org.apache.cayenne.map.DbEntity;
+import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.ModelerConstants;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.action.MultipleObjectsAction;
 import org.apache.cayenne.reflect.PropertyUtils;
 import org.apache.cayenne.util.CayenneMapEntry;
 
@@ -159,4 +161,19 @@
 
         return null;
     }
+    
+    /**
+     * Updates MultipleObjectActions' state, depending on number of selected objects
+     * (attributes, rel etc.)
+     */
+    public static void updateActions(int numSelected, String... actionNames) {
+        for (int i = 0; i < actionNames.length; i++) {
+            CayenneAction action = Application.getInstance().getAction(actionNames[i]);
+            
+            if (action instanceof MultipleObjectsAction) {
+                action.setEnabled(numSelected > 0);
+                action.setName(((MultipleObjectsAction) action).getActionName(numSelected > 1));
+            }
+        }
+    }
 }

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-copy.gif
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-copy.gif?rev=701839&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-copy.gif
------------------------------------------------------------------------------
    svn:executable = *

Propchange: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-copy.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-cut.gif
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-cut.gif?rev=701839&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-cut.gif
------------------------------------------------------------------------------
    svn:executable = *

Propchange: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-cut.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-paste.gif
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-paste.gif?rev=701839&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-paste.gif
------------------------------------------------------------------------------
    svn:executable = *

Propchange: cayenne/main/trunk/framework/cayenne-modeler/src/main/resources/org/apache/cayenne/modeler/images/icon-paste.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream



Mime
View raw message