Coverage Report - org.argouml.uml.diagram.state.ui.FigConcurrentRegion
 
Classes in this File Line Coverage Branch Coverage Complexity
FigConcurrentRegion
0%
0/191
0%
0/74
2.323
 
 1  
 /* $Id: FigConcurrentRegion.java 18612 2010-07-31 11:47:45Z bobtarling $
 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  
  *    mvw
 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.state.ui;
 40  
 
 41  
 import java.awt.Color;
 42  
 import java.awt.Dimension;
 43  
 import java.awt.Rectangle;
 44  
 import java.awt.event.MouseEvent;
 45  
 import java.awt.event.MouseListener;
 46  
 import java.awt.event.MouseMotionListener;
 47  
 import java.beans.PropertyChangeEvent;
 48  
 import java.util.Collection;
 49  
 import java.util.Iterator;
 50  
 import java.util.List;
 51  
 import java.util.Vector;
 52  
 
 53  
 import javax.swing.JSeparator;
 54  
 
 55  
 import org.argouml.model.Model;
 56  
 import org.argouml.model.UmlChangeEvent;
 57  
 import org.argouml.ui.ProjectActions;
 58  
 import org.argouml.uml.diagram.DiagramSettings;
 59  
 import org.argouml.uml.diagram.ui.ActionAddConcurrentRegion;
 60  
 import org.tigris.gef.base.Globals;
 61  
 import org.tigris.gef.base.Layer;
 62  
 import org.tigris.gef.base.Selection;
 63  
 import org.tigris.gef.presentation.Fig;
 64  
 import org.tigris.gef.presentation.FigLine;
 65  
 import org.tigris.gef.presentation.FigRect;
 66  
 import org.tigris.gef.presentation.FigText;
 67  
 import org.tigris.gef.presentation.Handle;
 68  
 
 69  
 /**
 70  
  * Class to display graphics for a UML ConcurrentRegion in a diagram.
 71  
  *
 72  
  * @author pepargouml@yahoo.es *
 73  
  */
 74  
 public class FigConcurrentRegion extends FigState
 75  
         implements
 76  
         MouseListener,
 77  
         MouseMotionListener {
 78  
 
 79  
     /**
 80  
      * The horizontal margin between the region and its composite parent state.
 81  
      */
 82  
     public static final int INSET_HORZ = 3;
 83  
     /**
 84  
      * The vertical margin between the region and its composite parent state.
 85  
      */
 86  
     public static final int INSET_VERT = 5;
 87  
 
 88  
     private FigRect cover;
 89  
     /**
 90  
      * The divider line is the horizontal dashed line
 91  
      * shown at the top side for
 92  
      * every region except the first one.
 93  
      */
 94  
     private FigLine dividerline;
 95  0
     private static Handle curHandle = new Handle(-1);
 96  
 
 97  
     private void initialize() {
 98  0
         cover =
 99  
             new FigRect(getInitialX(),
 100  
                 getInitialY(),
 101  
                 getInitialWidth(), getInitialHeight(),
 102  
                 INVISIBLE_LINE_COLOR, FILL_COLOR);
 103  0
         dividerline = new FigLine(getInitialX(),
 104  
                 getInitialY(),
 105  
                 getInitialWidth(),
 106  
                 getInitialY(),
 107  
                 getInitialColor());
 108  0
         dividerline.setDashed(true);
 109  0
         getBigPort().setLineWidth(0);
 110  0
         cover.setLineWidth(0);
 111  
 
 112  
         // add Figs to the FigNode in back-to-front order
 113  0
         addFig(getBigPort());
 114  0
         addFig(cover);
 115  0
         addFig(getNameFig());
 116  0
         addFig(dividerline);
 117  0
         addFig(getInternal());
 118  
 
 119  0
         setShadowSize(0);
 120  0
     }
 121  
 
 122  
     /**
 123  
      * Construct a new concurrent region fig.
 124  
      * 
 125  
      * @param node owning UML element
 126  
      * @param bounds position and size
 127  
      * @param settings render settings
 128  
      */
 129  
     public FigConcurrentRegion(Object node, Rectangle bounds, DiagramSettings
 130  
             settings) {
 131  0
         super(node, bounds, settings);
 132  0
         initialize();
 133  0
         if (bounds != null) {
 134  
             /* We have to use the specific methods written for this Fig: 
 135  
              * This fixes issue 5070. */
 136  0
             setBounds(bounds.x - _x, bounds.y - _y, bounds.width, 
 137  
                     bounds.height - _h, true);
 138  
         }
 139  0
         updateNameText();
 140  0
     }
 141  
 
 142  
     /**
 143  
      * The moment we add this fig to a layer, 
 144  
      * especially during load,
 145  
      * it needs to be made aware that it 
 146  
      * is enclosed by a FigCompositeState.
 147  
      * This fixes issue 3736.
 148  
      * 
 149  
      * @param lay the layer
 150  
      * @see org.argouml.uml.diagram.ui.FigNodeModelElement#setLayer(org.tigris.gef.base.Layer)
 151  
      */
 152  
     @Override
 153  
     public void setLayer(Layer lay) {
 154  0
         super.setLayer(lay);
 155  0
         for (Fig f : lay.getContents()) {
 156  0
             if (f instanceof FigCompositeState) {
 157  0
                 if (f.getOwner() 
 158  
                         == Model.getFacade().getContainer(getOwner())) {
 159  0
                     setEnclosingFig(f);
 160  0
                     break; // there can only be one
 161  
                 }
 162  
             }
 163  
         }
 164  0
     }
 165  
     
 166  
     /*
 167  
      * @see java.lang.Object#clone()
 168  
      */
 169  
     @Override
 170  
     public Object clone() {
 171  0
         FigConcurrentRegion figClone = (FigConcurrentRegion) super.clone();
 172  0
         Iterator it = figClone.getFigs().iterator();
 173  0
         figClone.setBigPort((FigRect) it.next());
 174  0
         figClone.cover = (FigRect) it.next();
 175  0
         figClone.setNameFig((FigText) it.next());
 176  0
         figClone.dividerline = (FigLine) it.next();
 177  0
         figClone.setInternal((FigText) it.next());
 178  0
         return figClone;
 179  
     }
 180  
 
 181  
     /*
 182  
      * @see org.tigris.gef.ui.PopupGenerator#getPopUpActions(java.awt.event.MouseEvent)
 183  
      */
 184  
     @Override
 185  
     public Vector getPopUpActions(MouseEvent me) {
 186  0
         Vector popUpActions = super.getPopUpActions(me);
 187  0
         popUpActions.remove(
 188  
                 ProjectActions.getInstance().getRemoveFromDiagramAction());
 189  0
         popUpActions.add(new JSeparator());
 190  
         // TODO: There's a cyclic dependency between FigConcurrentRegion and
 191  
         // the actions ActionAddConcurrentRegion
 192  0
         popUpActions.addElement(
 193  
                 new ActionAddConcurrentRegion());
 194  0
         return popUpActions;
 195  
     }
 196  
 
 197  
 
 198  
     /*
 199  
      * @see org.tigris.gef.presentation.Fig#getMinimumSize()
 200  
      */
 201  
     @Override
 202  
     public Dimension getMinimumSize() {
 203  0
         Dimension nameDim = getNameFig().getMinimumSize();
 204  0
         Dimension internalDim = getInternal().getMinimumSize();
 205  0
         int h = nameDim.height + 4 + internalDim.height;
 206  0
         int w = nameDim.width + 2 * MARGIN;
 207  0
         return new Dimension(w, h);
 208  
     }
 209  
 
 210  
     /*
 211  
      * @see org.tigris.gef.presentation.Fig#getUseTrapRect()
 212  
      */
 213  
     @Override
 214  
     public boolean getUseTrapRect() {
 215  0
         return true;
 216  
     }
 217  
 
 218  
     /**
 219  
      * Override setBounds to keep shapes looking right. <p>
 220  
      *
 221  
      * When resized by this way, it only changes the height and the
 222  
      * adjacent region's height.
 223  
      *
 224  
      * {@inheritDoc}
 225  
      */
 226  
     @Override
 227  
     protected void setStandardBounds(int x, int y, int w, int h) {
 228  0
         if (getNameFig() == null) {
 229  0
             return;
 230  
         }
 231  0
         Rectangle oldBounds = getBounds();
 232  0
         Dimension nameDim = getNameFig().getMinimumSize();
 233  0
         int adjacentindex = -1;
 234  0
         List regionsList = null;
 235  0
         int index = 0;
 236  0
         if (getEnclosingFig() != null) {
 237  0
             x = oldBounds.x;
 238  0
             w = oldBounds.width;
 239  0
             FigCompositeState f = ((FigCompositeState) getEnclosingFig());
 240  0
             regionsList = f.getEnclosedFigs();
 241  0
             index = regionsList.indexOf(this);
 242  
 
 243  
             /* if curHandle.index is 0 or 2,
 244  
              * the adjacent region is the previous region
 245  
              * but if it is 5 or 7, the adjacent region is the next region.
 246  
              * curHandle.index show which corner of the bound we are dragging.
 247  
              */
 248  0
             if (((curHandle.index == 0) || (curHandle.index == 2))
 249  
                     && index > 0) {
 250  0
                 adjacentindex = index - 1;
 251  
             }
 252  0
             if (((curHandle.index == 5) || (curHandle.index == 7))
 253  
                     && (index < (regionsList.size() - 1))) {
 254  0
                 adjacentindex = index + 1;
 255  
             }
 256  0
             if (h <= getMinimumSize().height) {
 257  0
                 if (h <= oldBounds.height) {
 258  0
                     h = oldBounds.height;
 259  0
                     y = oldBounds.y;
 260  
                 }
 261  
             }
 262  
 
 263  
             /* We aren't able to resize neither the top bound
 264  
              * from the first region nor
 265  
              * the bottom bound from the last region.
 266  
              */
 267  
 
 268  0
             if (adjacentindex == -1) {
 269  0
                 x = oldBounds.x;
 270  0
                 y = oldBounds.y;
 271  0
                 h = oldBounds.height;
 272  
 
 273  
                 /*The group must be resized if a text field exceed the bounds*/
 274  0
                 if (w > f.getBounds().width) {
 275  0
                     Rectangle fR = f.getBounds();
 276  0
                     f.setBounds(fR.x, fR.y, w + 6, fR.height);
 277  0
                 }
 278  
             } else {
 279  0
                 int hIncrement = oldBounds.height - h;
 280  0
                 FigConcurrentRegion adjacentFig =
 281  
                     ((FigConcurrentRegion)
 282  
                         regionsList.get(adjacentindex));
 283  0
                 if ((adjacentFig.getBounds().height + hIncrement)
 284  
                         <= adjacentFig.getMinimumSize().height) {
 285  0
                     y = oldBounds.y;
 286  0
                     h = oldBounds.height;
 287  
                 } else {
 288  0
                     if ((curHandle.index == 0) || (curHandle.index == 2)) {
 289  0
                         ((FigConcurrentRegion) regionsList.
 290  
                             get(adjacentindex)).setBounds(0, hIncrement);
 291  
                     }
 292  0
                     if ((curHandle.index == 5) || (curHandle.index == 7)) {
 293  0
                         ((FigConcurrentRegion) regionsList.
 294  
                             get(adjacentindex)).setBounds(-hIncrement,
 295  
                                     hIncrement);
 296  
                     }
 297  
                 }
 298  
             }
 299  
         }
 300  
 
 301  0
         dividerline.setShape(x, y, x + w, y);
 302  0
         getNameFig().setBounds(x + MARGIN,
 303  
                 y + SPACE_TOP,
 304  
                 w - 2 * MARGIN,
 305  
                 nameDim.height);
 306  0
         getInternal().setBounds(
 307  
                 x + MARGIN,
 308  
                 y + nameDim.height + SPACE_TOP + SPACE_MIDDLE,
 309  
                 w - 2 * MARGIN,
 310  
                 h - nameDim.height - SPACE_TOP - SPACE_MIDDLE - SPACE_BOTTOM);
 311  0
         getBigPort().setBounds(x, y, w, h);
 312  0
         cover.setBounds(x, y, w, h);
 313  
 
 314  0
         calcBounds(); //_x = x; _y = y; _w = w; _h = h;
 315  0
         updateEdges();
 316  0
         firePropChange("bounds", oldBounds, getBounds());
 317  0
     }
 318  
 
 319  
     /**
 320  
      * To resize with X and Y increments, absolute width and keeping the height.
 321  
      * @param xInc the x increment
 322  
      * @param yInc the y increment
 323  
      * @param w the width
 324  
      * @param concurrency is concurrent?
 325  
      */
 326  
     public void setBounds(int xInc, int yInc, int w, boolean concurrency) {
 327  0
         if (getNameFig() == null) {
 328  0
             return;
 329  
         }
 330  0
         Rectangle oldBounds = getBounds();
 331  0
         Dimension nameDim = getNameFig().getMinimumSize();
 332  0
         int x = oldBounds.x + xInc;
 333  0
         int y = oldBounds.y + yInc;
 334  0
         int h = oldBounds.height;
 335  
 
 336  0
         dividerline.setShape(x, y, x + w , y);
 337  0
         getNameFig().setBounds(x + 2, y + 2, w - 4, nameDim.height);
 338  0
         getInternal().setBounds(x + 2, y + nameDim.height + 4,
 339  
                 w - 4, h - nameDim.height - 8);
 340  0
         getBigPort().setBounds(x, y, w, h);
 341  0
         cover.setBounds(x, y, w, h);
 342  
 
 343  0
         calcBounds(); //_x = x; _y = y; _w = w; _h = h;
 344  0
         updateEdges();
 345  0
         firePropChange("bounds", oldBounds, getBounds());
 346  0
     }
 347  
 
 348  
     /**
 349  
      * To resize with X, Y and height increments and absolute width.
 350  
      * The boolean parameter is added in order to override the method.
 351  
      *
 352  
      * @param xInc the x increment
 353  
      * @param yInc the y increment
 354  
      * @param w the width
 355  
      * @param concurrency is concurrent?
 356  
      * @param hInc the height increment
 357  
      */
 358  
     public void setBounds(int xInc, int yInc, int w, int hInc,
 359  
             boolean concurrency) {
 360  0
         if (getNameFig() == null) {
 361  0
             return;
 362  
         }
 363  0
         Rectangle oldBounds = getBounds();
 364  0
         Dimension nameDim = getNameFig().getMinimumSize();
 365  0
         int x = oldBounds.x + xInc;
 366  0
         int y = oldBounds.y + yInc;
 367  0
         int h = oldBounds.height + hInc;
 368  
 
 369  0
         dividerline.setShape(x, y,
 370  
                 x + w , y);
 371  0
         getNameFig().setBounds(x + 2, y + 2, w - 4, nameDim.height);
 372  0
         getInternal().setBounds(x + 2, y + nameDim.height + 4,
 373  
                 w - 4, h - nameDim.height - 8);
 374  0
         getBigPort().setBounds(x, y, w, h);
 375  0
         cover.setBounds(x, y, w, h);
 376  
 
 377  0
         calcBounds(); //_x = x; _y = y; _w = w; _h = h;
 378  0
         updateEdges();
 379  0
         firePropChange("bounds", oldBounds, getBounds());
 380  0
     }
 381  
 
 382  
     /**
 383  
      * To resize with Y increments, height increment and
 384  
      * keeping the X and width.
 385  
      *
 386  
      * @param yInc the y increment
 387  
      * @param hInc the height increment
 388  
      */
 389  
     public void setBounds(int yInc, int hInc) {
 390  0
         if (getNameFig() == null) {
 391  0
             return;
 392  
         }
 393  0
         Rectangle oldBounds = getBounds();
 394  0
         Dimension nameDim = getNameFig().getMinimumSize();
 395  0
         int x = oldBounds.x;
 396  0
         int y = oldBounds.y + yInc;
 397  0
         int w = oldBounds.width;
 398  0
         int h = oldBounds.height + hInc;
 399  
 
 400  0
         dividerline.setShape(x, y, x + w , y);
 401  0
         getNameFig().setBounds(x + 2, y + 2, w - 4, nameDim.height);
 402  0
         getInternal().setBounds(x + 2, y + nameDim.height + 4,
 403  
                 w - 4, h - nameDim.height - 8);
 404  0
         getBigPort().setBounds(x, y, w, h);
 405  0
         cover.setBounds(x, y, w, h);
 406  
 
 407  0
         calcBounds(); //_x = x; _y = y; _w = w; _h = h;
 408  0
         updateEdges();
 409  0
         firePropChange("bounds", oldBounds, getBounds());
 410  0
     }
 411  
 
 412  
     ////////////////////////////////////////////////////////////////
 413  
     // fig accessors
 414  
 
 415  
     /*
 416  
      * This function only sets the color of the divider line 
 417  
      * (since that is the only visible part), and can be used to make 
 418  
      * the divider line invisible for the top region in a composite state.
 419  
      * 
 420  
      * @see org.tigris.gef.presentation.Fig#setLineColor(java.awt.Color)
 421  
      */
 422  
     @Override
 423  
     public void setLineColor(Color col) {
 424  0
         cover.setLineColor(INVISIBLE_LINE_COLOR);
 425  0
         dividerline.setLineColor(col);
 426  0
     }
 427  
 
 428  
     /*
 429  
      * @see org.tigris.gef.presentation.Fig#getLineColor()
 430  
      */
 431  
     @Override
 432  
     public Color getLineColor() {
 433  0
         return dividerline.getLineColor();
 434  
     }
 435  
 
 436  
     /*
 437  
      * @see org.tigris.gef.presentation.Fig#setFillColor(java.awt.Color)
 438  
      */
 439  
     @Override
 440  
     public void setFillColor(Color col) {
 441  0
         cover.setFillColor(col);
 442  0
     }
 443  
 
 444  
     /*
 445  
      * @see org.tigris.gef.presentation.Fig#getFillColor()
 446  
      */
 447  
     @Override
 448  
     public Color getFillColor() {
 449  0
         return cover.getFillColor();
 450  
     }
 451  
 
 452  
     /*
 453  
      * @see org.tigris.gef.presentation.Fig#setFilled(boolean)
 454  
      */
 455  
     @Override
 456  
     public void setFilled(boolean f) {
 457  0
         cover.setFilled(f);
 458  0
         getBigPort().setFilled(f);
 459  0
     }
 460  
 
 461  
 
 462  
     @Override
 463  
     public boolean isFilled() {
 464  0
         return cover.isFilled();
 465  
     }
 466  
 
 467  
     /*
 468  
      * @see org.tigris.gef.presentation.Fig#setLineWidth(int)
 469  
      */
 470  
     @Override
 471  
     public void setLineWidth(int w) {
 472  0
         dividerline.setLineWidth(w);
 473  0
     }
 474  
 
 475  
     /*
 476  
      * @see org.tigris.gef.presentation.Fig#getLineWidth()
 477  
      */
 478  
     @Override
 479  
     public int getLineWidth() {
 480  0
         return dividerline.getLineWidth();
 481  
     }
 482  
 
 483  
     ////////////////////////////////////////////////////////////////
 484  
     // event processing
 485  
 
 486  
     protected void modelChanged(PropertyChangeEvent mee) {
 487  
         // TODO: Rather than specifically ignore some item maybe it would be better
 488  
         // to specifically state what items are of interest. Otherwise we may still
 489  
         // be acting on other events we don't need
 490  0
         if (!Model.getFacade().isATransition(mee.getNewValue())
 491  
                 && !("container".equals(mee.getPropertyName()))
 492  
                 && !("isConcurrent".equals(mee.getPropertyName()))
 493  
                 && !("subvertex".equals(mee.getPropertyName()))) {
 494  0
             super.modelChanged(mee);
 495  
         }
 496  0
     }
 497  
     
 498  
     /*
 499  
      * @see org.tigris.gef.presentation.Fig#makeSelection()
 500  
      */
 501  
     @Override
 502  
     public Selection makeSelection() {
 503  0
         Selection sel = new SelectionState(this);
 504  0
         ((SelectionState) sel).setIncomingButtonEnabled(false);
 505  0
         ((SelectionState) sel).setOutgoingButtonEnabled(false);
 506  0
         return sel;
 507  
     }
 508  
 
 509  
     /*
 510  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialHeight()
 511  
      */
 512  
     public int getInitialHeight() {
 513  0
         return 130;
 514  
     }
 515  
 
 516  
     /*
 517  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialWidth()
 518  
      */
 519  
     protected int getInitialWidth() {
 520  0
         return 30;
 521  
     }
 522  
 
 523  
     /*
 524  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialX()
 525  
      */
 526  
     protected int getInitialX() {
 527  0
         return 0;
 528  
     }
 529  
 
 530  
     /*
 531  
      * @see org.argouml.uml.diagram.state.ui.FigState#getInitialY()
 532  
      */
 533  
     protected int getInitialY() {
 534  0
         return 0;
 535  
     }
 536  
 
 537  
     /**
 538  
      * @return the initial color
 539  
      */
 540  
     protected Color getInitialColor() {
 541  0
         return LINE_COLOR;
 542  
     }
 543  
 
 544  
     /////////////////////////////////////////////////////////////////////////
 545  
     // event handlers - MouseListener and MouseMotionListener implementation
 546  
 
 547  
     @Override
 548  
     protected void updateLayout(UmlChangeEvent event) {
 549  0
         if (!"container".equals(event.getPropertyName()) &&
 550  
                 !"isConcurrent".equals(event.getPropertyName())) {
 551  0
             super.updateLayout(event);
 552  
         }
 553  0
         final String eName = event.getPropertyName();
 554  
         /*
 555  
          * A Concurrent region cannot have incoming or outgoing transitions so
 556  
          * incoming or outgoing transitions are redirected to its concurrent
 557  
          * composite state container.
 558  
          */
 559  
         // TODO: This comparison is very suspect, it should use equals
 560  
         // method. The code within the block is in fact never executed.
 561  
         // I hesitate to change this now as it will trigger code has never been
 562  
         // used before and am not aware of any problems that it usage may
 563  
         // introduce.
 564  
         // I do think that we need to be able to find a different way to
 565  
         // implement the intent here which seems to be to correct edge drawings
 566  
         // that should actually not be allowed - Bob
 567  0
         if (eName == "incoming" || eName == "outgoing") {
 568  0
             final Object owner = getOwner();
 569  0
             final Collection transactions = (Collection) event.getNewValue();
 570  0
             if (!transactions.isEmpty()) {
 571  0
                 final Object transition = transactions.iterator().next();
 572  0
                 if (eName == "incoming") {
 573  0
                     if (Model.getFacade().isATransition(transition)) {
 574  0
                         Model.getCommonBehaviorHelper().setTarget(transition,
 575  
                                 Model.getFacade().getContainer(owner));
 576  
                     }
 577  
                 } else {
 578  0
                     if (Model.getFacade().isATransition(transition)) {
 579  0
                         Model.getStateMachinesHelper().setSource(transition,
 580  
                                 Model.getFacade().getContainer(owner));
 581  
                     }
 582  
                 }
 583  
             }
 584  
         }
 585  0
     }
 586  
 
 587  
     /*
 588  
      * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
 589  
      */
 590  
     @Override
 591  
     public void mousePressed(MouseEvent e) {
 592  0
         int x = e.getX();
 593  0
         int y = e.getY();
 594  0
         Globals.curEditor().getSelectionManager().hitHandle(
 595  
                 new Rectangle(x - 4, y - 4, 8, 8), curHandle);
 596  0
     }
 597  
 
 598  
     /*
 599  
      * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
 600  
      */
 601  
     @Override
 602  
     public void mouseReleased(MouseEvent e) {
 603  0
         curHandle.index = -1;
 604  0
     }
 605  
 
 606  
     /*
 607  
      * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
 608  
      */
 609  
     public void mouseDragged(MouseEvent e) {
 610  0
         if (curHandle.index == -1) {
 611  0
             Globals.curEditor().getSelectionManager().select(getEnclosingFig());
 612  
         }
 613  0
     }
 614  
 
 615  
     /*
 616  
      * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
 617  
      */
 618  
     public void mouseMoved(MouseEvent e) {
 619  
         // ignored
 620  0
     }
 621  
 
 622  
     /**
 623  
      * The UID.
 624  
      */
 625  
     private static final long serialVersionUID = -7228935179004210975L;
 626  
 }