svn commit: r16602 - trunk/src/argouml-app: . src/org/argouml/persistence src/org/argouml/ui src/org/argouml/uml/diagram/collaboration/ui src/org/argouml/uml/diagram/state/ui src/org/argouml/uml/diagram/static_structure/ui src/org/argouml/uml/diagram/ui src/org/argouml/uml/diagram/use_case/ui

Dave Thompson <[email protected]>
Newsgroups gmane.comp.lang.uml.argouml.cvs
Message-ID <[email protected]>
Author: dthompson
Date: 2009-01-14 12:33:14-0800
New Revision: 16602

Added:
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/ModeLabelDrag.java
      - copied unchanged from r16600, /branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/uml/diagram/ui/ModeLabelDrag.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/ModeLabelDragFactory.java
      - copied unchanged from r16600, /branches/work_issue1048_dthompson/src/argouml-app/src/org/argouml/uml/diagram/ui/ModeLabelDragFactory.java
Modified:
   trunk/src/argouml-app/   (props changed)
   trunk/src/argouml-app/src/org/argouml/persistence/PGML.tee
   trunk/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java
   trunk/src/argouml-app/src/org/argouml/ui/MultiEditorPane.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/collaboration/ui/FigAssociationRole.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/state/ui/FigTransition.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigLink.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigDependency.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEdgeModelElement.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigGeneralization.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigTextGroup.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/PathItemPlacement.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/TabDiagram.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtend.java
   trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigInclude.java

Log:
Issue 1048: merging from branches/work_issue_1048_dthompson to trunk, implementing adjustment of labels on path items.
Notable changes:
* New mode at the top of the GEF mode stack: ModeLabelDrag, to handle the label drag events. The stack is reinitialised in MultiEditorPane.java.
* Switched most (all?) of the path item placement strategies to PathItemPlacement
* Selection boxes are removed for path items, and instead are highlighted in an alpha shaded blue.
* Double-clicking anywhere in the shaded area of a path item edits the first editable text box.
* Path item positions are saved to the .uml file using a modified PGML.tee.
* Path item positions are restored from the .uml file using PrivateHandler.java.
* Some tweaks to PathItemPlacement to make it position labels more reliably.
For more info, see issue 1048 and http://argouml.tigris.org/wiki/Issue1048

Modified: trunk/src/argouml-app/src/org/argouml/persistence/PGML.tee
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/persistence/PGML.tee?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/persistence/PGML.tee	(original)
+++ trunk/src/argouml-app/src/org/argouml/persistence/PGML.tee	2009-01-14 12:33:14-0800
@@ -137,6 +137,39 @@
 
 <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
 
+<template class="org.tigris.gef.base.PathConv">
+
+<![CDATA[
+
+<argouml:pathitem figname="<ocl>org.argouml.persistence.PgmlUtility.getId(self.pathFig)</ocl>"
+                  classname="<ocl>self.class.name</ocl>"
+                  ownerhref="<ocl ignoreNull>org.argouml.uml.UUIDHelper.getUUID(self.pathFig)</ocl>" />
+
+]]>
+
+</template>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
+<template class="org.argouml.uml.diagram.ui.PathItemPlacement">
+
+<![CDATA[
+
+<argouml:pathitem figname="<ocl>org.argouml.persistence.PgmlUtility.getId(self.itemFig)</ocl>"
+                  classname="<ocl>self.class.name</ocl>"
+                  figclassname="<ocl>self.itemFig.class.name</ocl>"
+                  ownerhref="<ocl ignoreNull>org.argouml.uml.UUIDHelper.getUUID(self.itemFig)</ocl>"
+                  angle="<ocl>self.angle</ocl>"
+                  offset="<ocl>self.vectorOffset</ocl>" />
+
+]]>
+
+</template>
+
+
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+
 <template class="org.tigris.gef.presentation.FigRect">
 
 <![CDATA[
@@ -525,7 +558,8 @@
     sourceFigNode="<ocl>org.argouml.persistence.PgmlUtility.getId(self.sourceFigNode)</ocl>"
 
     destFigNode="<ocl>org.argouml.persistence.PgmlUtility.getId(self.destFigNode)</ocl>"
-
+    
+    <ocl>self.pathItemStrategies</ocl>
   </private>
 
 

Modified: trunk/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/persistence/PrivateHandler.java	2009-01-14 12:33:14-0800
@@ -26,12 +26,17 @@
 import java.util.StringTokenizer;
 
 import org.apache.log4j.Logger;
+import org.argouml.uml.diagram.ui.PathItemPlacement;
 import org.argouml.util.IItemUID;
 import org.argouml.util.ItemUID;
+import org.tigris.gef.base.PathItemPlacementStrategy;
 import org.tigris.gef.persistence.pgml.Container;
 import org.tigris.gef.persistence.pgml.FigEdgeHandler;
 import org.tigris.gef.persistence.pgml.FigGroupHandler;
 import org.tigris.gef.persistence.pgml.PGMLHandler;
+import org.tigris.gef.presentation.Fig;
+import org.tigris.gef.presentation.FigEdge;
+import org.xml.sax.Attributes;
 import org.xml.sax.SAXException;
 
 /**
@@ -109,8 +114,151 @@
         // Handle other uses of <private> contents
         super.gotElement(contents);
     }
+    
+    /**
+     * Process starting elements within the private tag.
+     * This method handles all attributes within tags within private methods.
+     * The only specific tags we handle here at the moment are pathitems.
+     * 
+     * The strategy for handling pathitems is as follows:
+     * <ul>
+     *  <li>Data is saved for each path item using one <argouml:pathitem ... /> 
+     *      tag per path item.
+     *  <li>The code that defines what is stored is in 
+     *      org.argouml.persistence.PGML.tee
+     *  <li>Each <argouml:pathitem> tag stores 
+     *  <ul>
+     *    <li>The class name of the PathItemPlacementStrategy
+     *    <li>The class name of the fig which it places.
+     *    <li>The href of the model element which owns the fig being placed.
+     *    <li>The angle of the placement vector (PathItemPlacement.angle)
+     *    <li>The distance along the displacement vector to place the fig
+     *        (PathItemPlacement.vectorOffset).
+     *  </ul>
+     *  </li>
+     *  <li>No specific data is stored to match pathitem tags to the
+     *      diagram figs which they control.
+     *  <li>The matching during file load depends entirely on
+     *      there being a unique figclassname and ownerhref combination
+     *      for each pathitem on the diagram.  For example, For a 
+     *      FigAssociation, the main label is a FigTextGroup, and it's
+     *      owner is assigned to the Association.  This combination is
+     *      unique, and is used to match the parsed pathitem data back 
+     *      to the instantiated PathItemPlacement.
+     *      Another example is the source multiplicity, which is a
+     *      FigMultiplicity, and it's owner is assigned to the
+     *      source model element.
+     *      In each case, the combination is unique, so there is only
+     *      one pathitem that matches when rebuilding the diagram.
+     *  </ul>
+     * 
+     * @param uri
+     * @param localname
+     * @param qname
+     * @param attributes
+     * @throws SAXException
+     * @see org.tigris.gef.persistence.pgml.BaseHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
+     */
+    public void startElement(String uri, String localname, String qname,
+            Attributes attributes) throws SAXException {
+        if ("argouml:pathitem".equals(qname)
+                && container instanceof FigEdgeHandler) {
+            String classname = attributes.getValue("classname");
+            String figclassname = 
+                attributes.getValue("figclassname");
+            String ownerhref = attributes.getValue("ownerhref");
+            String angle = attributes.getValue("angle");
+            String offset = attributes.getValue("offset");
+            if ( classname != null
+                    && figclassname != null
+                    && ownerhref != null
+                    && angle != null
+                    && offset != null ) {
+                // Method 2: (assign data immediately, see end of file).
+                // TODO: if we ever want to extend PathItemPlacement,
+                // we should modify this, so that we also recognise any 
+                // subclass of PathItemPlacement.
+                // Is the class name a PathItemPlacment?
+                if ("org.argouml.uml.diagram.ui.PathItemPlacement".equals(
+                        classname)) {
+                    PathItemPlacementStrategy pips 
+                        = getPips(figclassname, ownerhref);
+                    // Sanity check - the returned path item placement 
+                    // strategy should match the one in the UML.
+                    // If it doesn't, it could be that the UML was 
+                    // created with an older argo version, and the new
+                    // argo version use a different placement strategy.
+                    // If they don't match, just use the default.
+                    if (pips.getClass().getName().equals(classname)) {
+                        // Now we're into processing each specific path 
+                        // item strategy.
+                        // At the moment, we only know PathItemPlacement
+                        if (pips instanceof PathItemPlacement) {
+                            PathItemPlacement pip = 
+                                (PathItemPlacement) pips;
+                            pip.setDisplacementVector(
+                                    Double.parseDouble(angle),
+                                    Integer.parseInt(offset));
+                        }
+                        // Continue (future PathItemPlacementStrategy impl) 
+                        //else if (...) {
+                        //}
+                    }
+                    // If the PathItemPlacement was unknown, leave the
+                    // diagram with the default settings.
+                    else {
+                        LOG.warn("PGML stored pathitem class name does "
+                                + "not match the class name on the "
+                                + "diagram. Label position will revert "
+                                + "to defaults.");
+                    }
+                }
+            }
+            // If any of the values are null, ignore the element.
+            else {
+                LOG.warn("Could not find all attributes for <" 
+                        + qname + "> tag, ignoring.");
+                //System.out.println("Error - one of these is null:" 
+                //        + "classname=" + classname
+                //        + " figclassname=" + figclassname
+                //        + " ownerhref=" + ownerhref
+                //        + " angle=" + angle
+                //        + " offset=" + offset);
+            }
+        }
+        super.startElement(uri, localname, qname, attributes);
+    }
 
     /**
+     * Finds the path item placement strategy for a sub Fig, by its class name,
+     * and it's owner href.
+     * @param figclassname The class name of the fig being placed.
+     * @param ownerhref The href of the owner of the fig being placed.
+     * @return The path item placement strategy.
+     */
+    private PathItemPlacementStrategy getPips(String figclassname, 
+            String ownerhref) {
+        if (container instanceof FigEdgeHandler) {
+            FigEdge fe = ((FigEdgeHandler) container).getFigEdge();
+            Object owner = getPGMLStackParser().findOwner(ownerhref);
+
+            for (Object o : fe.getPathItemFigs()) {
+                Fig f = (Fig) o;
+                // For a match to be found, it has to have the same 
+                // owner, and the same long class name.
+                if (owner.equals(f.getOwner())
+                        && figclassname.equals(f.getClass().getName())) {
+                    //System.out.println("MATCHED! " + figclassname);
+                    return fe.getPathItemPlacementStrategy(f);
+                }
+            }
+        }
+        LOG.warn("Could not load path item for fig '" + figclassname 
+                + "', using default placement.");
+        return null;
+    }
+    
+    /**
      * Determine if the string contains an ItemUID.
      *
      * @return a newly created ItemUID (or <code>null</code>).
@@ -199,3 +347,86 @@
         return rv;
     }
 }
+
+// An alternative implementation of the parsing of pathitems is to collect 
+// everything at the start, then iterate through it all at the end.
+// The code below does this - it works, but it is currently not used,
+// since it is a unnecessarily complicated.
+// There are probably better ways to implement this than using an
+// ArrayList of Hashtables.
+// see option 1 in 
+// http://argouml.tigris.org/issues/show_bug.cgi?id=1048#desc66
+//
+
+///**
+// * A list of the path item attributes for this container.
+// * The list is populated during parsing, them processed at endElement() 
+// */
+//private List<Hashtable<String, String>> pathItemAttrs = 
+//    new ArrayList<Hashtable<String, String>>();
+
+// This code has to go within the startElement block after the strings
+// have been matched.
+
+//// Method 1:
+//// (collect data and assign later in endElement() method).
+//Hashtable<String, String> ht = 
+//    new Hashtable<String, String>(); 
+//ht.put("classname", classname);
+//ht.put("figclassname", figclassname);
+//ht.put("ownerhref", ownerhref);
+//ht.put("angle", angle);
+//ht.put("offset", offset);
+//pathItemAttrs.add(ht);
+
+//public void endElement(String uri, String localname, String qname)
+//throws SAXException {
+////System.out.print("Got endElement: " 
+////        + "uri='" + uri + "'\n" 
+////        + "localname='" + localname + "'\n" 
+////        + "qname='" + qname + "'\n" 
+////);
+//// If we collected any path items for a FigEdgeModelElement,
+//// process them now, and assign their values to real Figs on the diag.
+//if (!(pathItemAttrs.isEmpty())) {
+//    for (Hashtable<String, String> attrs : pathItemAttrs) {
+//        // Is the class name a PathItemPlacment?
+//        // TODO: if we ever want to extend PathItemPlacement,
+//        // we should modify this, so that we also recognise any 
+//        // subclass of PathItemPlacement.
+//        if ("org.argouml.uml.diagram.ui.PathItemPlacement".
+//                equals(attrs.get("classname"))) {
+//            //System.out.println("figclassname=" + attrs.get("figclassname"));
+//            
+//            PathItemPlacementStrategy pips 
+//                = getPips(attrs.get("figclassname"), 
+//                        attrs.get("ownerhref"));
+//            // Sanity check - the returned path item placement straty
+//            // should match the one in the uml.
+//            if (pips.getClass().getName().equals(attrs.get("classname"))) {
+//                // Now we're into processing each specific path item 
+//                // strategy.
+//                // At the moment, we only know about PathItemPlacement
+//                if (pips instanceof PathItemPlacement) {
+//                    PathItemPlacement pip = (PathItemPlacement) pips;
+//                    pip.setDisplacementVector(
+//                            Double.parseDouble(attrs.get("angle")),
+//                            Integer.parseInt(attrs.get("offset")));
+//                }
+//                // Continue (future PathItemPlacementStrategy impl) 
+//                //else if (...) {
+//                //    
+//                //}
+//                    
+//            }
+//            else {
+//                LOG.warn("PGML stored pathitem class name does not "
+//                        + "match the class name on the diagram."
+//                        + "Label position will revert to defaults.");
+//            }
+//        }
+//    }
+//}
+//    
+//super.endElement(uri, localname, qname);
+//}

Modified: trunk/src/argouml-app/src/org/argouml/ui/MultiEditorPane.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/ui/MultiEditorPane.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/ui/MultiEditorPane.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/ui/MultiEditorPane.java	2009-01-14 12:33:14-0800
@@ -45,7 +45,13 @@
 import org.argouml.ui.targetmanager.TargetEvent;
 import org.argouml.ui.targetmanager.TargetListener;
 import org.argouml.ui.targetmanager.TargetManager;
+import org.argouml.uml.diagram.ui.ModeLabelDragFactory;
 import org.argouml.uml.diagram.ui.TabDiagram;
+import org.tigris.gef.base.Globals;
+import org.tigris.gef.base.ModeDragScrollFactory;
+import org.tigris.gef.base.ModeFactory;
+import org.tigris.gef.base.ModePopupFactory;
+import org.tigris.gef.base.ModeSelectFactory;
 
 /**
  * The upper right pane in the ArgoUML user interface.  It may have several
@@ -57,6 +63,18 @@
     extends JPanel
     implements ChangeListener, MouseListener, TargetListener {
 
+    {
+        // I hate this so much even before I start writing it.
+        // Re-initialising a global in a place where no-one will see it just
+        // feels wrong.  Oh well, here goes.
+        ArrayList<ModeFactory> modeFactories = new ArrayList<ModeFactory>();
+        modeFactories.add(new ModeLabelDragFactory());
+        modeFactories.add(new ModeSelectFactory());
+        modeFactories.add(new ModePopupFactory());
+        modeFactories.add(new ModeDragScrollFactory()); 
+        Globals.setDefaultModeFactories(modeFactories);
+    }
+    
     /** logger */
     private static final Logger LOG = Logger.getLogger(MultiEditorPane.class);
         

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/collaboration/ui/FigAssociationRole.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/collaboration/ui/FigAssociationRole.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/collaboration/ui/FigAssociationRole.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/collaboration/ui/FigAssociationRole.java	2009-01-14 12:33:14-0800
@@ -34,8 +34,8 @@
 import org.argouml.uml.diagram.ui.ArgoFigGroup;
 import org.argouml.uml.diagram.ui.FigAssociation;
 import org.argouml.uml.diagram.ui.FigMessage;
+import org.argouml.uml.diagram.ui.PathItemPlacement;
 import org.tigris.gef.base.Layer;
-import org.tigris.gef.base.PathConvPercent;
 import org.tigris.gef.presentation.Fig;
 
 
@@ -64,7 +64,7 @@
     public FigAssociationRole() {
         super();
         messages = new FigMessageGroup();
-        addPathItem(messages, new PathConvPercent(this, 50, 10));
+        addPathItem(messages, new PathItemPlacement(this, messages, 50, 10));
     }
 
     /**
@@ -93,7 +93,7 @@
     public FigAssociationRole(Object owner, DiagramSettings settings) {
         super(owner, settings);
         messages = new FigMessageGroup(owner, settings);
-        addPathItem(messages, new PathConvPercent(this, 50, 10));
+        addPathItem(messages, new PathItemPlacement(this, messages, 50, 10));
     }
     
     /*

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/state/ui/FigTransition.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/state/ui/FigTransition.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/state/ui/FigTransition.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/state/ui/FigTransition.java	2009-01-14 12:33:14-0800
@@ -36,7 +36,7 @@
 import org.argouml.ui.targetmanager.TargetManager;
 import org.argouml.uml.diagram.DiagramSettings;
 import org.argouml.uml.diagram.ui.FigEdgeModelElement;
-import org.argouml.uml.diagram.ui.PathConvPercent2;
+import org.argouml.uml.diagram.ui.PathItemPlacement;
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewActionSequence;
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewCallAction;
 import org.argouml.uml.ui.behavior.common_behavior.ActionNewCreateAction;
@@ -117,7 +117,7 @@
 
     private void initializeTransition() {
         addPathItem(getNameFig(),
-                new PathConvPercent2(this, getNameFig(), 50, 10));
+                new PathItemPlacement(this, getNameFig(), 50, 10));
         getFig().setLineColor(LINE_COLOR);
         setDestArrowHead(endArrow);
         allowRemoveFromDiagram(false);

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigLink.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigLink.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigLink.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/static_structure/ui/FigLink.java	2009-01-14 12:33:14-0800
@@ -27,7 +27,7 @@
 import org.argouml.model.Model;
 import org.argouml.uml.diagram.ui.FigEdgeModelElement;
 import org.argouml.uml.diagram.ui.FigTextGroup;
-import org.argouml.uml.diagram.ui.PathConvPercent2;
+import org.argouml.uml.diagram.ui.PathItemPlacement;
 import org.tigris.gef.presentation.Fig;
 
 /**
@@ -58,7 +58,7 @@
     public FigLink() {
         middleGroup.addFig(getNameFig());
         addPathItem(middleGroup,
-                new PathConvPercent2(this, middleGroup, 50, 25));
+                new PathItemPlacement(this, middleGroup, 50, 25));
         getNameFig().setUnderline(true);
 	getFig().setLineColor(LINE_COLOR);
 	setBetweenNearestPoints(true);

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigDependency.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigDependency.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigDependency.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigDependency.java	2009-01-14 12:33:14-0800
@@ -68,7 +68,7 @@
         middleGroup.addFig(getNameFig());
         middleGroup.addFig(getStereotypeFig());
         addPathItem(middleGroup,
-                new PathConvPercent2(this, middleGroup, 50, 25));
+                new PathItemPlacement(this, middleGroup, 50, 25));
         
         setDestArrowHead(createEndArrow());
         

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEdgeModelElement.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEdgeModelElement.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEdgeModelElement.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigEdgeModelElement.java	2009-01-14 12:33:14-0800
@@ -467,17 +467,7 @@
      * @param g the graphics
      */
     protected void indicateBounds(FigText f, Graphics g) {
-        if (f == null || isReadOnly()) {
-            return;
-        }
-        String text = f.getText();
-        if (text == null || text.length() == 0) {
-            Rectangle rect = f.getBounds();
-            Color c = g.getColor();
-            g.setColor(Globals.getPrefs().handleColorFor(f));
-            g.drawRect(rect.x, rect.y, rect.width, rect.height);
-            g.setColor(c); // TODO: Is this needed?
-        }
+        // No longer necessary, see issue 1048.
     }
     
     /**

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigGeneralization.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigGeneralization.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigGeneralization.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigGeneralization.java	2009-01-14 12:33:14-0800
@@ -74,7 +74,8 @@
 	discriminator.setLineWidth(0);
 	discriminator.setReturnAction(FigText.END_EDITING);
 	discriminator.setTabAction(FigText.END_EDITING);
-	addPathItem(discriminator, new PathConvPercent(this, 40, -10));
+	addPathItem(discriminator, 
+	        new PathItemPlacement(this, discriminator, 50, -10));
 
         endArrow = new ArrowHeadTriangle();
 	endArrow.setFillColor(FILL_COLOR);

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigTextGroup.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigTextGroup.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigTextGroup.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/FigTextGroup.java	2009-01-14 12:33:14-0800
@@ -31,6 +31,7 @@
 
 import org.argouml.uml.diagram.DiagramSettings;
 import org.tigris.gef.presentation.Fig;
+import org.tigris.gef.presentation.FigText;
 
 /**
  * Custom class to group FigTexts in such a way that they don't
@@ -185,7 +186,27 @@
             if (f instanceof MouseListener) {
                 ((MouseListener) f).mouseClicked(me);
             }
+            if (me.isConsumed()) {
+                return;
+            }
+            // If the mouse event hasn't been consumed, it means that the user
+            // double clicked on an area that didn't contain an editable fig.
+            // in this case, scan through the list and start editing the first 
+            // fig with editable text.  This allows us to remove the editable 
+            // box clarifier outline, and just outline the whole FigTextGroup, 
+            // see issue 1048.
+            for (Object o : this.getFigs()) {
+                f = (Fig) o;
+                if (f instanceof MouseListener && f instanceof FigText) {
+                    if ( ((FigText) f).getEditable()) {
+                        ((MouseListener) f).mouseClicked(me);
+                    }
+                }
+            }
         }
+        // TODO: 21/12/2008 dthompson mouseClicked(me) above consumes the 
+        // mouse event internally, so I suspect that this line might not be 
+        // necessary.
         me.consume();
     }
 }

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/PathItemPlacement.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/PathItemPlacement.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/PathItemPlacement.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/PathItemPlacement.java	2009-01-14 12:33:14-0800
@@ -98,6 +98,11 @@
      */
     private Point offset;
     
+    /**
+     * Set true to keep items on same side (top or bottom) of path as
+     * it rotates through vertical.
+     */
+    private final boolean swap = true;
     
     /**
      * Construct a new path to coordinate conversion object which positions at a
@@ -146,7 +151,7 @@
         super(pathFig);
         itemFig = theItemFig;
         setAnchor(pathPercent, pathDelta);
-        setDisplacementVector(displacementAngle, displacementDistance);
+        setDisplacementVector(displacementAngle + 180, displacementDistance);
     }
 
     /**
@@ -172,6 +177,17 @@
         setAnchor(pathPercent, pathDelta);
         setAbsoluteOffset(absoluteOffset);
     }
+    
+    /**
+     * Returns the Fig that this PathItemPlacement places.
+     * To get the Fig of the Edge which owns this fig, use use getPathFig()
+     * @see org.tigris.gef.base.PathConv#getPathFig()
+     * @note Used by PGML.tee.
+     * @return The fig that this path item places.
+     */
+    public Fig getItemFig() {
+        return itemFig;
+    }
 
     /**
      * Compute a position.  This strangely named method computes a
@@ -373,6 +389,22 @@
         offset = newOffset;
         useAngle = false;
     }
+    
+    /**
+     * Attempts to set a new location for the fig being controlled
+     * by this path item.  Takes the given Point which represents an x,y 
+     * position, and calculates the most appropriate angle and displacement
+     * to achieve this new position.  Used when the user drags a label
+     * on the diagram.  
+     * @override
+     * @param newPoint The new target location for the PathItem fig.
+     * @see org.tigris.gef.base.PathConv#setPoint(java.awt.Point)
+     */
+    public void setPoint(Point newPoint) {
+        int vect[] = computeVector(newPoint);
+        setDisplacementAngle(vect[0]);
+        setDisplacementDistance(vect[1]);
+    }
 
 
     /**
@@ -380,21 +412,25 @@
      * This is a convenience method to help callers get coordinates in a form
      * that can be passed back in using {@link #setDisplacementVector(int, int)}
      * 
-     * TODO: Untested.
      * @param point the desired target point
      * @return an array of two integers containing the angle and distance
      */
     public int[] computeVector(Point point) {
         Point anchor = getAnchorPosition();
         int distance = (int) anchor.distance(point);
+        int angl = 0;
         double pathSlope = getSlope();
         double offsetSlope = getSlope(anchor, point);
-        // TODO: This is completely untested.  The angle probably needs to
-        // be adjusted to get it to match what is expected on input.
-        int angle = (int) ((offsetSlope - pathSlope) / Math.PI * 180);
-        int[] result = new int[] {angle, distance};
-        throw new UnsupportedOperationException();
-//        return result;
+
+        if (swap && pathSlope > Math.PI / 2 && pathSlope < Math.PI * 3 / 2) {
+            angl = -(int) ((offsetSlope - pathSlope) / Math.PI * 180);
+        }
+        else {
+            angl = (int) ((offsetSlope - pathSlope) / Math.PI * 180);
+        }
+
+        int[] result = new int[] {angl, distance};
+        return result;
     }
     
     /**
@@ -410,6 +446,19 @@
     }
     
     /**
+     * Set the displacement vector to the given angle and distance.
+     * 
+     * @param vectorAngle angle in degrees relative to the edge at the anchor
+     *            point.
+     * @param vectorDistance distance along vector in drawing coordinate units
+     */
+    public void setDisplacementVector(double vectorAngle, 
+            int vectorDistance) {
+        setDisplacementAngle(vectorAngle);
+        setDisplacementDistance(vectorDistance);
+    }
+    
+    /**
      * @param offsetAngle the new angle for the displacement vector, 
      * specified in degrees relative to the edge at the anchor.
      */
@@ -419,6 +468,15 @@
     }
 
     /**
+     * @param offsetAngle the new angle for the displacement vector, 
+     * specified in degrees relative to the edge at the anchor.
+     */
+    public void setDisplacementAngle(double offsetAngle) {
+        angle = offsetAngle * Math.PI / 180.0;
+        useAngle = true;
+    }
+
+    /**
      * Set distance along displacement vector to place the figure.
      * @param newDistance distance in units of the drawing coordinate system
      */
@@ -526,10 +584,6 @@
     private Point applyOffset(double theta, int theOffset, 
             Point result) {
      
-        // Set true to keep items on same side (top or bottom) of path as
-        // it rotates through vertical.
-        final boolean swap = true;
-        
         // Set the following for some backward compatibility with old algorithm
         final boolean aboveAndRight = false;
 
@@ -555,12 +609,6 @@
         int dx = (int) (theOffset * Math.cos(theta));
         int dy = (int) (theOffset * Math.sin(theta));
         
-        // Invert signs for compatibility with callers notion 
-        // that positive offsets are above
-        // TODO: Do in polar domain?  Skip altogether?
-        dy = -dy;
-        dx = -dx;
-
         // For backward compatibility everything is above and right
         // TODO: Do in polar domain?
         if (aboveAndRight) {
@@ -660,4 +708,37 @@
         double y = m.getY1() + as * (m.getY2() - m.getY1());
         return new Point((int) x, (int) y);
     }
+    
+    /**
+     * Returns the value of the percent field - the position of the anchor
+     * point as a percentage of the edge.
+     * @important Used by PGML.tee.
+     * @return The value of the percent field. 
+     */
+    public int getPercent() {
+        return percent;
+    }
+    
+    /**
+     * Returns the value of the angle field converted to degrees.
+     * The angle of the path item relative to the edge.
+     * @important Used by PGML.tee.
+     * @return The value of the angle field in degrees.
+     */
+    public double getAngle() {
+        return angle * 180 / Math.PI;
+    }
+    
+    /**
+     * Returns the value of the vectorOffset field.
+     * The vectorOffset field is the distance away from the edge, along the 
+     * path vector that the item Fig is placed.
+     * @important Used by PGML.tee.
+     * @return The value of the vectorOffset field.
+     */
+    public int getVectorOffset() {
+        return vectorOffset;
+    }
+    /** End of methods used by PGML.tee */
+    
 }

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/TabDiagram.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/TabDiagram.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/TabDiagram.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/ui/TabDiagram.java	2009-01-14 12:33:14-0800
@@ -313,7 +313,9 @@
      */
     public void modeChange(ModeChangeEvent mce) {
         LOG.debug("TabDiagram got mode change event");
-        if (!Globals.getSticky() && Globals.mode() instanceof ModeSelect) {
+        if (target != null    // Target might not have been initialised yet. 
+                && !Globals.getSticky() 
+                && Globals.mode() instanceof ModeSelect) {
 //            if (_target instanceof UMLDiagram) {
 	    target.deselectAllTools();
 //            }

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtend.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtend.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtend.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigExtend.java	2009-01-14 12:33:14-0800
@@ -36,7 +36,7 @@
 import org.argouml.uml.diagram.ui.ArgoFigText;
 import org.argouml.uml.diagram.ui.FigEdgeModelElement;
 import org.argouml.uml.diagram.ui.FigTextGroup;
-import org.tigris.gef.base.PathConvPercent;
+import org.argouml.uml.diagram.ui.PathItemPlacement;
 import org.tigris.gef.presentation.ArrowHeadGreater;
 import org.tigris.gef.presentation.Fig;
 
@@ -127,7 +127,7 @@
         // relationship, the arrow points to the base use case, but because of
         // the way we draw it, that is still the destination end.
 
-        addPathItem(fg, new PathConvPercent(this, 50, 10));
+        addPathItem(fg, new PathItemPlacement(this, fg, 50, 10));
 
         setDashed(true);
 

Modified: trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigInclude.java
Url: http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigInclude.java?view=diff&pathrev=16602&r1=16601&r2=16602
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigInclude.java	(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/diagram/use_case/ui/FigInclude.java	2009-01-14 12:33:14-0800
@@ -30,7 +30,7 @@
 import org.argouml.uml.diagram.DiagramSettings;
 import org.argouml.uml.diagram.ui.FigEdgeModelElement;
 import org.argouml.uml.diagram.ui.FigSingleLineText;
-import org.tigris.gef.base.PathConvPercent;
+import org.argouml.uml.diagram.ui.PathItemPlacement;
 import org.tigris.gef.presentation.ArrowHeadGreater;
 import org.tigris.gef.presentation.Fig;
 
@@ -83,7 +83,7 @@
         label.setEditable(false);
         label.setText("<<include>>");
         
-        addPathItem(label, new PathConvPercent(this, 50, 10));
+        addPathItem(label, new PathItemPlacement(this, label, 50, 10));
         
         // Make the line dashed

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

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.