Coverage Report - org.argouml.uml.ui.ActionDeleteModelElements
 
Classes in this File Line Coverage Branch Coverage Complexity
ActionDeleteModelElements
54%
52/96
35%
24/68
4.8
ActionDeleteModelElements$1
77%
7/9
N/A
4.8
 
 1  
 /* $Id: ActionDeleteModelElements.java 17881 2010-01-12 21:09:28Z linus $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    bobtarling
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2007 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies.  This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason.  IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.uml.ui;
 40  
 
 41  
 import java.awt.Component;
 42  
 import java.awt.KeyboardFocusManager;
 43  
 import java.awt.event.ActionEvent;
 44  
 import java.text.MessageFormat;
 45  
 import java.util.List;
 46  
 
 47  
 import javax.swing.Action;
 48  
 import javax.swing.JOptionPane;
 49  
 import javax.swing.JTable;
 50  
 import javax.swing.table.TableCellEditor;
 51  
 
 52  
 import org.apache.log4j.Logger;
 53  
 import org.argouml.application.helpers.ResourceLoaderWrapper;
 54  
 import org.argouml.i18n.Translator;
 55  
 import org.argouml.kernel.Project;
 56  
 import org.argouml.kernel.ProjectManager;
 57  
 import org.argouml.kernel.UmlModelMutator;
 58  
 import org.argouml.model.InvalidElementException;
 59  
 import org.argouml.model.Model;
 60  
 import org.argouml.ui.targetmanager.TargetEvent;
 61  
 import org.argouml.ui.targetmanager.TargetListener;
 62  
 import org.argouml.ui.targetmanager.TargetManager;
 63  
 import org.argouml.uml.CommentEdge;
 64  
 import org.argouml.uml.diagram.ArgoDiagram;
 65  
 import org.argouml.util.ArgoFrame;
 66  
 import org.tigris.gef.base.Editor;
 67  
 import org.tigris.gef.base.Globals;
 68  
 import org.tigris.gef.presentation.Fig;
 69  
 import org.tigris.gef.presentation.FigTextEditor;
 70  
 import org.argouml.ui.UndoableAction;
 71  
 
 72  
 /**
 73  
  * Action for removing objects from the model. 
 74  
  * Objects can be Modelelements, Diagrams (argodiagram and it's children),
 75  
  * Figs without owner,... 
 76  
  */
 77  
 @UmlModelMutator
 78  2654
 public class ActionDeleteModelElements extends UndoableAction {
 79  
 
 80  
     /**
 81  
      * Generated serial version for rev 1.4
 82  
      */
 83  
     private static final long serialVersionUID = -5728400220151823726L;
 84  
 
 85  
     private static ActionDeleteModelElements targetFollower;
 86  
 
 87  
     public static ActionDeleteModelElements getTargetFollower() {
 88  4089
         if (targetFollower == null) {
 89  900
             targetFollower  = new ActionDeleteModelElements();
 90  900
             TargetManager.getInstance().addTargetListener(new TargetListener() {
 91  
                 public void targetAdded(TargetEvent e) {
 92  0
                     setTarget();
 93  0
                 }
 94  
                 public void targetRemoved(TargetEvent e) {
 95  88
                     setTarget();
 96  88
                 }
 97  
 
 98  
                 public void targetSet(TargetEvent e) {
 99  1239
                     setTarget();
 100  1239
                 }
 101  
                 private void setTarget() {
 102  1327
                     targetFollower.setEnabled(targetFollower.shouldBeEnabled());
 103  1327
                 }
 104  
             });
 105  900
             targetFollower.setEnabled(targetFollower.shouldBeEnabled());
 106  
         }
 107  4089
         return targetFollower;
 108  
     }
 109  
     
 110  900
     private static final Logger LOG =
 111  
         Logger.getLogger(ActionDeleteModelElements.class);
 112  
 
 113  
     /**
 114  
      * Constructor.
 115  
      */
 116  
     public ActionDeleteModelElements() {
 117  900
         super(Translator.localize("action.delete-from-model"),
 118  
                 ResourceLoaderWrapper.lookupIcon("action.delete-from-model"));
 119  
         // Set the tooltip string:
 120  900
         putValue(Action.SHORT_DESCRIPTION, 
 121  
                 Translator.localize("action.delete-from-model"));
 122  900
         putValue(Action.SMALL_ICON,
 123  
                 ResourceLoaderWrapper.lookupIcon("Delete"));
 124  900
     }
 125  
 
 126  
     /*
 127  
      * @see java.awt.event.ActionListener#actionPerformed(ActionEvent)
 128  
      */
 129  
     public void actionPerformed(ActionEvent ae) {
 130  38
         super.actionPerformed(ae);
 131  38
         KeyboardFocusManager focusManager =
 132  
             KeyboardFocusManager.getCurrentKeyboardFocusManager();
 133  38
         Component focusOwner = focusManager.getFocusOwner();
 134  38
         if (focusOwner instanceof FigTextEditor) {
 135  
             // TODO: Probably really want to cancel editing
 136  
             //((FigTextEditor) focusOwner).cancelEditing();
 137  0
             ((FigTextEditor) focusOwner).endEditing();
 138  38
         } else if (focusOwner instanceof JTable) {
 139  0
             JTable table = (JTable) focusOwner;
 140  0
             if (table.isEditing()) {
 141  0
                 TableCellEditor ce = table.getCellEditor();
 142  0
                 if (ce != null) {
 143  0
                     ce.cancelCellEditing();
 144  
                 }
 145  
             }
 146  
         }
 147  
 
 148  38
         Project p = ProjectManager.getManager().getCurrentProject();
 149  38
         Object[] targets = TargetManager.getInstance().getTargets().toArray();
 150  
         /* This next line fixes issue 4276: */
 151  38
         TargetManager.getInstance().setTarget(null);
 152  38
         Object target = null;
 153  76
         for (int i = targets.length - 1; i >= 0; i--) {
 154  38
             target = targets[i];
 155  
             try {
 156  38
                 if (sureRemove(target)) {
 157  
                     // remove from the model
 158  38
                     if (target instanceof Fig) {
 159  0
                         Object owner = ((Fig) target).getOwner();
 160  0
                         if (owner != null) {
 161  0
                             target = owner;
 162  
                         }
 163  
                     }
 164  38
                     p.moveToTrash(target);
 165  
                 }
 166  0
             } catch (InvalidElementException e) {
 167  0
                 LOG.debug("Model element deleted twice - ignoring 2nd delete");
 168  38
             }
 169  
         }
 170  38
     }
 171  
 
 172  
     /**
 173  
      * A utility method that asks the user if he is sure to remove the selected
 174  
      * target.<p>
 175  
      *
 176  
      * @param target the object that will be removed
 177  
      * @return boolean
 178  
      */
 179  
     public static boolean sureRemove(Object target) {
 180  
         // usage of other sureRemove method is legacy. They should be
 181  
         // integrated.
 182  38
         boolean sure = false;
 183  38
         if (Model.getFacade().isAModelElement(target)) {
 184  0
             sure = sureRemoveModelElement(target);
 185  38
         } else if (Model.getFacade().isAUMLElement(target)) {
 186  
             // It is a UML element that is not a ModelElement
 187  0
             sure = true;
 188  38
         } else if (target instanceof ArgoDiagram) {
 189  
             // lets see if this diagram has some figs on it
 190  38
             ArgoDiagram diagram = (ArgoDiagram) target;
 191  38
             if (diagram.getNodes().size() + diagram.getEdges().size() != 0) {
 192  
                 // the diagram contains figs so lets ask the user if
 193  
                 // he/she is sure
 194  0
                 String confirmStr =
 195  
                     MessageFormat.format(Translator.localize(
 196  
                         "optionpane.remove-from-model-confirm-delete"),
 197  
                         new Object[] {
 198  
                             diagram.getName(), "",
 199  
                         });
 200  0
                 String text =
 201  
                     Translator.localize(
 202  
                         "optionpane.remove-from-model-confirm-delete-title");
 203  0
                 int response =
 204  
                     JOptionPane.showConfirmDialog(ArgoFrame.getFrame(),
 205  
                           confirmStr,
 206  
                           text,
 207  
                           JOptionPane.YES_NO_OPTION);
 208  0
                 sure = (response == JOptionPane.YES_OPTION);
 209  0
             } else { // no content of diagram
 210  38
                 sure = true;
 211  
             }
 212  38
         } else if (target instanceof Fig) {
 213  
             // we can delete figs like figrects now too
 214  0
             if (Model.getFacade().isAModelElement(((Fig) target).getOwner())) {
 215  0
                 sure = sureRemoveModelElement(((Fig) target).getOwner());
 216  
             } else {
 217  0
                 sure = true;
 218  
             }
 219  0
         } else if (target instanceof CommentEdge) {
 220  
             // we can delete CommentEdge now too thanks to issue 3643.
 221  0
             sure = true;
 222  
         }
 223  38
         return sure;
 224  
     }
 225  
 
 226  
     /**
 227  
      * An utility method that asks the user if he is sure to remove a selected
 228  
      * model element.
 229  
      *
 230  
      * @param me the modelelement that may be removed
 231  
      * @return boolean
 232  
      */
 233  
     protected static boolean sureRemoveModelElement(Object me) {
 234  0
         Project p = ProjectManager.getManager().getCurrentProject();
 235  
 
 236  0
         int count = p.getPresentationCountFor(me);
 237  
 
 238  0
         boolean doAsk = false;
 239  0
         String confirmStr = "";
 240  0
         if (count > 1) {
 241  0
             confirmStr += Translator.localize(
 242  
                 "optionpane.remove-from-model-will-remove-from-diagrams");
 243  0
             doAsk = true;
 244  
         }
 245  
 
 246  
         /* TODO: If a namespace with sub-classdiagrams is deleted, then { 
 247  
             confirmStr +=
 248  
                 Translator.localize(
 249  
                     "optionpane.remove-from-model-will-remove-subdiagram");
 250  
             doAsk = true;
 251  
         }*/
 252  
 
 253  0
         if (!doAsk) {
 254  0
             return true;
 255  
         }
 256  
 
 257  0
         String name = Model.getFacade().getName(me);
 258  0
         if (name == null || name.equals("")) {
 259  0
             name = Translator.localize(
 260  
                 "optionpane.remove-from-model-anon-element-name");
 261  
         }
 262  
 
 263  0
         confirmStr =
 264  
             MessageFormat.format(Translator.localize(
 265  
                 "optionpane.remove-from-model-confirm-delete"),
 266  
                 new Object[] {
 267  
                     name, confirmStr,
 268  
                 });
 269  0
         int response =
 270  
             JOptionPane.showConfirmDialog(
 271  
                     ArgoFrame.getFrame(),
 272  
                     confirmStr,
 273  
                     Translator.localize(
 274  
                     "optionpane.remove-from-model-confirm-delete-title"),
 275  
                     JOptionPane.YES_NO_OPTION);
 276  
 
 277  0
         return (response == JOptionPane.YES_OPTION);
 278  
     }
 279  
     
 280  
     /**
 281  
      * @return true if the tool should be enabled
 282  
      */
 283  
     public boolean shouldBeEnabled() {
 284  2227
         List targets = TargetManager.getInstance().getTargets();
 285  2227
         for (Object target : targets) {
 286  1201
             if (Model.getFacade().isAModelElement(target)
 287  
                     && Model.getModelManagementHelper().isReadOnly(target)) {
 288  0
                 return false;
 289  
             }
 290  
         }
 291  
         
 292  2227
         int size = 0;
 293  
         try {
 294  2227
             Editor ce = Globals.curEditor();
 295  2227
             List<Fig> figs = ce.getSelectionManager().getFigs();
 296  2227
             size = figs.size();
 297  0
         } catch (Exception e) {
 298  
             // TODO: This catch block needs to be narrower and do something
 299  
             // with the caught exception - tfm 20071120
 300  
             // Ignore
 301  2227
         }
 302  2227
         if (size > 0) {
 303  0
             return true;
 304  
         }
 305  
         // TODO: All of the following can be broken if we have multiple
 306  
         // targets selected
 307  2227
         Object target = TargetManager.getInstance().getTarget();
 308  2227
         if (target instanceof ArgoDiagram) { 
 309  
             // we cannot delete the last diagram
 310  1201
             return (ProjectManager.getManager().getCurrentProject()
 311  
                 .getDiagramList().size() > 1);
 312  
         }
 313  1026
         if (Model.getFacade().isAModel(target)
 314  
         // we cannot delete the model itself
 315  
             && target.equals(ProjectManager.getManager().getCurrentProject()
 316  
                  .getModel())) {
 317  0
             return false;
 318  
         }
 319  1026
         if (Model.getFacade().isAAssociationEnd(target)) {
 320  0
             return Model.getFacade().getOtherAssociationEnds(target).size() > 1;
 321  
         }
 322  1026
         if (Model.getStateMachinesHelper().isTopState(target)) {
 323  
             /* we can not delete a "top" state,
 324  
              * it comes and goes with the statemachine. Issue 2655.
 325  
              */
 326  0
             return false;
 327  
         }
 328  1026
         return target != null;
 329  
     }
 330  
 }