Coverage Report - org.argouml.uml.diagram.ui.ActionAddNote
 
Classes in this File Line Coverage Branch Coverage Complexity
ActionAddNote
6%
4/64
0%
0/32
8
 
 1  
 /* $Id: ActionAddNote.java 17865 2010-01-12 20:45:26Z 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-2008 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.diagram.ui;
 40  
 
 41  
 import java.awt.Point;
 42  
 import java.awt.Rectangle;
 43  
 import java.awt.event.ActionEvent;
 44  
 import java.util.Collection;
 45  
 import java.util.Iterator;
 46  
 
 47  
 import javax.swing.Action;
 48  
 
 49  
 import org.argouml.application.helpers.ResourceLoaderWrapper;
 50  
 import org.argouml.i18n.Translator;
 51  
 import org.argouml.kernel.UmlModelMutator;
 52  
 import org.argouml.model.Model;
 53  
 import org.argouml.ui.ProjectBrowser;
 54  
 import org.argouml.ui.targetmanager.TargetManager;
 55  
 import org.argouml.uml.CommentEdge;
 56  
 import org.argouml.uml.diagram.ArgoDiagram;
 57  
 import org.argouml.uml.diagram.DiagramUtils;
 58  
 import org.tigris.gef.graph.MutableGraphModel;
 59  
 import org.tigris.gef.presentation.Fig;
 60  
 import org.tigris.gef.presentation.FigEdge;
 61  
 import org.tigris.gef.presentation.FigNode;
 62  
 import org.tigris.gef.presentation.FigPoly;
 63  
 import org.argouml.ui.UndoableAction;
 64  
 
 65  
 /**
 66  
  * Action to add a note aka comment. This action adds a Comment to 0..*
 67  
  * modelelements. <p>
 68  
  *
 69  
  * The modelelements that are present on the current diagram, are connected
 70  
  * graphically. All others are only annotated in the model.
 71  
  */
 72  
 @UmlModelMutator
 73  
 public class ActionAddNote extends UndoableAction {
 74  
 
 75  
     /**
 76  
      * The default position (x and y) of the new fig.
 77  
      */
 78  
     private static final int DEFAULT_POS = 20;
 79  
 
 80  
     /**
 81  
      * The distance (x and y) from other figs where we place this.
 82  
      */
 83  
     private static final int DISTANCE = 80;
 84  
 
 85  
     /**
 86  
      * The constructor. This action is not global, since it is never disabled.
 87  
      */
 88  
     public ActionAddNote() {
 89  900
         super(Translator.localize("action.new-comment"),
 90  
                 ResourceLoaderWrapper.lookupIcon("action.new-comment"));
 91  
         // Set the tooltip string:
 92  900
         putValue(Action.SHORT_DESCRIPTION, 
 93  
                 Translator.localize("action.new-comment"));
 94  900
         putValue(Action.SMALL_ICON, ResourceLoaderWrapper
 95  
                 .lookupIconResource("New Note"));
 96  900
     }
 97  
 
 98  
 
 99  
     /*
 100  
      * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
 101  
      */
 102  
     @Override
 103  
     public void actionPerformed(ActionEvent ae) {
 104  0
         super.actionPerformed(ae); //update all tools' enabled status
 105  0
         Collection targets = TargetManager.getInstance().getModelTargets();
 106  
 
 107  
         //Let's build the comment first, unlinked.
 108  0
         ArgoDiagram diagram = DiagramUtils.getActiveDiagram();
 109  0
         Object comment =
 110  
             Model.getCoreFactory().buildComment(null,
 111  
                 diagram.getNamespace());
 112  0
         MutableGraphModel mgm = (MutableGraphModel) diagram.getGraphModel();
 113  
 
 114  
         //Now, we link it to the modelelements which are represented by FigNode
 115  0
         Object firstTarget = null;
 116  0
         Iterator i = targets.iterator();
 117  0
         while (i.hasNext()) {
 118  0
             Object obj = i.next();
 119  0
             Fig destFig = diagram.presentationFor(obj);
 120  0
             if (destFig instanceof FigEdgeModelElement) {
 121  0
                 FigEdgeModelElement destEdge = (FigEdgeModelElement) destFig;
 122  0
                 destEdge.makeEdgePort();
 123  0
                 destFig = destEdge.getEdgePort();
 124  0
                 destEdge.calcBounds();
 125  
             }
 126  0
             if (Model.getFacade().isAModelElement(obj)
 127  
                     && (!(Model.getFacade().isAComment(obj)))) {
 128  0
                 if (firstTarget == null) {
 129  0
                     firstTarget = obj;
 130  
                 }
 131  
                 /* Prevent e.g. AssociationClasses from being added trice: */
 132  0
                 if (!Model.getFacade().getAnnotatedElements(comment)
 133  
                         .contains(obj)) {
 134  0
                     Model.getCoreHelper().addAnnotatedElement(comment, obj);
 135  
                 }
 136  
             }
 137  0
         }
 138  
 
 139  
         //Create the Node Fig for the comment itself and draw it
 140  0
         mgm.addNode(comment);
 141  
         // remember the fig for later
 142  0
         Fig noteFig = diagram.presentationFor(comment);
 143  
 
 144  
         //Create the comment links and draw them
 145  0
         i = Model.getFacade().getAnnotatedElements(comment).iterator();
 146  0
         while (i.hasNext()) {
 147  0
             Object obj = i.next();
 148  0
             if (diagram.presentationFor(obj) != null) {
 149  0
                 CommentEdge commentEdge = new CommentEdge(comment, obj);
 150  0
                 mgm.addEdge(commentEdge);
 151  0
                 FigEdge fe = (FigEdge) diagram.presentationFor(commentEdge);
 152  0
                 FigPoly fp = (FigPoly) fe.getFig();
 153  0
                 fp.setComplete(true);
 154  
             }
 155  0
         }
 156  
 
 157  
         //Place the comment Fig on the nicest spot on the diagram
 158  0
         noteFig.setLocation(calculateLocation(diagram, firstTarget, noteFig));
 159  
 
 160  
         //Select the new comment as target
 161  0
         TargetManager.getInstance().setTarget(noteFig.getOwner());
 162  0
     }
 163  
 
 164  
     /**
 165  
      * Calculate the position of the comment, based on the 1st target only.
 166  
      *
 167  
      * @param diagram The Diagram that we are working in.
 168  
      * @param firstTarget The object element of the first found comment.
 169  
      * @param noteFig The Fig for the comment.
 170  
      * @return The position where it should be placed.
 171  
      */
 172  
     private Point calculateLocation(
 173  
             ArgoDiagram diagram, Object firstTarget, Fig noteFig) {
 174  0
         Point point = new Point(DEFAULT_POS, DEFAULT_POS);
 175  
 
 176  0
         if (firstTarget == null) {
 177  0
             return point;
 178  
         }
 179  
 
 180  0
         Fig elemFig = diagram.presentationFor(firstTarget);
 181  0
         if (elemFig == null) {
 182  0
             return point;
 183  
         }
 184  
 
 185  0
         if (elemFig instanceof FigEdgeModelElement) {
 186  0
             elemFig = ((FigEdgeModelElement) elemFig).getEdgePort();
 187  
         }
 188  
 
 189  0
         if (elemFig instanceof FigNode) {
 190  
             // TODO: We need a better algorithm.
 191  0
             point.x = elemFig.getX() + elemFig.getWidth() + DISTANCE;
 192  0
             point.y = elemFig.getY();
 193  
             // TODO: This can't depend on ProjectBrowser.  Alternate below
 194  0
             Rectangle drawingArea =
 195  
                 ProjectBrowser.getInstance().getEditorPane().getBounds();
 196  
             // Perhaps something like the following would work instead
 197  
 //            Rectangle drawingArea =
 198  
 //                Globals.curEditor().getJComponent().getVisibleRect();
 199  
             
 200  0
             if (point.x + noteFig.getWidth() > drawingArea.getX()) {
 201  0
                 point.x = elemFig.getX() - noteFig.getWidth() - DISTANCE;
 202  
 
 203  0
                 if (point.x >= 0) {
 204  0
                     return point;
 205  
                 }
 206  
 
 207  0
                 point.x = elemFig.getX();
 208  0
                 point.y = elemFig.getY() - noteFig.getHeight() - DISTANCE;
 209  0
                 if (point.y >= 0) {
 210  0
                     return point;
 211  
                 }
 212  
 
 213  0
                 point.y = elemFig.getY() + elemFig.getHeight() + DISTANCE;
 214  0
                 if (point.y + noteFig.getHeight() > drawingArea.getHeight()) {
 215  0
                     return new Point(0, 0);
 216  
                 }
 217  
             }
 218  
         }
 219  
 
 220  0
         return point;
 221  
     }
 222  
 
 223  
     /**
 224  
      * The UID.
 225  
      */
 226  
     private static final long serialVersionUID = 6502515091619480472L;
 227  
 }