Coverage Report - org.argouml.uml.diagram.activity.ui.FigObjectFlowState
 
Classes in this File Line Coverage Branch Coverage Complexity
FigObjectFlowState
0%
0/116
0%
0/24
1.5
 
 1  
 /* $Id: FigObjectFlowState.java 18852 2010-11-20 19:27:11Z mvw $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009-2010 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  
  *    Michiel van der Wulp
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2009 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.activity.ui;
 40  
 
 41  
 import java.awt.Color;
 42  
 import java.awt.Dimension;
 43  
 import java.awt.Rectangle;
 44  
 import java.beans.PropertyChangeEvent;
 45  
 import java.beans.PropertyVetoException;
 46  
 import java.util.Collection;
 47  
 import java.util.HashSet;
 48  
 import java.util.Iterator;
 49  
 import java.util.Set;
 50  
 
 51  
 import org.argouml.model.Model;
 52  
 import org.argouml.notation.Notation;
 53  
 import org.argouml.notation.NotationName;
 54  
 import org.argouml.notation.NotationProvider;
 55  
 import org.argouml.notation.NotationProviderFactory2;
 56  
 import org.argouml.notation.NotationSettings;
 57  
 import org.argouml.uml.diagram.DiagramSettings;
 58  
 import org.argouml.uml.diagram.ui.FigNodeModelElement;
 59  
 import org.argouml.uml.diagram.ui.FigSingleLineText;
 60  
 import org.tigris.gef.base.LayerPerspective;
 61  
 import org.tigris.gef.base.Selection;
 62  
 import org.tigris.gef.presentation.Fig;
 63  
 import org.tigris.gef.presentation.FigRect;
 64  
 import org.tigris.gef.presentation.FigText;
 65  
 
 66  
 
 67  
 /**
 68  
  * Class to display graphics for a UML ObjectFlowState in a diagram.<p>
 69  
  *
 70  
  * The Fig of this modelElement may either represent the following UMLelements:
 71  
  * <p>
 72  
  * (1) an ObjectFlowState with a Classifier as type, or <p>
 73  
  * (2) an ObjectFlowState with a ClassifierInState as type. <p>
 74  
  *
 75  
  * In both cases (1) and (2), the Fig shows
 76  
  * the underlined name of the Classifier,
 77  
  * and in the latter case (2), it shows also the names of the states
 78  
  * of the ClassifierInState. <p>
 79  
  *
 80  
  * In the examples in the UML standard, this is written like<pre>
 81  
  *      PurchaseOrder
 82  
  *       [approved]
 83  
  * </pre>
 84  
  * i.e. in 2 lines. The first line is underlined,
 85  
  * to indicate that it is an instance (object).<p>
 86  
  *
 87  
  * The fact that the first line is underlined, and the 2nd not, is the
 88  
  * reason to implement them in 2 separate Figs.<p>
 89  
  *
 90  
  * TODO: Allow stereotypes to be shown.
 91  
  *
 92  
  * @author mvw
 93  
  */
 94  
 public class FigObjectFlowState extends FigNodeModelElement {
 95  
 
 96  
     private static final int PADDING = 8;
 97  
     private static final int OFS_WIDTH = 70;
 98  
     private static final int HEIGHT = 50;
 99  
     private static final int STATE_HEIGHT = NAME_FIG_HEIGHT;
 100  
 
 101  
     private NotationProvider notationProviderState;
 102  
     
 103  
     private FigRect cover;
 104  
     private FigText state;      // the state name
 105  
 
 106  
     
 107  
     /**
 108  
      * Construct a new FigObjectFlowState.
 109  
      * 
 110  
      * @param owner owning UML element
 111  
      * @param bounds position and size
 112  
      * @param settings rendering settings
 113  
      */
 114  
     public FigObjectFlowState(Object owner, Rectangle bounds,
 115  
             DiagramSettings settings) {
 116  0
         super(owner, bounds, settings);
 117  0
         state = new FigSingleLineText(owner, new Rectangle(X0, Y0, OFS_WIDTH,
 118  
                 STATE_HEIGHT), settings, true);
 119  0
         initFigs(bounds);
 120  0
     }
 121  
 
 122  
     private void initFigs(Rectangle bounds) {
 123  0
         cover =
 124  
             new FigRect(X0, Y0, OFS_WIDTH, HEIGHT,
 125  
                     LINE_COLOR, FILL_COLOR);
 126  
 
 127  0
         getNameFig().setUnderline(true);
 128  0
         getNameFig().setLineWidth(0);
 129  
 
 130  
         // add Figs to the FigNode in back-to-front order
 131  0
         addFig(getBigPort());
 132  0
         addFig(cover);
 133  0
         addFig(getNameFig());
 134  0
         addFig(state);
 135  
 
 136  0
         enableSizeChecking(false);
 137  
 
 138  
         /* Set the drop location in the case of D&D: */
 139  0
         if (bounds != null) {
 140  0
             setLocation(bounds.x, bounds.y);
 141  
         }
 142  
 
 143  0
         renderingChanged();
 144  0
         setSuppressCalcBounds(false);
 145  0
         setBounds(getBounds());
 146  0
         enableSizeChecking(true);
 147  0
     }
 148  
 
 149  
     /*
 150  
      * @see org.argouml.uml.diagram.ui.FigNodeModelElement#initNotationProviders(java.lang.Object)
 151  
      */
 152  
     @Override
 153  
     protected void initNotationProviders(Object own) {
 154  0
         super.initNotationProviders(own);
 155  0
         if (Model.getFacade().isAModelElement(own)) {
 156  0
             NotationName notationName = Notation
 157  
                     .findNotation(getNotationSettings().getNotationLanguage());
 158  0
             notationProviderState =
 159  
                 NotationProviderFactory2.getInstance().getNotationProvider(
 160  
                         NotationProviderFactory2.TYPE_OBJECTFLOWSTATE_STATE,
 161  
                         own, this, notationName);
 162  
         }
 163  0
     }
 164  
     
 165  
     protected int getNotationProviderType() {
 166  0
         return NotationProviderFactory2.TYPE_OBJECTFLOWSTATE_TYPE;
 167  
     }
 168  
 
 169  
     @Override
 170  
     protected void modelChanged(PropertyChangeEvent mee) {
 171  0
         super.modelChanged(mee);
 172  
         // TODO: Rather than specifically ignore some item maybe it would be better
 173  
         // to specifically state what items are of interest. Otherwise we may still
 174  
         // be acting on other events we don't need
 175  0
         if (!Model.getFacade().isATransition(mee.getNewValue())) {
 176  0
             renderingChanged();
 177  0
             updateListeners(getOwner(), getOwner());
 178  
         }
 179  0
     }
 180  
 
 181  
     @Override
 182  
     protected void updateListeners(Object oldOwner, Object newOwner) {
 183  0
         Set<Object[]> l = new HashSet<Object[]>();
 184  
 
 185  0
         if (newOwner != null) {
 186  
             /* Don't listen to all property names
 187  
              * We only need to listen to its "type", and "remove". */
 188  0
             l.add(new Object[] {newOwner, new String[] {"type", "remove"}});
 189  
             // register for events from the type
 190  0
             Object type = Model.getFacade().getType(newOwner);
 191  0
             if (Model.getFacade().isAClassifier(type)) {
 192  0
                 if (Model.getFacade().isAClassifierInState(type)) {
 193  0
                     Object classifier = Model.getFacade().getType(type);
 194  0
                     l.add(new Object[] {classifier, "name"});
 195  0
                     l.add(new Object[] {type, "inState"});
 196  0
                     Collection states = Model.getFacade().getInStates(type);
 197  0
                     Iterator i = states.iterator();
 198  0
                     while (i.hasNext()) {
 199  0
                         l.add(new Object[] {i.next(), "name"});
 200  
                     }
 201  0
                 } else {
 202  0
                     l.add(new Object[] {type, "name"});
 203  
                 }
 204  
             }
 205  
         }
 206  
 
 207  0
         updateElementListeners(l);
 208  0
     }
 209  
 
 210  
     @Override
 211  
     public Object clone() {
 212  0
         FigObjectFlowState figClone = (FigObjectFlowState) super.clone();
 213  0
         Iterator it = figClone.getFigs().iterator();
 214  0
         figClone.setBigPort((FigRect) it.next());
 215  0
         figClone.cover = (FigRect) it.next();
 216  0
         figClone.setNameFig((FigText) it.next());
 217  0
         figClone.state = (FigText) it.next();
 218  0
         return figClone;
 219  
     }
 220  
 
 221  
     @Override
 222  
     public void setEnclosingFig(Fig encloser) {
 223  0
         LayerPerspective layer = (LayerPerspective) getLayer();
 224  
         // If the layer is null, then most likely we are being deleted.
 225  0
         if (layer == null) {
 226  0
             return;
 227  
         }
 228  
 
 229  0
         super.setEnclosingFig(encloser);
 230  0
     }
 231  
 
 232  
     /*
 233  
      * The space between the 2 text figs is: PADDING.
 234  
      * @see org.tigris.gef.presentation.Fig#getMinimumSize()
 235  
      */
 236  
     @Override
 237  
     public Dimension getMinimumSize() {
 238  0
         Dimension tempDim = getNameFig().getMinimumSize();
 239  0
         int w = tempDim.width + PADDING * 2;
 240  0
         int h = tempDim.height + PADDING;
 241  0
         tempDim = state.getMinimumSize();
 242  0
         w = Math.max(w, tempDim.width + PADDING * 2);
 243  0
         h = h + PADDING + tempDim.height + PADDING;
 244  
 
 245  0
         return new Dimension(Math.max(w, OFS_WIDTH / 2), Math.max(h, HEIGHT / 2));
 246  
     }
 247  
 
 248  
     /*
 249  
      * Override setBounds to keep shapes looking right.
 250  
      * The classifier and state Figs are nicely centered vertically,
 251  
      * and stretched out over the full width,
 252  
      * to allow easy selection with the mouse.
 253  
      * The Fig can only be shrunk to half its original size - so that
 254  
      * it is not reducible to a few pixels only.
 255  
      *
 256  
      * @see org.tigris.gef.presentation.Fig#setBoundsImpl(int, int, int, int)
 257  
      */
 258  
     @Override
 259  
     protected void setStandardBounds(int x, int y, int w, int h) {
 260  0
         Rectangle oldBounds = getBounds();
 261  
 
 262  0
         Dimension classDim = getNameFig().getMinimumSize();
 263  0
         Dimension stateDim = state.getMinimumSize();
 264  
         /* the height of the blank space above and below the text figs: */
 265  0
         int blank = (h - PADDING - classDim.height - stateDim.height) / 2;
 266  0
         getNameFig().setBounds(x + PADDING,
 267  
                 y + blank,
 268  
                 w - PADDING * 2,
 269  
                 classDim.height);
 270  0
         state.setBounds(x + PADDING,
 271  
                 y + blank + classDim.height + PADDING,
 272  
                 w - PADDING * 2,
 273  
                 stateDim.height);
 274  
 
 275  0
         getBigPort().setBounds(x, y, w, h);
 276  0
         cover.setBounds(x, y, w, h);
 277  
 
 278  0
         calcBounds();
 279  0
         updateEdges();
 280  0
         firePropChange("bounds", oldBounds, getBounds());
 281  0
     }
 282  
 
 283  
     /*
 284  
      * @see org.argouml.uml.diagram.ui.FigNodeModelElement#renderingChanged()
 285  
      */
 286  
     @Override
 287  
     public void renderingChanged() {
 288  0
         super.renderingChanged();
 289  0
         updateStateText();
 290  0
         updateBounds();
 291  0
         damage();
 292  0
     }
 293  
 
 294  
     /**
 295  
      * Updates the text of the state FigText.
 296  
      */
 297  
     private void updateStateText() {
 298  0
         if (isReadyToEdit()) {
 299  0
             state.setText(notationProviderState.toString(getOwner(), 
 300  
                     getNotationSettings()));
 301  
         }
 302  0
     }
 303  
 
 304  
     /*
 305  
      * @see org.tigris.gef.presentation.Fig#setLineColor(java.awt.Color)
 306  
      */
 307  
     @Override
 308  
     public void setLineColor(Color col) {
 309  0
         cover.setLineColor(col);
 310  0
     }
 311  
 
 312  
     /*
 313  
      * @see org.tigris.gef.presentation.Fig#getLineColor()
 314  
      */
 315  
     @Override
 316  
     public Color getLineColor() {
 317  0
         return cover.getLineColor();
 318  
     }
 319  
 
 320  
     /*
 321  
      * @see org.tigris.gef.presentation.Fig#setFillColor(java.awt.Color)
 322  
      */
 323  
     @Override
 324  
     public void setFillColor(Color col) {
 325  0
         cover.setFillColor(col);
 326  0
     }
 327  
 
 328  
     /*
 329  
      * @see org.tigris.gef.presentation.Fig#getFillColor()
 330  
      */
 331  
     @Override
 332  
     public Color getFillColor() {
 333  0
         return cover.getFillColor();
 334  
     }
 335  
 
 336  
     /*
 337  
      * @see org.tigris.gef.presentation.Fig#setFilled(boolean)
 338  
      */
 339  
     @Override
 340  
     public void setFilled(boolean f) {
 341  0
         cover.setFilled(f);
 342  0
     }
 343  
 
 344  
     @Override
 345  
     public boolean isFilled() {
 346  0
         return cover.isFilled();
 347  
     }
 348  
 
 349  
     /*
 350  
      * @see org.tigris.gef.presentation.Fig#setLineWidth(int)
 351  
      */
 352  
     @Override
 353  
     public void setLineWidth(int w) {
 354  0
         cover.setLineWidth(w);
 355  0
     }
 356  
 
 357  
     /*
 358  
      * @see org.tigris.gef.presentation.Fig#getLineWidth()
 359  
      */
 360  
     @Override
 361  
     public int getLineWidth() {
 362  0
         return cover.getLineWidth();
 363  
     }
 364  
 
 365  
     /*
 366  
      * @see org.argouml.uml.diagram.ui.FigNodeModelElement#textEdited(org.tigris.gef.presentation.FigText)
 367  
      */
 368  
     @Override
 369  
     protected void textEdited(FigText ft) throws PropertyVetoException {
 370  0
         super.textEdited(ft);
 371  0
         if (ft == state) {
 372  0
             notationProviderState.parse(getOwner(), ft.getText());
 373  0
             ft.setText(notationProviderState.toString(getOwner(),
 374  
                     getNotationSettings()));
 375  
         }
 376  0
     }
 377  
 
 378  
     /*
 379  
      * @see org.argouml.uml.diagram.ui.FigNodeModelElement#textEditStarted(org.tigris.gef.presentation.FigText)
 380  
      */
 381  
     @Override
 382  
     protected void textEditStarted(FigText ft) {
 383  0
         super.textEditStarted(ft);
 384  0
         if (ft == state) {
 385  0
             showHelp(notationProviderState.getParsingHelp());
 386  
         }
 387  0
     }
 388  
 
 389  
     /*
 390  
      * @see org.tigris.gef.presentation.Fig#makeSelection()
 391  
      */
 392  
     @Override
 393  
     public Selection makeSelection() {
 394  0
         return new SelectionActionState(this);
 395  
     }
 396  
 
 397  
     public void notationRenderingChanged(NotationProvider np, String rendering) {
 398  0
         super.notationRenderingChanged(np, rendering);
 399  0
         if (notationProviderState == np) {
 400  0
             state.setText(rendering);
 401  0
             updateBounds();
 402  0
             damage();
 403  
         }
 404  0
     }
 405  
 
 406  
     public NotationSettings getNotationSettings(NotationProvider np) {
 407  
         // both have the same settings
 408  0
         return getNotationSettings();
 409  
     }
 410  
 
 411  
     public Object getOwner(NotationProvider np) {
 412  
         // both have the same owner
 413  0
         return getOwner();
 414  
     }
 415  
 
 416  
 }