svn commit: r17365 - trunk/src/argouml-app/src/org/argouml: persistence uml/diagram uml/diagram/static_structure/ui uml/diagram/ui uml/diagram/use_case/ui

Michiel van der Wulp <[email protected]>
Newsgroups gmane.comp.lang.uml.argouml.cvs
Message-ID <[email protected]>
Author: mvw
Date: 2009-09-30 23:13:34-0700
New Revision: 17365

Added:
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionPointsCompartmentContainer.java
      - copied, changed from r17336, /trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionsCompartmentContainer.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigExtensionPointsCompartment.java
Removed:
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionsCompartmentContainer.java
Modified:
   trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigEnumeration.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigSignal.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigStereotypeDeclaration.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/ActionCompartmentDisplay.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigCompartmentBox.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEditableCompartment.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtensionPoint.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigUseCase.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/StylePanelFigUseCase.java

Log:
Complete overhaul of the FigUseCase: it is now less than half the lines of code.
This fixes issues 3964, 3965, 3966, 4595, 5187.
TODO: The extension points compartment separator line is not drawn from ellipse edge to edge, but only as wide as the widest text in the oval.

Modified: trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/persistence/PGMLStackParser.java	2009-09-30 23:13:34-0700
@@ -40,7 +40,7 @@
 import org.argouml.uml.diagram.AttributesCompartmentContainer;
 import org.argouml.uml.diagram.DiagramEdgeSettings;
 import org.argouml.uml.diagram.DiagramSettings;
-import org.argouml.uml.diagram.ExtensionsCompartmentContainer;
+import org.argouml.uml.diagram.ExtensionPointsCompartmentContainer;
 import org.argouml.uml.diagram.OperationsCompartmentContainer;
 import org.argouml.uml.diagram.PathContainer;
 import org.argouml.uml.diagram.StereotypeContainer;
@@ -324,8 +324,8 @@
                 ((PathContainer) fig)
                     .setPathVisible(value.equalsIgnoreCase("true"));
             } else if ("extensionPointVisible".equals(name)) {
-                ((ExtensionsCompartmentContainer) fig)
-                    .setExtensionPointVisible(value.equalsIgnoreCase("true"));
+                ((ExtensionPointsCompartmentContainer) fig)
+                    .setExtensionPointsVisible(value.equalsIgnoreCase("true"));
             }
         }
     }

Copied: trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionPointsCompartmentContainer.java (from r17336, /trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionsCompartmentContainer.java)
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionPointsCompartmentContainer.java?view=diff&pathrev=17365&r1=17336&r2=17365
==============================================================================
--- /trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionsCompartmentContainer.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionPointsCompartmentContainer.java	2009-09-30 23:13:34-0700
@@ -1,5 +1,5 @@
 // $Id$
-// Copyright (c) 2005-2006 The Regents of the University of California. All
+// Copyright (c) 2005-2009 The Regents of the University of California. All
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 // software and its documentation without fee, and without a written
 // agreement is hereby granted, provided that the above copyright notice
@@ -30,18 +30,18 @@
  *
  * @author [email protected]
  */
-public interface ExtensionsCompartmentContainer {
+public interface ExtensionPointsCompartmentContainer {
 
     /**
      * Determine if the operations compartment is visible.
      * @return true if the operations compartment is visible.
      */
-    boolean isExtensionPointVisible();
+    boolean isExtensionPointsVisible();
 
     /**
      * Set the visibility of the operations compartment.
      * @param visible the new visibility status.
      */
-    void setExtensionPointVisible(boolean visible);
+    void setExtensionPointsVisible(boolean visible);
 
 }

Removed: trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionsCompartmentContainer.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ExtensionsCompartmentContainer.java?view=markup&pathrev=17364

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigEnumeration.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigEnumeration.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigEnumeration.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigEnumeration.java	2009-09-30 23:13:34-0700
@@ -25,14 +25,11 @@
 package org.argouml.uml.diagram.static_structure.ui;
 
 import java.awt.Rectangle;
-import java.beans.PropertyChangeEvent;
 import java.util.HashSet;
 import java.util.Set;
 
 import javax.swing.Action;
 
-import org.argouml.model.AssociationChangeEvent;
-import org.argouml.model.AttributeChangeEvent;
 import org.argouml.model.Model;
 import org.argouml.ui.ArgoJMenu;
 import org.argouml.uml.diagram.DiagramSettings;
@@ -106,16 +103,6 @@
     }
 
     @Override
-    protected void modelChanged(PropertyChangeEvent mee) {
-        super.modelChanged(mee);
-        if (mee instanceof AssociationChangeEvent 
-                || mee instanceof AttributeChangeEvent) {
-            renderingChanged();
-            updateListeners(getOwner(), getOwner());
-        }
-    }
-
-    @Override
     public void renderingChanged() {
         super.renderingChanged();
         if (getOwner() != null) {

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigSignal.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigSignal.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigSignal.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigSignal.java	2009-09-30 23:13:34-0700
@@ -26,11 +26,8 @@
 
 import java.awt.Rectangle;
 import java.awt.event.MouseEvent;
-import java.beans.PropertyChangeEvent;
 import java.util.Vector;
 
-import org.argouml.model.AssociationChangeEvent;
-import org.argouml.model.AttributeChangeEvent;
 import org.argouml.uml.diagram.DiagramSettings;
 import org.tigris.gef.base.Selection;
 
@@ -113,14 +110,4 @@
         return popUpActions;
     }
 
-    @Override
-    protected void modelChanged(PropertyChangeEvent mee) {
-        super.modelChanged(mee);
-        if (mee instanceof AssociationChangeEvent 
-                || mee instanceof AttributeChangeEvent) {
-            renderingChanged();
-            updateListeners(getOwner(), getOwner());
-        }
-    }
-
 } 

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigStereotypeDeclaration.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigStereotypeDeclaration.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigStereotypeDeclaration.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigStereotypeDeclaration.java	2009-09-30 23:13:34-0700
@@ -26,15 +26,12 @@
 
 import java.awt.Rectangle;
 import java.awt.event.MouseEvent;
-import java.beans.PropertyChangeEvent;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.Vector;
 
 import javax.swing.Action;
 
-import org.argouml.model.AssociationChangeEvent;
-import org.argouml.model.AttributeChangeEvent;
 import org.argouml.model.Model;
 import org.argouml.ui.ArgoJMenu;
 import org.argouml.uml.diagram.DiagramSettings;
@@ -165,24 +162,6 @@
         return fc;
     }
 
-    /**
-     * Handles changes to the model. Takes into account the event that
-     * occurred. If you need to update the whole fig, consider using
-     * renderingChanged.
-     * {@inheritDoc}
-     * @see org.argouml.uml.diagram.ui.FigNodeModelElement#modelChanged(java.beans.PropertyChangeEvent)
-     */
-    @Override
-    protected void modelChanged(PropertyChangeEvent mee) {
-        super.modelChanged(mee);
-        if (mee instanceof AssociationChangeEvent 
-                || mee instanceof AttributeChangeEvent) {
-            renderingChanged();
-            updateListeners(getOwner(), getOwner());
-            damage();
-        }
-    }
-
     @Override
     protected void updateListeners(Object oldOwner, Object newOwner) {
         

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/ActionCompartmentDisplay.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/ActionCompartmentDisplay.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/ActionCompartmentDisplay.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/ActionCompartmentDisplay.java	2009-09-30 23:13:34-0700
@@ -1,5 +1,5 @@
 // $Id$
-// Copyright (c) 1996-2006 The Regents of the University of California. All
+// Copyright (c) 1996-2009 The Regents of the University of California. All
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 // software and its documentation without fee, and without a written
 // agreement is hereby granted, provided that the above copyright notice
@@ -34,7 +34,7 @@
 
 import org.argouml.i18n.Translator;
 import org.argouml.uml.diagram.AttributesCompartmentContainer;
-import org.argouml.uml.diagram.ExtensionsCompartmentContainer;
+import org.argouml.uml.diagram.ExtensionPointsCompartmentContainer;
 import org.argouml.uml.diagram.OperationsCompartmentContainer;
 import org.tigris.gef.base.Editor;
 import org.tigris.gef.base.Globals;
@@ -221,12 +221,12 @@
                     visible++;
                 }
             }
-            if (f instanceof ExtensionsCompartmentContainer) {
+            if (f instanceof ExtensionPointsCompartmentContainer) {
                 present++;
                 epPresent = true;
                 epVisible =
-                        ((ExtensionsCompartmentContainer) f)
-                                .isExtensionPointVisible();
+                        ((ExtensionPointsCompartmentContainer) f)
+                                .isExtensionPointsVisible();
                 if (epVisible) {
                     visible++;
                 }
@@ -322,8 +322,8 @@
             }
 
             if ((cType & COMPARTMENT_EXTENSIONPOINT) != 0) {
-                if (f instanceof ExtensionsCompartmentContainer) {
-                    ((ExtensionsCompartmentContainer) f).setExtensionPointVisible(display);
+                if (f instanceof ExtensionPointsCompartmentContainer) {
+                    ((ExtensionPointsCompartmentContainer) f).setExtensionPointsVisible(display);
                 }
             }
             if ((cType & COMPARTMENT_ENUMLITERAL) != 0) {

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigCompartmentBox.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigCompartmentBox.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigCompartmentBox.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigCompartmentBox.java	2009-09-30 23:13:34-0700
@@ -29,10 +29,13 @@
 import java.awt.Rectangle;
 import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.log4j.Logger;
+import org.argouml.model.AssociationChangeEvent;
+import org.argouml.model.AttributeChangeEvent;
 import org.argouml.ui.targetmanager.TargetManager;
 import org.argouml.uml.diagram.DiagramSettings;
 import org.argouml.uml.diagram.static_structure.ui.SelectionClass;
@@ -100,6 +103,11 @@
         new ArrayList<FigCompartment>();
 
     /**
+     * Buffer the calculated dimensions of the compartments for later use.
+     */
+    protected Dimension containerBox;
+
+    /**
      * Initialization shared by all constructors.
      */
     private void initialize() {
@@ -119,22 +127,18 @@
          * compartments. Its size always equals the bigPort. Its body is
          * transparent.
          */
-        borderFig = new FigEmptyRect(X0, Y0, 0, 0);
-        borderFig.setLineColor(LINE_COLOR);
-        borderFig.setLineWidth(LINE_WIDTH);
+        borderFig = createBorderFig();
 
         getBigPort().setLineWidth(0);
         /* The bigPort draws the background color: */
         getBigPort().setFillColor(FILL_COLOR);
+    }
 
-        /*
-         * TODO: The above means that the border is drawn OVER 
-         * the background fill (which won't work if colors have 
-         * alpha channels). But the fill should only be drawn WITHIN 
-         * the border. MVW: I propose to have the borderFig show 
-         * the fill color and have the bigPort be transparent and
-         * without border.
-         */
+    protected Fig createBorderFig() {
+        Fig b = new FigEmptyRect(X0, Y0, 0, 0);
+        b.setLineColor(LINE_COLOR);
+        b.setLineWidth(LINE_WIDTH);
+        return b;
     }
 
     /**
@@ -193,11 +197,49 @@
          * dimensions to the minimum space required for its contents:
          */
         aSize.width = Math.max(WIDTH, aSize.width);
-        aSize.width += 2 * getLineWidth();
-        aSize.height += 2 * getLineWidth();
+        
+        aSize = addCompartmentBoxSurroundings(aSize);
 
         return aSize;
     }
+    
+    /**
+     * Increase the size of the given box with the area around the 
+     * compartments.
+     * 
+     * @param box the minimum box size needed for the compartments
+     * @return the dimensions of the complete fig
+     */
+    protected Dimension addCompartmentBoxSurroundings(Dimension box) {
+        containerBox = new Dimension(box);
+        box.width += 2 * getLineWidth();
+        box.height += 2 * getLineWidth();
+        return box;
+    }
+    
+    /**
+     * Given the outside dimensions and location of the Fig, calculate 
+     * the position and size of the box for the compartments.
+     * The compartments are located inside the complete fig. For a
+     * rectangle (i.e. the default implementation), only the line-width 
+     * of the outside box needs to be added.
+     * Other Figs may have other shapes, e.g. a Use Case has the 
+     * box located inside an ellipse. So, they need to overrule this method.
+     * 
+     * @param x outside top left
+     * @param y outside top left
+     * @param w outside dimension, including line-width
+     * @param h outside dimension, including line-width
+     * @return the location and area to be used by the compartments
+     */
+    protected Rectangle calculateCompartmentBoxDimensions(
+            final int x, final int y, final int w, final int h) {
+        return new Rectangle(
+                x + getLineWidth(), 
+                y + getLineWidth(), 
+                w - 2 * getLineWidth(),
+                h - 2 * getLineWidth());
+    }
 
     /**
      * Sets the bounds, but the size will be at least the one returned by
@@ -229,14 +271,21 @@
         Dimension minimumSize = getMinimumSize();
         int newW = Math.max(w, minimumSize.width);
         int newH = Math.max(h, minimumSize.height);
+        
+        /* The box for the compartments is somewhere 
+         * inside the outside bounds: */
+        Rectangle box = calculateCompartmentBoxDimensions(
+                x, y, newW, newH);
 
         int currentHeight = 0;
 
         if (getStereotypeFig().isVisible()) {
             int stereotypeHeight = getStereotypeFig().getMinimumSize().height;
             getNameFig().setTopMargin(stereotypeHeight);
-            getStereotypeFig().setBounds(x + getLineWidth(),
-                    y + getLineWidth(), newW - 2 * getLineWidth(),
+            getStereotypeFig().setBounds(
+                    box.x,
+                    box.y, 
+                    box.width,
                     stereotypeHeight);
         } else {
             getNameFig().setTopMargin(0);
@@ -246,8 +295,8 @@
         Dimension nameMin = getNameFig().getMinimumSize();
         int minNameHeight = Math.max(nameMin.height, NAME_FIG_HEIGHT);
 
-        getNameFig().setBounds(x + getLineWidth(), y + getLineWidth(),
-                newW - 2 * getLineWidth(), minNameHeight);
+        getNameFig().setBounds(box.x, box.y,
+                box.width, minNameHeight);
 
         /* The new height can not be less than the name height: */
         /*
@@ -258,7 +307,7 @@
 
         currentHeight += minNameHeight;
 
-        int requestedHeight = newH - currentHeight - 2 * getLineWidth();
+        int requestedHeight = box.height - currentHeight;
         int neededHeight = 0;
         /* Calculate the minimum needed height for all the compartments:*/
         for (FigCompartment c : compartments) {
@@ -278,9 +327,10 @@
                     compartmentHeight += (requestedHeight - neededHeight)
                             / getVisibleCompartmentCount();
                 }
-                c.setBounds(x + getLineWidth(), 
-                        y + currentHeight + getLineWidth(), 
-                        newW - 2 * getLineWidth(),
+                c.setBounds( 
+                        box.x, 
+                        box.y + currentHeight, 
+                        box.width,
                         compartmentHeight);
                 currentHeight += compartmentHeight;
             }
@@ -324,6 +374,17 @@
         }
     }
 
+    @Override
+    protected void modelChanged(PropertyChangeEvent mee) {
+        // Let our superclass sort itself out first
+        super.modelChanged(mee);
+        if (mee instanceof AssociationChangeEvent 
+                || mee instanceof AttributeChangeEvent) {
+            renderingChanged();
+            updateListeners(getOwner(), getOwner());
+        }
+    }
+    
     /*
      * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
      */

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEditableCompartment.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEditableCompartment.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEditableCompartment.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEditableCompartment.java	2009-09-30 23:13:34-0700
@@ -61,7 +61,7 @@
 
     private static final int MIN_HEIGHT = FigNodeModelElement.NAME_FIG_HEIGHT;
 
-    private FigSeparator compartmentSeperator;
+    private FigSeparator compartmentSeparator;
 
     /**
      * The constructor. <p>
@@ -85,9 +85,9 @@
     }
 
     private void constructFigs() {
-        compartmentSeperator = 
+        compartmentSeparator = 
             new FigSeparator(X0, Y0, 11, LINE_WIDTH);
-        addFig(compartmentSeperator); // number 2
+        addFig(compartmentSeparator); // number 2
     }
     
     /**
@@ -114,7 +114,7 @@
      * @return separator figure
      */
     protected FigSeparator getSeperatorFig() {
-        return compartmentSeperator;
+        return compartmentSeparator;
     }
 
     /**
@@ -346,6 +346,7 @@
      * @param h h
      * @return the new dimension
      */
+    @SuppressWarnings("unused")
     public Dimension updateFigGroupSize(
                        int x,
                        int y,
@@ -366,7 +367,7 @@
     public Dimension getMinimumSize() {
         Dimension d = super.getMinimumSize();
         d.height = Math.max(d.height, 
-                MIN_HEIGHT + compartmentSeperator.getHeight());
+                MIN_HEIGHT + compartmentSeparator.getHeight());
         return d;
     }
 
@@ -374,27 +375,28 @@
     public void setLineColor(Color col) {
         super.setLineColor(col);
         if (col != null) {
-            compartmentSeperator.setFillColor(col);
-            compartmentSeperator.setFilled(true);
+            compartmentSeparator.setFillColor(col);
+            compartmentSeparator.setFilled(true);
         }
     }
 
     @Override
     public void setLineWidth(int w) {
         super.setLineWidth(0);
+        compartmentSeparator.setHeight(w);
     }
 
     @Override
     public void setFillColor(Color col) {
         super.setFillColor(col);
-        compartmentSeperator.setFillColor(getLineColor());
-        compartmentSeperator.setFilled(true);
+        compartmentSeparator.setFillColor(getLineColor());
+        compartmentSeparator.setFilled(true);
     }
 
     @Override
     public void setFilled(boolean f) {
         super.setFilled(f);
-        compartmentSeperator.setFilled(true);
+        compartmentSeparator.setFilled(true);
     }
 
     /**
@@ -421,7 +423,7 @@
         @Override
         public Dimension getMinimumSize() {
             return new Dimension(MIN_SIZE, getHeight());
-        }        
-        
+        }
+
     }
 }

Added: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigExtensionPointsCompartment.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigExtensionPointsCompartment.java?view=markup&pathrev=17365
==============================================================================
--- (empty file)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigExtensionPointsCompartment.java	2009-09-30 23:13:34-0700
@@ -0,0 +1,85 @@
+// $Id: eclipse-argo-codetemplates.xml 11347 2006-10-26 22:37:44Z linus $
+// Copyright (c) 2009 The Regents of the University of California. All
+// Rights Reserved. Permission to use, copy, modify, and distribute this
+// software and its documentation without fee, and without a written
+// agreement is hereby granted, provided that the above copyright notice
+// and this paragraph appear in all copies. This software program and
+// documentation are copyrighted by The Regents of the University of
+// California. The software program and documentation are supplied "AS
+// IS", without any accompanying services from The Regents. The Regents
+// does not warrant that the operation of the program will be
+// uninterrupted or error-free. The end-user understands that the program
+// was developed for research purposes and is advised not to rely
+// exclusively on the program for any reason. IN NO EVENT SHALL THE
+// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
+// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+package org.argouml.uml.diagram.ui;
+
+import java.awt.Rectangle;
+import java.util.Collection;
+
+import org.argouml.model.Model;
+import org.argouml.notation.NotationProviderFactory2;
+import org.argouml.ui.targetmanager.TargetManager;
+import org.argouml.uml.diagram.DiagramSettings;
+import org.argouml.uml.diagram.use_case.ui.FigExtensionPoint;
+
+/**
+ * The compartment that contains extension points.
+ *
+ * @author michiel
+ */
+public class FigExtensionPointsCompartment extends FigEditableCompartment {
+
+    /**
+     * The constructor.
+     * 
+     * @param owner owning UML element
+     * @param bounds position and size
+     * @param settings render settings
+     */
+    public FigExtensionPointsCompartment(Object owner, Rectangle bounds,
+            DiagramSettings settings) {
+        super(owner, bounds, settings);
+        super.populate();
+    }
+
+    @Override
+    FigSingleLineTextWithNotation createFigText(Object owner, Rectangle bounds,
+            DiagramSettings settings) {
+        return new FigExtensionPoint(owner, bounds, settings);
+    }
+
+    @Override
+    protected int getNotationType() {
+        return NotationProviderFactory2.TYPE_EXTENSION_POINT;
+    }
+
+    @Override
+    protected Collection getUmlCollection() {
+        Object usecase = getOwner(); //TODO: check!
+        return Model.getFacade().getExtensionPoints(usecase);
+    }
+
+    @Override
+    protected void createModelElement() {
+        Object usecase = getGroup().getOwner(); //TODO: check!
+        Object ep = Model.getUseCasesFactory().buildExtensionPoint(usecase);
+        TargetManager.getInstance().setTarget(ep);
+    }
+
+    @Override
+    public String getName() {
+         return "extension points";
+    }
+
+}

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigNodeModelElement.java	2009-09-30 23:13:34-0700
@@ -376,7 +376,7 @@
 
         // this rectangle marks the whole modelelement figure; everything
         // is inside it:
-        bigPort = new FigRect(X0, Y0, 0, 0, DEBUG_COLOR, DEBUG_COLOR);
+        bigPort = createBigPortFig();
         nameFig = new FigNameWithAbstractAndBold(element, 
                 new Rectangle(X0, Y0, WIDTH, NAME_FIG_HEIGHT), getSettings(), true);
         stereotypeFig = createStereotypeFig();
@@ -426,6 +426,15 @@
         
         readyToEdit = true;
     }
+
+    /**
+     * Overrule this if a rectangle is not usable.
+     * 
+     * @return the Fig to be used as bigPort
+     */
+    protected Fig createBigPortFig() {
+        return new FigRect(X0, Y0, 0, 0, DEBUG_COLOR, DEBUG_COLOR);
+    }
     
     protected FigStereotypesGroup createStereotypeFig() {
         return new FigStereotypesGroup(getOwner(), 
@@ -1916,7 +1925,10 @@
 
 
     /**
-     * @param bp the bigPort, which is the port where edges connect to this node
+     * @param bp the bigPort, which is the port where edges 
+     *          connect to this node
+     * @deprecated by MVW since V0.28.1. Use makeBigPortFig instead, 
+     *          to guarantee correct initialization.
      */
     protected void setBigPort(Fig bp) {
         this.bigPort = bp;

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtensionPoint.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtensionPoint.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtensionPoint.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtensionPoint.java	2009-09-30 23:13:34-0700
@@ -26,9 +26,9 @@
 
 import java.awt.Rectangle;
 
+import org.argouml.notation.NotationProviderFactory2;
 import org.argouml.uml.diagram.DiagramSettings;
 import org.argouml.uml.diagram.ui.CompartmentFigText;
-import org.tigris.gef.presentation.FigText;
 
 /**
  * Fig to show one extension point in a compartment.
@@ -46,12 +46,11 @@
             DiagramSettings settings) {
         super(owner, bounds, settings);
 
-        setFilled(false);
-        setLineWidth(0);
-        setTextColor(getTextColor());
-        setJustification(FigText.JUSTIFY_LEFT);
-        setReturnAction(FigText.END_EDITING);
-
     }
-
+    
+    @Override
+    protected int getNotationProviderType() {
+        return NotationProviderFactory2.TYPE_EXTENSION_POINT;
+    }
+    
 }

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigUseCase.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigUseCase.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigUseCase.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigUseCase.java	2009-09-30 23:13:34-0700
@@ -24,44 +24,32 @@
 
 package org.argouml.uml.diagram.use_case.ui;
 
+
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Point;
 import java.awt.Rectangle;
-import java.awt.event.InputEvent;
 import java.awt.event.MouseEvent;
-import java.beans.PropertyChangeEvent;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.List;
 import java.util.Set;
 import java.util.Vector;
 
 import javax.swing.Action;
 
-import org.argouml.model.AssociationChangeEvent;
-import org.argouml.model.AttributeChangeEvent;
 import org.argouml.model.Model;
 import org.argouml.ui.ArgoJMenu;
 import org.argouml.ui.targetmanager.TargetManager;
 import org.argouml.uml.diagram.DiagramSettings;
-import org.argouml.uml.diagram.ExtensionsCompartmentContainer;
+import org.argouml.uml.diagram.ExtensionPointsCompartmentContainer;
 import org.argouml.uml.diagram.ui.ActionAddExtensionPoint;
 import org.argouml.uml.diagram.ui.ActionAddNote;
 import org.argouml.uml.diagram.ui.ActionCompartmentDisplay;
-import org.argouml.uml.diagram.ui.CompartmentFigText;
-import org.argouml.uml.diagram.ui.FigNodeModelElement;
-import org.tigris.gef.base.Editor;
-import org.tigris.gef.base.Globals;
+import org.argouml.uml.diagram.ui.FigCompartmentBox;
+import org.argouml.uml.diagram.ui.FigExtensionPointsCompartment;
 import org.tigris.gef.base.Selection;
 import org.tigris.gef.presentation.Fig;
 import org.tigris.gef.presentation.FigCircle;
-import org.tigris.gef.presentation.FigGroup;
-import org.tigris.gef.presentation.FigLine;
-import org.tigris.gef.presentation.FigRect;
-import org.tigris.gef.presentation.FigText;
 
 /**
  * A fig to display use cases on use case diagrams.<p>
@@ -114,60 +102,20 @@
  * origin is at our top left corner, and the Y coordinates are
  * reversed.<p>
  */
-public class FigUseCase extends FigNodeModelElement
-    implements ExtensionsCompartmentContainer {
+public class FigUseCase extends FigCompartmentBox
+    implements ExtensionPointsCompartmentContainer {
 
     /**
-     * The minimum padding allowed above and below the rectangle for
+     * The minimum padding allowed above the rectangle for
      * the use case name and extension points to the top of the use
-     * case oval itself.<p>
+     * case oval itself.
      */
     private static final int MIN_VERT_PADDING = 4;
-    
-    // Space between ellipse and stereotype underneath
-    private static final int STEREOTYPE_PADDING = 0;
-    
-
-    /**
-     * Space above and below the line separating name from extension
-     * points. The line takes a further 1 pixel.<p>
-     */
-    private static final int SPACER = 2;
-
-    /**
-     * UML use cases do not really have ports, so just define one big
-     * one so that users can drag edges to or from any point in the
-     * icon.<p>
-     */
-    private FigMyCircle bigPort;
-
-    /**
-     * We don't use bigPort for the actual graphics of the oval. We
-     * define an identical oval that sits on top of it.<p>
-     */
-    private FigMyCircle cover;
 
     /**
-     * The line separating name and extension points.<p>
+     * The Fig for the extensionPoints compartment (if any).
      */
-    private FigLine epSep;
-
-    /**
-     * The vector of graphics for extension points (if any). First one
-     * is the rectangle for the entire extension points box.<p>
-     */
-    private FigGroup epVec;
-
-    /**
-     * The rectangle for the entire extension point box.<p>
-     */
-    private FigRect epBigPort;
-
-    /**
-     * Text highlighted by mouse actions on the diagram. Assumed to
-     * belong to the extension point compartment.<p>
-     */
-    private CompartmentFigText highlightedFigText;
+    private FigExtensionPointsCompartment extensionPointsFigCompartment;
 
     /**
      * Initialization which is common to multiple constructors.<p>
@@ -175,77 +123,65 @@
      * There should be no size calculations here, nor color setting,
      * since not all attributes are set yet (like e.g. fill color).
      */
-    private void initialize() {        
+    private void initialize(Rectangle bounds) {       
+        enableSizeChecking(false);
+        setSuppressCalcBounds(true); 
         // Create all the things we need
 
         // First the main port ellipse and the cover of identical size that
-        // will realize it. Use arbitrary dimensions for now.
-
-        bigPort = new FigMyCircle(0, 0, 100, 60);
-        cover = new FigMyCircle(0, 0, 100, 60);
-
-        // Mark the text as NOT filled.
-        // The use of multi-line text is not supported 
-        // (how do we enter a multi-line name?).
+        // will realize it. 
+//        setBigPort(new FigMyCircle(0, 0, 100, 60));
+        // repeat this from the parent, since we now have a different bigPort:
+//        getBigPort().setLineWidth(0);
+        /* The bigPort draws the background color: */
+//        getBigPort().setFillColor(FILL_COLOR);
+        
+        /* TODO: This next line prevent loading a UseCase 
+         * with a stereotype to grow. Why? */
+        getStereotypeFig().setVisible(true);
         
-        /* TODO: The above comment hints that the ReturnAction 
-         * should be INSERT, not END_EDITING. */
-
-        getNameFig().setTextFilled(false);
-        getNameFig().setFilled(false);
-        getNameFig().setLineWidth(0);
-        getNameFig().setReturnAction(FigText.END_EDITING);
-
-        // The separator, again with arbitrary bounds for now.
-
-        epSep = new FigLine(0, 30, 100, 100);
-        epSep.setLineWidth(LINE_WIDTH);
-
-        epSep.setVisible(false);
-
-        // The surrounding box for the extension points, again with arbitrary
-        // bounds for now (but made the same width as the name field, so the
-        // name field width will dominate size calculations, but there is a
-        // space to double click in for a new EP. It is not filled, nor has it
-        // a surrounding line. Its bounds, which allow for one line (which is
-        // empty) are the same as for the name box at this stage.
-
-        epBigPort =
-	    new FigRect(0, 30, getNameFig().getBounds().width, 20);
-
-        epBigPort.setFilled(false);
-        epBigPort.setLineWidth(0);
-        epBigPort.setVisible(false);
-
-        // The group for the extension points. The first entry in the group
-        // is the overall surrounding box itself. The group is not filled, nor
-        // has any line. The first entry we add is the epBigPort
-
-        epVec = new FigGroup();
-
-        epVec.setFilled(false);
-        epVec.setLineWidth(0);
-        epVec.setVisible(false);
-
-        epVec.addFig(epBigPort);
-
-        setBigPort(bigPort);
-
         // add Figs to the FigNode in back-to-front order
-        addFig(bigPort);
-        addFig(cover);
+        addFig(getBigPort());
         addFig(getNameFig());
+        // stereotype fig covers the name fig:
         addFig(getStereotypeFig());
-        addFig(epSep);
-        addFig(epVec);
-
-        updateExtensionPoint();
+        // Side effect: This creates the fig:
+        addFig(getExtensionPointsCompartment());
+        addFig(getBorderFig());
+
+        // Make all the parts match the main fig
+        setFilled(true);
+        setFillColor(FILL_COLOR);
+        setLineColor(LINE_COLOR);
+        setLineWidth(LINE_WIDTH);
         
-        // Having built the figure, getBounds finds the enclosing rectangle,
-        // which we set as our bounds.
+        // by default, do not show extension points:
+        setExtensionPointsVisible(false);
+
+        /* Set the drop location in the case of D&D: */
+        if (bounds != null) {
+            setLocation(bounds.x, bounds.y);
+        }
+
+        setSuppressCalcBounds(false);
         setBounds(getBounds());
+        enableSizeChecking(true);
     }
     
+    @Override
+    protected Fig createBigPortFig() {
+        /* Use arbitrary dimensions for now. */
+        return new FigMyCircle(0, 0, 100, 60);
+    }
+
+    @Override
+    protected Fig createBorderFig() {
+        Fig b = new FigMyCircle(0, 0, 100, 60);
+        b.setLineColor(LINE_COLOR);
+        b.setLineWidth(LINE_WIDTH);
+        return b;
+    }
+
     /**
      * Construct a use case figure with the given owner, bounds, and rendering 
      * settings.  This constructor is used by the PGML parser.
@@ -257,49 +193,7 @@
     public FigUseCase(Object owner, Rectangle bounds, 
             DiagramSettings settings) {
         super(owner, bounds, settings);
-        initialize();
-        if (bounds != null) {
-            setLocation(bounds.x, bounds.y);
-        }
-    }
-
-    /**
-     * The text string to be used as the default name of the new use
-     * case fig. This name is only shown on the diagram when drawing 
-     * with the mouse as long as the mouse button is down - once 
-     * the mouse button is released, this is  immediately
-     * overwritten - presumably somewhere in the creation code for the
-     * object, which chooses to define a name.
-     *
-     * @return  The desired text of the default name.
-     */
-    @Override
-    public String placeString() {
-        return "new Use Case";
-    }
-
-    /**
-     * Make a copy of the current fig.<p>
-     *
-     * Uses the generic superclass clone which gives a list of all
-     * the figs. Then initialize our instance variables from this
-     * list.<p>
-     *
-     * @return  A new copy of the the current fig.
-     */
-    @Override
-    public Object clone() {
-        FigUseCase figClone = (FigUseCase) super.clone();
-        Iterator it = figClone.getFigs().iterator();
-
-        figClone.bigPort = (FigMyCircle) it.next();
-        figClone.cover = (FigMyCircle) it.next();
-        figClone.setNameFig((FigText) it.next());
-        it.next();
-        figClone.epSep = (FigLine) it.next();
-        figClone.epVec = (FigGroup) it.next();
-
-        return figClone;
+        initialize(bounds);
     }
 
     /**
@@ -362,11 +256,12 @@
     @Override
     public String classNameAndBounds() {
         return super.classNameAndBounds()
-                + "extensionPointVisible=" + isExtensionPointVisible();
+                + "extensionPointVisible=" + isExtensionPointsVisible();
     }
 
-    public boolean isExtensionPointVisible() {
-        return epVec.isVisible();
+    public boolean isExtensionPointsVisible() {
+        return extensionPointsFigCompartment != null 
+            && extensionPointsFigCompartment.isVisible();
     }
 
     /**
@@ -383,37 +278,10 @@
      * @param isVisible  <code>true</code> if the compartment should be shown,
      *                   <code>false</code> otherwise.
      *
-     * @see org.argouml.uml.diagram.ExtensionsCompartmentContainer#setExtensionPointVisible(boolean)
+     * @see org.argouml.uml.diagram.ExtensionPointsCompartmentContainer#setExtensionPointsVisible(boolean)
      */
-    public void setExtensionPointVisible(boolean isVisible) {
-        if (epVec.isVisible() && (!isVisible)) {
-            setExtensionPointVisibleInternal(false);
-        } else if ((!epVec.isVisible()) && isVisible) {
-            setExtensionPointVisibleInternal(true);
-        }
-        /* Move the stereotype out of the way: */
-        updateStereotypeText();
-    }
-
-    private void setExtensionPointVisibleInternal(boolean visible) {
-        // Record our current bounds for later use
-        Rectangle oldBounds = getBounds();
-
-        // Tell GEF that we are starting to make a change. Loop through the
-        // epVec marking each element as not visible.
-        for (Fig fig : (List<Fig>) epVec.getFigs()) {
-            fig.setVisible(visible);
-        }
-
-        // Mark the vector itself and the separator as not displayed
-        epVec.setVisible(visible);
-        epSep.setVisible(visible);
-
-        // Redo the bounds and then tell GEF the change has finished
-        setBounds(oldBounds.x, oldBounds.y,
-                oldBounds.width,
-                oldBounds.height);
-        endTrans();
+    public void setExtensionPointsVisible(boolean isVisible) {
+        setCompartmentVisible(extensionPointsFigCompartment, isVisible);
     }
 
     /**
@@ -428,53 +296,21 @@
     }
 
     /**
-     * Compute the minimum acceptable size of the use case.<p>
-     *
-     * We work out the minimum size of the text box, and from that the radii
-     *   of the enclosing ellipse.<p>
-     *
-     * @return  The dimensions of the smallest size bounding box of the use
-     *          case.
-     */
-    @Override
-    public Dimension getMinimumSize() {
-
-        Dimension textSize = getTextSize();
-
-        Dimension size = calcEllipse(textSize, MIN_VERT_PADDING);
-
-        return new Dimension(Math.max(size.width, 100),
-			     Math.max(size.height, 60));
-    }
-
-    /**
-     * A private utility routine to calculate the minimum size of the
-     *   rectangle to hold the name and extension points (if displayed).<p>
-     *
-     * @return  The dimensions of the rectangle
+     * Compute the dimensions of an ellipse that intersects the 4 corners 
+     * of the given box.
+     * 
+     * @param box the width and height of the box
+     * @return the dimension of the ellipse
      */
-    private Dimension getTextSize() {
-        Dimension minSize = getNameFig().getMinimumSize();
-
-        // Now allow for the extension points, if they are displayed
-        if (epVec.isVisible()) {
-
-            // Allow for a separator (spacer each side + 1 pixel width line)
-            minSize.height += 2 * SPACER + 1;
-
-            // Loop through all the extension points, to find the widest
-            List<CompartmentFigText> figs = getEPFigs();
-            for (CompartmentFigText f : figs) {
-                int elemWidth = f.getMinimumSize().width;
-                minSize.width = Math.max(minSize.width, elemWidth);
-            }
-
-            // Height allows one row for each extension point
-            int rowHeight = Math.max(ROWHEIGHT, minSize.height);
-            minSize.height += rowHeight * Math.max(1, figs.size());
-        }
+    public Dimension addCompartmentBoxSurroundings(Dimension box) {
+        containerBox = box;
+        
+        @SuppressWarnings("unused")
+        double h = box.height;
+        double w = box.width;
 
-        return minSize;
+        int padding = Math.max((int) (w / 10.0), MIN_VERT_PADDING);
+        return calcEllipse(box, padding);
     }
 
     /**
@@ -514,156 +350,25 @@
         // Result as integers, rounded up. We ensure that the radii are
         // integers for convenience.
 
-        return new Dimension(((int) (Math.ceil(a)) * 2),
-			     ((int) (Math.ceil(b)) * 2));
+        return new Dimension(((int) (Math.ceil(a) + getLineWidth()) * 2),
+			     ((int) (Math.ceil(b) + getLineWidth()) * 2));
     }
 
-    /**
-     * Change the boundary of the use case.<p>
-     *
-     * If we are called with less than the minimum size, we impose the
-     *   minimum size.<p>
-     *
-     * We place the name and extension points at the centre of the
-     *   rectangle.<p>
-     *
-     * Set the bounds of all components of the Fig.<p>
-     *
-     * @param x  X coordinate of upper left corner
-     *
-     * @param y  Y coordinate of upper left corner
-     *
-     * @param w  width of bounding box
-     *
-     * @param h  height of bounding box
-     */
     @Override
-    protected void setBoundsImpl(int x, int y, int w, int h) {
-
-        // Remember where we are at present, so we can tell GEF later. Then
-        // check we are as big as the minimum size
-        Rectangle oldBounds = getBounds();
-        Dimension minSize = getMinimumSize();
-
-        int newW = (minSize.width > w) ? minSize.width : w;
-        int newH = (minSize.height > h) ? minSize.height : h;
-        
-        newH = newH - (getStereotypeFig().getHeight() + STEREOTYPE_PADDING);
-
-        // Work out the size of the name and extension point rectangle, and
-        // hence the vertical padding
-        Dimension textSize = getTextSize();
-        int vPadding = (newH - textSize.height) / 2;
-
-        // Adjust the alignment of the name.
-        Dimension nameSize = getNameFig().getMinimumSize();
-
-        getNameFig().setBounds(x + ((newW - nameSize.width) / 2),
-			       y + vPadding,
-			       nameSize.width,
-			       nameSize.height);
-
-        // Place extension points if they are showing
-        if (epVec.isVisible()) {
-
-            // currY tracks the current vertical position of each element. The
-            // separator is _SPACER pixels below the name. Its length is
-            // calculated from the formula for an ellipse.
-            int currY = y + vPadding + nameSize.height + SPACER;
-            int sepLen =
-		2 * (int) (calcX(newW / 2.0,
-				  newH / 2.0,
-				  newH / 2.0 - (currY - y)));
-
-            epSep.setShape(x + (newW - sepLen) / 2,
-			    currY,
-			    x + (newW + sepLen) / 2,
-			    currY);
-
-            // Extension points are 1 pixel for the line and _SPACER gap below
-            // the separator
-            currY += 1 + SPACER;
-
-            // Move the extension point figures. For
-            // now we assume that extension points are the width of the overall
-            // text rectangle (true unless the name is wider than any EP).
-            updateFigGroupSize(
-               	   x + ((newW - textSize.width) / 2),
-               	   currY,
-               	   textSize.width,
-               	   (textSize.height - nameSize.height - SPACER * 2 - 1));
-        }
-
-        // Set the bounds of the bigPort and cover
-        bigPort.setBounds(x, y, newW, newH);
-        cover.setBounds(x, y, newW, newH);
-
-        // Record the changes in the instance variables of our parent, tell GEF
-        // and trigger the edges to reconsider themselves.
-        _x = x;
-        _y = y;
-        _w = newW;
-        _h = newH + getStereotypeFig().getHeight() + STEREOTYPE_PADDING;
-        
-        positionStereotypes();
-
-        firePropChange("bounds", oldBounds, getBounds());
-        updateEdges();
-    }
-
-    /**
-     * Calculates the new size of the FigGroup (based on its extensionPoints)
-     * after calculation new bounds for all sub-figs, considering their minimal
-     * sizes; FigGroup need not be displayed; no update event is fired.
-     * This used to be a duplicate method from FigEditableCompartment. <p>
-     * 
-     * TODO: Follow the improvements done to 
-     * the similar code in FigEditableCompartment. 
-     *
-     * @param x
-     *            x
-     * @param y
-     *            y
-     * @param w
-     *            w
-     * @param h
-     *            h
-     */
-    protected void updateFigGroupSize(int x, int y, int w,
-            int h) {
-        int newW = w;
-        int n = epVec.getFigs().size() - 1;
-        int newH =
-            isCheckSize() ? Math.max(h, ROWHEIGHT * Math.max(1, n) + 2)
-                : h;
-
-        // set new bounds for all included figs
-        Iterator figs = epVec.getFigs().iterator();
-        figs.next(); // skip epBigPort
-        Fig fi;
-        int fw, fh;
-        int yy = y;
-        while (figs.hasNext()) {
-            fi = (Fig) figs.next();
-            fw = fi.getMinimumSize().width;
-            fh = fi.getMinimumSize().height;
-            if (!isCheckSize() && fw > newW - 2) {
-                fw = newW - 2;
-            }
-            fi.setBounds(x + 1, yy + 1, fw, fh/* - 2*/);
-            if (isCheckSize() && newW < fw + 2) {
-                newW = fw + 2;
-            }
-            yy += fh;
-        }
-        epBigPort.setBounds(x, y, newW, newH);
-        // calculate the rectangle containing all FigText objects:
-        epVec.calcBounds();
+    protected Rectangle calculateCompartmentBoxDimensions(
+            int x, int y, int w, int h) {
+        /* For an ellipse, we can put the box in the middle:  */
+        return new Rectangle(
+                x + (w - containerBox.width) / 2, 
+                y + (h - containerBox.height) / 2, 
+                containerBox.width, 
+                containerBox.height);
     }
 
     /**
      * Private utility routine to work out the (positive) x coordinate of a
      * point on an oval, given the radii and y coordinate.<p>
+     * TODO: Use this to calculate the separator lines!
      *
      * @param a  radius in X direction
      * @param b  radius in Y direction
@@ -671,6 +376,9 @@
      * @return   Positive X coordinate for the given Y coordinate
      */
     private double calcX(double a, double b, double y) {
+        assert a > 0;
+        assert b > 0;
+        assert b > y;
         return (a * Math.sqrt(b * b - y * y)) / b;
     }
 
@@ -685,22 +393,8 @@
      */
     @Override
     public void setLineColor(Color col) {
-        if (cover != null) {
-            cover.setLineColor(col);
-            epSep.setLineColor(col);
-        }
-    }
-
-    /**
-     * Get the line colour for the use case oval.<p>
-     *
-     * This involves getting the <code>cover</code> oval colour, not the bigPort.
-     * 
-     * @return  The colour in use.
-     */
-    @Override
-    public Color getLineColor() {
-        return cover.getLineColor();
+           super.setLineColor(col);
+           getBigPort().setLineColor(null);
     }
 
     /**
@@ -714,21 +408,8 @@
      */
     @Override
     public void setFillColor(Color col) {
-        if (cover != null) {
-            cover.setFillColor(col);
-        }
-    }
-
-    /**
-     * Get the line colour for the use case oval.<p>
-     *
-     * This involves getting the <code>cover</code> oval colour, not the bigPort.
-     *
-     * @return  The colour in use.
-     */
-    @Override
-    public Color getFillColor() {
-        return cover.getFillColor();
+        super.setFillColor(col);
+        getBorderFig().setFillColor(null);
     }
 
     /**
@@ -744,50 +425,8 @@
      */
     @Override
     public void setFilled(boolean f) {
-        if (cover != null) {
-            cover.setFilled(f);
-        }
-    }
-
-    /**
-     * Get whether the use case oval is to be filled.<p>
-     *
-     * This involves getting the <code>cover</code> oval, not the bigPort.<p>
-     *
-     * @return  <code>true</code> if the oval is to be filled,
-     *          <code>false</code> if not.
-     */
-    @Override
-    public boolean isFilled() {
-        return cover.isFilled();
-    }
-
-    /**
-     * Set the line width for the use case oval.<p>
-     *
-     * This involves setting the <code>cover</code> oval, not the bigPort.
-     * Calling the super method would cause all FigGroup elements
-     * to be filled, too - which is not wanted for e.g. the stereotype figs.
-     *
-     * @param w  The line width desired.
-     */
-    @Override
-    public void setLineWidth(int w) {
-        if (cover != null) {
-            cover.setLineWidth(w);
-        }
-    }
-
-    /**
-     * Get the line width for the use case oval.<p>
-     *
-     * This involves getting the <code>cover</code> oval colour, not the bigPort.<p>
-     *
-     * @return  The line width set.
-     */
-    @Override
-    public int getLineWidth() {
-        return cover.getLineWidth();
+        super.setFilled(f);
+        getBorderFig().setFilled(false);
     }
 
     /**
@@ -873,336 +512,66 @@
      */
     @Override
     public Point connectionPoint(Point anotherPt) {
-        return bigPort.connectionPoint(anotherPt);
-    }
-
-    ///////////////////////////////////////////////////////////////////////////
-    //
-    // Event handlers
-    //
-    ///////////////////////////////////////////////////////////////////////////
-
-    /**
-     * React to a mouse key being pressed.<p>
-     *
-     * @param me  The mouse action that caused us to be invoked.
-     */
-    @Override
-    public void mousePressed(MouseEvent me) {
-
-        // Deal with anything from the parent first
-        super.mousePressed(me);
-
-        // If we are currently selected, turn off the draggable buttons at each
-        // side, and unhighlight any currently selected extension points.
-        Editor ce = Globals.curEditor();
-        if (ce != null) {
-            Selection sel = ce.getSelectionManager().findSelectionFor(this);
-            if (sel instanceof SelectionUseCase) {
-                ((SelectionUseCase) sel).hideButtons();
-            }
-        }
-
-        unhighlight();
-
-        // Display extension point properties if necessary. Look to see if the
-        // mouse (2x2 pixels) hit the extension point compartment. Use a flag
-        // to track this.
-        Rectangle r = new Rectangle(me.getX() - 1, me.getY() - 1, 2, 2);
-        Fig f = hitFig(r);
-
-
-        if (f == epVec) {
-
-            // Work out which extension point this corresponds to. Each EP
-            // takes ROWHEIGHT pixels, so take the difference between the
-            // centre of the mouse (me.getY() - 1) and the top of the epVec
-            // (f.getY()) and integer divide by ROWHEIGHT.
-            int i = (me.getY() - f.getY() - 1) / ROWHEIGHT;
-
-            List<CompartmentFigText> figs = getEPFigs();
-            
-            // If we are in the range of the EP list size (avoids any nasty
-            // boundary overflows), we can select that EP entry. Make this
-            // entry the target Fig, and note that we do have a
-            // target.             
-            if ((i >= 0) && (i < figs.size())) {
-                highlightedFigText = figs.get(i);
-                highlightedFigText.setHighlighted(true);
-            }
-        }
-    }
-
-    /**
-     * React to a mouse key being clicked.<p>
-     *
-     * @param me  The mouse action that caused us to be invoked.
-     */
-    @Override
-    public void mouseClicked(MouseEvent me) {
-	super.mouseClicked(me);
-
-	if (me.isConsumed()) {
-	    return;
-	}
-
-	if (!isExtensionPointVisible() || me.getY() < epSep.getY1()) {
-	    getNameFig().mouseClicked(me);
-	} else if (me.getClickCount() >= 2
-		   && !(me.isPopupTrigger()
-			|| me.getModifiers() == InputEvent.BUTTON3_MASK)) {
-	    createContainedModelElement(epVec, me);
-	}
-    }
-
-    /**
-     * Deal with the mouse leaving the fig. Unhighlight the fig.<p>
-     *
-     * @param me  The mouse action that caused us to be invoked.
-     */
-    @Override
-    public void mouseExited(MouseEvent me) {
-        super.mouseExited(me);
-        unhighlight();
-    }
-
-    /**
-     * Create a new "feature" (extension point) in the use case fig.<p>
-     *
-     * Extension points are not strictly features, but that is a historical
-     *   accident of naming. This creates a new entry in the extension point
-     *   vector.<p>
-     *
-     * @param fg  The fig group to which this applies (which must be the
-     *            extension point vector).
-     *
-     * @param ie  The input event that triggered us. In the current
-     *            implementation a mouse double click.
-     */
-    protected void createContainedModelElement(FigGroup fg, InputEvent ie) {
-
-        // Give up if we don't have an owner
-        if (getOwner() == null) {
-            return;
-        }
-
-        // Invoke the relevant action method to create an empty extension
-        // point, then start the editor, assuming we successfully created an
-        // extension point.
-        ActionAddExtensionPoint.singleton().actionPerformed(null);
-
-        CompartmentFigText ft =
-            (CompartmentFigText) fg.getFigs().get(fg.getFigs().size() - 1);
-
-        if (ft != null) {
-            ft.startTextEditor(ie);
-            ft.setHighlighted(true);
-
-            highlightedFigText = ft;
-        }
-        ie.consume();
-    }
-
-    /**
-     * Private utility to unhighlight any currently selected extension
-     * point.<p>
-     *
-     * @return  The extension point that was unhighlighted.
-     */
-    private CompartmentFigText unhighlight() {
-
-        // Loop through the list of extension points, until we find a
-        // highlighted one.
-        for (CompartmentFigText ft : getEPFigs()) {
-            if (ft.isHighlighted()) {
-                ft.setHighlighted(false);
-                highlightedFigText = null;
-                return ft;
-            }
-        }
-
-        // None were highlighted
-        return null;
-    }
-
-    @Override
-    protected void modelChanged(PropertyChangeEvent mee) {
-
-        // Let our superclass sort itself out first
-        super.modelChanged(mee);
-        if (mee instanceof AssociationChangeEvent 
-                || mee instanceof AttributeChangeEvent) {
-            renderingChanged();
-            updateListeners(getOwner(), getOwner());
-        }
+        return getBigPort().connectionPoint(anotherPt);
     }
 
     @Override
     protected void updateListeners(Object oldOwner, Object newOwner) {
-        Set<Object[]> l = new HashSet<Object[]>();
+        Set<Object[]> listeners = new HashSet<Object[]>();
         /* Let's register for events from all modelelements
          * that change the name or body text: 
          */
         if (newOwner != null) {
-            /* Register for name changes, added extensionpoints
+            /* Register for name changes, added extensionPoints
              * and abstract makes the text italic.
              * All Figs need to listen to "remove", too: */
-            l.add(new Object[] {newOwner, 
+            listeners.add(new Object[] {newOwner, 
                                 new String[] {"remove", "name", "isAbstract", 
                                     "extensionPoint", "stereotype"}});
             
             // register for extension points:
             for (Object ep : Model.getFacade().getExtensionPoints(newOwner)) {
-                l.add(new Object[] {ep, new String[] {"location", "name"}});
+                listeners.add(new Object[] {ep, new String[] {"location", "name"}});
             }
             
             for (Object st : Model.getFacade().getStereotypes(newOwner)) {
-                l.add(new Object[] {st, "name"});
+                listeners.add(new Object[] {st, "name"});
             }
         }
-        updateElementListeners(l);
+        updateElementListeners(listeners);
     }
 
     @Override
     public void renderingChanged() {
         super.renderingChanged();
         if (getOwner() != null) {
-            updateExtensionPoint();
-        }
-    }
-
-    /**
-     * Updates the extensionPoints in the fig. <p>
-     * 
-     * A difference in behaviour of this function
-     * compared to the similar 
-     * FigEditableCompartment.populate()
-     * is that the extensionPoints 
-     * are not ordered, while features are.
-     */
-    protected void updateExtensionPoint() {
-        // Give up if we have no owner
-        Object useCase = getOwner();
-        if (useCase == null) {
-            return;
+            updateExtensionPoints();
         }
-
-        // Note our current bounds
-        Rectangle oldBounds = getBounds();
-
-        // Loop through all the extension points. epCount keeps track of the
-        // fig's index as we go through the extension points.
-        Collection eps =
-	    Model.getFacade().getExtensionPoints(useCase);
-        int epCount = 1;
-
-        if ((eps != null) && (eps.size() > 0)) {
-            int xpos = epBigPort.getX();
-            int ypos = epBigPort.getY();
-
-            // Take each EP and its corresponding fig in turn
-            Iterator iter = eps.iterator();
-            List<CompartmentFigText> figs = getEPFigs();
-            List<CompartmentFigText> toBeRemoved = 
-                new ArrayList<CompartmentFigText>(figs);
-
-            while (iter.hasNext()) {
-                CompartmentFigText epFig = null;
-                Object ep = iter.next();
-
-                /* Find the fig for this extensionPoint: */
-                for (CompartmentFigText candidate : figs) {
-                    if (candidate.getOwner() == ep) {
-                        epFig = candidate;
-                        break;
-                    }
-                }
-
-                // If we don't have a fig for this EP, we'll need to add
-                // one. We set the bounds, but they will be reset later.
-                if (epFig == null) {
-                     epFig = new FigExtensionPoint(ep, new Rectangle(
-                            xpos,
-			    ypos + (epCount - 1) * ROWHEIGHT,
-			    0,
-			    ROWHEIGHT),
-			    getSettings());
-                    epVec.addFig(epFig);
-                } else {
-                    /* This one is still usable, so let's not remove it: */
-                    toBeRemoved.remove(epFig);
-                }
-
-                // Now put the text in
-                // We must handle the case where the text is null
-                String epText = epFig.getNotationProvider().toString(ep, 
-                        getNotationSettings());
-                if (epText == null) {
-                    epText = "";
-                }
-                epFig.setText(epText);
-
-                epCount++;
-            }
-
-            // Remove any spare figs we have if there are now fewer extension
-            // points than figs
-            for (Fig f : toBeRemoved) {
-                epVec.removeFig(f);    
-            }
-        }
-
-        // Now recalculate all the bounds, using our old bounds.
-        setBounds(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height);
     }
-
-    @Override
-    protected void updateNameText() {
-        Object useCase = getOwner();
-        if (useCase == null) {
+    
+    protected void updateExtensionPoints() {
+        if (!isExtensionPointsVisible()) {
             return;
         }
-        Rectangle oldBounds = getBounds();
-        // Now things to do with the use case itself. Put the use case in
-        // italics if it is abstract, otherwise ordinary font.
-
-        super.updateNameText();
-        setBounds(oldBounds.x, oldBounds.y, oldBounds.width, oldBounds.height);
-    }
+        extensionPointsFigCompartment.populate();
 
-    @Override
-    protected void updateStereotypeText() {
-        super.updateStereotypeText();
-        if (getOwner() == null) {
-            return;
-        }
-        positionStereotypes();
+        setBounds(getBounds());
         damage();
     }
     
-    private void positionStereotypes() {
-        if (((FigGroup) getStereotypeFig()).getFigCount() > 0) {
-            getStereotypeFig().setBounds(
-        	    (getX() + getWidth() / 2
-        		    - getStereotypeFig().getWidth() / 2),
-        	    (getY() + bigPort.getHeight() + STEREOTYPE_PADDING),
-                    getStereotypeFig().getWidth(),
-                    getStereotypeFig().getHeight());
-        } else {
-            getStereotypeFig().setBounds(0, 0, 0, 0);
-        }
-    }
-
     /**
-     * Get a list of the extension point Figs <em>without</em> the first fig
-     * which is the bigPort fig.
-     * 
-     * @return a list of the extension point Figs
+     * @return the Fig for the extension point compartment
      */
-    private List<CompartmentFigText> getEPFigs() {
-        List<CompartmentFigText> l = 
-            new ArrayList<CompartmentFigText>(epVec.getFigs());
-        l.remove(0);
-        return l;
+    public FigExtensionPointsCompartment getExtensionPointsCompartment() {
+        // Set bounds will be called from our superclass constructor before
+        // our constructor has run, so make sure this gets set up if needed.
+        if (extensionPointsFigCompartment == null) {
+            extensionPointsFigCompartment = new FigExtensionPointsCompartment(
+                    getOwner(),
+                    DEFAULT_COMPARTMENT_BOUNDS, 
+                    getSettings());
+        }
+        return extensionPointsFigCompartment;
     }
+
 }

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/StylePanelFigUseCase.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/StylePanelFigUseCase.java?view=diff&pathrev=17365&r1=17364&r2=17365
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/StylePanelFigUseCase.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/StylePanelFigUseCase.java	2009-09-30 23:13:34-0700
@@ -1,5 +1,5 @@
 // $Id$
-// Copyright (c) 1996-2007 The Regents of the University of California. All
+// Copyright (c) 1996-2009 The Regents of the University of California. All
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 // software and its documentation without fee, and without a written
 // agreement is hereby granted, provided that the above copyright notice
@@ -82,7 +82,7 @@
 
         FigUseCase target = (FigUseCase) getTarget();
 
-        epCheckBox.setSelected(target.isExtensionPointVisible());
+        epCheckBox.setSelected(target.isExtensionPointsVisible());
 
         refreshTransaction = false;
     }
@@ -98,7 +98,7 @@
         if (!refreshTransaction) {
             if (e.getSource() == epCheckBox) {
                 FigUseCase target = (FigUseCase) getTarget();
-                target.setExtensionPointVisible(epCheckBox.isSelected());
+                target.setExtensionPointsVisible(epCheckBox.isSelected());
             } else {
                 super.itemStateChanged(e);
             }


------------------------------------------------------
http://argouml.tigris.org/ds/viewMessage.do?dsForumId=5905&dsMessageId=2402374

To unsubscribe from this discussion, e-mail: [[email protected]].
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.