Some improvements to the GraphEditor (display overlaying edges, adding edges, edit edge values)

git-svn-id: http://dev.eclipse.org/svnroot/technology/org.eclipse.stem/branches/STEM_1_2_3@2583 92a21009-5b66-0410-b83a-dc787c41c6e9
diff --git a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/ConnectionData.java b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/ConnectionData.java
index dec01fa..dc4f38b 100644
--- a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/ConnectionData.java
+++ b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/ConnectionData.java
@@ -1,23 +1,36 @@
 package org.eclipse.stem.ui.grapheditor;

 

 import org.eclipse.emf.common.util.URI;

+import org.eclipse.stem.core.graph.Edge;

 import org.eclipse.stem.core.graph.EdgeLabel;

 import org.eclipse.stem.definitions.edges.MigrationEdgeLabel;

 import org.eclipse.stem.definitions.labels.CommonBorderRelationshipLabel;

+import org.eclipse.stem.definitions.labels.CommonBorderRelationshipLabelValue;

 import org.eclipse.stem.definitions.labels.RelativePhysicalRelationshipLabel;

+import org.eclipse.stem.definitions.edges.MigrationEdge;

 

 public class ConnectionData

 {

 	

+	Edge edge;

 	URI nodeAURI;

 	URI nodeBURI;

 	URI edgeURI;

 	EdgeLabel edgeLabel;

 	String edgeTitle;

 	String edgeIdentifier;

+	String edgePopulation;

 	

-	ConnectionData(URI nodeAURI, URI nodeBURI, URI edgeURI, EdgeLabel edgeLabel, String edgeTitle, String edgeIdentifier)

+	ConnectionData(Edge edge, URI nodeAURI, URI nodeBURI, URI edgeURI, EdgeLabel edgeLabel, String edgeTitle, String edgeIdentifier, String edgePopulation)

 	{

+		this(edge, nodeAURI, nodeBURI, edgeURI, edgeLabel, edgeTitle, edgeIdentifier );

+		this.edgePopulation = edgePopulation;

+		

+	}

+	

+	ConnectionData(Edge edge, URI nodeAURI, URI nodeBURI, URI edgeURI, EdgeLabel edgeLabel, String edgeTitle, String edgeIdentifier)

+	{

+		this.edge = edge;

 		this.nodeAURI = nodeAURI;

 		this.nodeBURI = nodeBURI;

 		this.edgeURI = edgeURI;

@@ -83,9 +96,37 @@
 			}

 			((MigrationEdgeLabel)this.edgeLabel).getCurrentValue().setMigrationRate(newRate);

 			break;

+		case GraphDefs.COMMON_BORDER_EDGE: 

+			double newBorderLength;

+			try {

+				newBorderLength = Double.parseDouble(value);

+				

+			} catch (NumberFormatException ex){

+				newBorderLength = ((CommonBorderRelationshipLabelValue)this.edgeLabel).getBorderLength();

+			}

+			CommonBorderRelationshipLabel cbrl = (CommonBorderRelationshipLabel) this.edgeLabel;

+			((CommonBorderRelationshipLabelValue)cbrl.getCurrentValue()).setBorderLength(newBorderLength);

+			break;

 		}

 	}

 	

+	void setEdgePopulation(String value)

+	{

+		

+		switch (this.getEdgeLabelType())

+		{

+			case GraphDefs.MIGRATION_EDGE: this.edgePopulation = value; 

+			((MigrationEdge)this.edge).setPopulationIdentifier(value); break;

+		

+		}

+	}

+	

+	String getEdgePopulation()

+	{

+	  return this.edgePopulation;

+			// ..

+	}

+	

 	void setEdgeTitle(String edgeTitle)

 	{

 		this.edgeTitle = edgeTitle;

diff --git a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphCanvas.java b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphCanvas.java
index f1451ce..d583926 100644
--- a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphCanvas.java
+++ b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphCanvas.java
@@ -28,12 +28,15 @@
 import org.eclipse.emf.ecore.EObject;

 import org.eclipse.emf.ecore.util.EcoreUtil;

 import org.eclipse.stem.adapters.file.File;

+import org.eclipse.stem.core.STEMURI;

 import org.eclipse.stem.core.Utility;

+import org.eclipse.stem.core.common.DublinCore;

 import org.eclipse.stem.core.common.Identifiable;

 import org.eclipse.stem.core.graph.Edge;

 import org.eclipse.stem.core.graph.EdgeLabel;

 import org.eclipse.stem.core.graph.Node;

 import org.eclipse.stem.core.graph.NodeLabel;

+import org.eclipse.stem.core.graph.impl.EdgeImpl;

 import org.eclipse.stem.core.model.Model;

 import org.eclipse.stem.definitions.adapters.spatial.SpatialProviderAdapter;

 import org.eclipse.stem.definitions.adapters.spatial.geo.LatLong.Segment;

@@ -41,13 +44,22 @@
 import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProvider;

 import org.eclipse.stem.definitions.adapters.spatial.geo.LatLongProviderAdapterFactory;

 import org.eclipse.stem.definitions.adapters.spatial.geo.PlatformLatLongDataProvider;

+import org.eclipse.stem.definitions.edges.EdgesFactory;

+import org.eclipse.stem.definitions.edges.MigrationEdge;

 import org.eclipse.stem.definitions.edges.MigrationEdgeLabel;

+import org.eclipse.stem.definitions.edges.MigrationEdgeLabelValue;

+import org.eclipse.stem.definitions.edges.impl.EdgesFactoryImpl;

 import org.eclipse.stem.definitions.labels.AreaLabel;

 import org.eclipse.stem.definitions.labels.CommonBorderRelationshipLabel;

+import org.eclipse.stem.definitions.labels.CommonBorderRelationshipLabelValue;

 import org.eclipse.stem.definitions.labels.LabelsFactory;

 import org.eclipse.stem.definitions.labels.PopulationLabel;

+import org.eclipse.stem.definitions.labels.PopulationLabelValue;

+import org.eclipse.stem.definitions.labels.RelativePhysicalRelationship;

 import org.eclipse.stem.definitions.labels.RelativePhysicalRelationshipLabel;

+import org.eclipse.stem.definitions.labels.RelativePhysicalRelationshipLabelValue;

 import org.eclipse.stem.definitions.labels.impl.AreaLabelImpl;

+import org.eclipse.stem.definitions.labels.impl.CommonBorderRelationshipLabelImpl;

 import org.eclipse.stem.definitions.labels.impl.PopulationLabelImpl;

 import org.eclipse.stem.ui.Activator;

 import org.eclipse.stem.ui.grapheditor.handlers.SaveInProjectDialog;

@@ -72,6 +84,7 @@
 import org.eclipse.swt.widgets.Combo;

 import org.eclipse.swt.widgets.Composite;

 import org.eclipse.swt.widgets.Display;

+import org.eclipse.swt.widgets.Group;

 import org.eclipse.swt.widgets.Label;

 import org.eclipse.swt.widgets.Listener;

 import org.eclipse.swt.widgets.Menu;

@@ -118,7 +131,8 @@
 	 					EDGE_TITLE= GraphDefs.EDGE_TITLE,

 	 					EDGE_AURI= GraphDefs.EDGE_AURI,

 	 					EDGE_BURI= GraphDefs.EDGE_BURI,

-	 					EDGE_LABEL_VALUE= GraphDefs.EDGE_LABEL_VALUE;

+	 					EDGE_LABEL_VALUE= GraphDefs.EDGE_LABEL_VALUE,

+						EDGE_POPULATION = GraphDefs.EDGE_POPULATION;

 	

 	//TODO : handle coordinates * R > integer range

 	//Rescale for Data

@@ -137,8 +151,8 @@
 	Map<String,GraphNode> GraphNodes = new HashMap<String, GraphNode>();

 

 	Map<String,GraphConnection> GraphConnections = new HashMap<String, GraphConnection>();

-	

-	

+	//after 2011/10/24 final Map<URI, GraphNode> URI2Graphnodes = new HashMap<URI, GraphNode>(); 

+	Map<URI, Edge> additionalEdges2Graph = new HashMap<URI, Edge>();

 	List<double[]> centers = new ArrayList<double[]>();

 	Map<String,Set<DisplayPolygon>> nodeID2Poly = new HashMap<String, Set<DisplayPolygon>>();

 

@@ -426,14 +440,22 @@
 			String edgeTitle;

 			if (e.getDublinCore().getTitle() != null) edgeTitle = e.getDublinCore().getTitle();

 			else edgeTitle = "";

+			String edgePopulation = null;

 			

+			if (e instanceof MigrationEdge) 

+			{

+				edgePopulation = ((MigrationEdge) e).getPopulationIdentifier();

+			}

 				

 			if ((URI2Graphnodes.get(nodeAURI) != null) && 

 					(URI2Graphnodes.get(nodeBURI) != null))

 			{

 			  GraphConnection gc = new GraphConnection(zestGraph, SWT.NONE, 

 					URI2Graphnodes.get(nodeAURI), URI2Graphnodes.get(nodeBURI));

-			  gc.setData(new ConnectionData(nodeAURI, nodeBURI, edgeURI, edgeLabel, edgeTitle, edgeIdentifier));

+			  if (edgePopulation == null) gc.setData(new ConnectionData(e, nodeAURI, nodeBURI, edgeURI, edgeLabel, edgeTitle, edgeIdentifier));

+			  else gc.setData(new ConnectionData(e, nodeAURI, nodeBURI, edgeURI, edgeLabel, edgeTitle, edgeIdentifier, edgePopulation));

+			  setEdgeColor(gc);

+			  preventOverlay(zestGraph, gc);

 			  GraphConnections.put(edgeIdentifier, gc);

 			}

 		

@@ -846,7 +868,7 @@
 			NodeLabel copyGraphNodeLabel = stemLabels.get(uri);

 			if ((nodeLabel != null) && (copyGraphNodeLabel != null)) 

 				if (!copyGraphNodeLabel.toString().equals(nodeLabel.toString()))					

-				//TODO if (copyGraphNodeLabel != nodeLabel) 

+				// if (copyGraphNodeLabel != nodeLabel) 

 				{

 					

 					//System.err.println("Change Label with URI " + uri + " from "

@@ -854,10 +876,22 @@
 										

 					if (stemLabels.get(uri) instanceof PopulationLabel) 

 					{	

+						//Pop Identifier / Name

 						((PopulationLabel)stemLabels.get(uri)).

 							setPopulationIdentifier(((PopulationLabel)nodeLabel).getPopulationIdentifier());

 						((PopulationLabel)stemLabels.get(uri)).

-						setName(((PopulationLabel)nodeLabel).getName());

+							setName(((PopulationLabel)nodeLabel).getName());

+						

+						//Pop size

+						PopulationLabelValue plv_nodeLabel = ((PopulationLabel)nodeLabel).getCurrentPopulationValue();

+						double populationCount = plv_nodeLabel.getCount();

+						PopulationLabelValue plv = ((PopulationLabel)stemLabels.get(uri)).getCurrentPopulationValue();

+						plv.setCount(populationCount);

+						

+						//Pop Area

+						((PopulationLabel)stemLabels.get(uri)).

+							setPopulatedArea(((PopulationLabel)nodeLabel).getPopulatedArea());

+						

 						

 					}	

 					if (stemLabels.get(uri) instanceof AreaLabel)

@@ -885,6 +919,7 @@
 		if (gc != null) 

 		{

 			ConnectionData edgeData = (ConnectionData) gc.getData();

+			 

 			//Title

 			e.getDublinCore().setTitle(edgeData.getEdgeTitle());	

 			

@@ -898,12 +933,28 @@
 												

 			}

 			

+			if (e.getLabel() instanceof CommonBorderRelationshipLabel)

+			{

+				CommonBorderRelationshipLabel cbrl1 = (CommonBorderRelationshipLabel) edgeData.getEdgeLabel();			

+				double borderLength = ((CommonBorderRelationshipLabelValue)cbrl1.getCurrentValue()).getBorderLength();

+				

+				CommonBorderRelationshipLabel cbrl2 = (CommonBorderRelationshipLabel) e.getLabel();			

+				((CommonBorderRelationshipLabelValue)cbrl2.getCurrentValue()).setBorderLength(borderLength);

+			}

+			

+			

+			if (e instanceof MigrationEdge)

+			{

+				((MigrationEdge) e).setPopulationIdentifier(edgeData.getEdgePopulation());

+			}

+			

 		}			

 	}

 	

 	

-	Map<Node, NodeLabel> add2GraphMap = new HashMap<Node,NodeLabel>();

-	//NODES

+	

+	//NODES (+added labels, +added edges)

+	Map<Node, NodeLabel> add2GraphMap = new HashMap<Node,NodeLabel>();	

 	EMap<URI, Node> stemNodes = graphcopy.getNodes();

 

 	Map<String,Set<GmlPolygon>> polygonMap = new HashMap<String,Set<GmlPolygon>>();	

@@ -960,11 +1011,9 @@
 		for (Map.Entry<Node,NodeLabel> URINodeEntry : add2GraphMap.entrySet()) 

 		{

 

-

-		

 			NodeLabel nl = URINodeEntry.getValue();

 			Node node = URINodeEntry.getKey();

-			graph.getNode(node.getURI()).getLabels().add(nl);

+			if (nl != null) graph.getNode(node.getURI()).getLabels().add(nl);

 			

 		}

 		

@@ -994,6 +1043,37 @@
 				n.getDublinCore().setSpatial(nodeSpatialString);						

 			}

 		}

+		

+		

+		//add additional edges here 

+		//(into the file that contains the nodes, because maybe there is no "edges" file, there must be a 

+		//nodes file because the edge was drawn between nodes)

+		for (Map.Entry<URI,Edge> URI2EdgeEntry : additionalEdges2Graph.entrySet()) 

+		{

+			URI edgeURI = URI2EdgeEntry.getKey();

+			// if saved as canonical graph, the source of the graph will be "stemGraph" where it is stored already

+			if (stemEdges.contains(edgeURI)) 

+			{ 

+				//nothing to do

+			}

+			else

+			{

+				// if the additional edge is saved in the graph files, it is not there yet and will be added here						

+				// but only if the origin node is contained in this graph and the current node in the loop, 

+				// because it could be that several files contain

+				// nodes, and edges (or edge references) would be added to the file then

+				Edge edge = URI2EdgeEntry.getValue();

+				//both?!

+				

+				//System.out.println("node URI: " + n.getURI() + "\t"+ "edge nodeA URI: " + edge.getA().getURI() + " or " + edge.getNodeAURI());

+				if (n.getURI() == edge.getNodeAURI())

+				{

+					graphcopy.putEdge(edge);

+					graph.putEdge(edge);

+				}

+										

+			}

+		}

 	}//node loop

 

 	

@@ -1119,7 +1199,7 @@
 				catch (Exception ex) { Activator.logError(ex.getMessage(), ex); }

 				

 				

-				//display(graphList, null, project, null); //TODO check to give model

+				//display(graphList, null, project, null); // check to give model

 				Activator.getDefault().getWorkbench().getDisplay().getActiveShell().dispose();

 				//clean(graphList, project);

 				

@@ -1157,7 +1237,7 @@
 	

 	

 	

-	/* TODO Reset Button

+	/*  Reset Button

 	ToolItem resetButton = new ToolItem(toolBar, SWT.PUSH);

 	resetButton.setText("Reset");

 	resetButton.addSelectionListener(new SelectionListener() {

@@ -1200,11 +1280,13 @@
 	

 	

 	final Composite dataComposite = new Composite(parent, SWT.CENTER);

-						

-	final Composite propertiesComposite_nodes = new Composite(dataComposite, SWT.CENTER);

-	final Composite propertiesComposite_edges = new Composite(dataComposite, SWT.CENTER);	

-	final Composite infoComposite = new Composite(dataComposite, SWT.CENTER);

 	

+	final Group propertiesComposite_nodes = new Group(dataComposite, SWT.CENTER);

+	final Group propertiesComposite_edges = new Group(dataComposite, SWT.CENTER);	

+	final Group infoComposite = new Group(dataComposite, SWT.CENTER);

+	propertiesComposite_nodes.setText("Node");

+	propertiesComposite_edges.setText("Edge");

+	infoComposite.setText("Display Information");

 	

 	

 	final RowLayout dataCompositeLayout = new RowLayout(SWT.VERTICAL);

@@ -1243,13 +1325,14 @@
 	final Label edgeLabelType_edit;

 	final Label edgeLabelValue;

 	final Text edgeLabelValue_edit;

-  

+	final Label edgePop;

+	final Text edgePop_edit;

 		

 	nodeTitle = new Label(propertiesComposite_nodes, SWT.NONE);

 	nodeTitle.setLayoutData(new RowData(30, SWT.DEFAULT));

 	nodeTitle.setText("Title: ");

 	nodeTitle_edit = new Text(propertiesComposite_nodes, SWT.NONE);

-	nodeTitle_edit.setLayoutData(new RowData(250, SWT.DEFAULT));

+	nodeTitle_edit.setLayoutData(new RowData(241, SWT.DEFAULT));

 	nodeTitle_edit.addModifyListener(new TextModifyListener(zestGraph, NODE_TITLE));

 	

 	

@@ -1263,31 +1346,34 @@
 	nodeLabelType.setLayoutData(new RowData(50, SWT.DEFAULT));

 	nodeLabelType.setText("LabelType: ");

 	nodeLabelType_edit = new Combo(propertiesComposite_nodes, SWT.READ_ONLY);

-	nodeLabelType_edit.setLayoutData(new RowData(95, SWT.DEFAULT));

+	nodeLabelType_edit.setLayoutData(new RowData(80, SWT.DEFAULT));

 

 	

 	nodeLabelValue = new Label(propertiesComposite_nodes, SWT.NONE);

 	nodeLabelValue.setLayoutData(new RowData(130, SWT.DEFAULT));

 	nodeLabelValue.setText("Value: ");

 	nodeLabelValue_edit = new Combo(propertiesComposite_nodes, SWT.NONE);

-	nodeLabelValue_edit.setLayoutData(new RowData(80, SWT.DEFAULT));

+	nodeLabelValue_edit.setLayoutData(new RowData(70, SWT.DEFAULT));

 	nodeLabelType_edit.addSelectionListener(new ComboListenerType(zestGraph, nodeLabelValue_edit, nodeLabelValue));

 	

 	nodeLabelValue_edit.addKeyListener(new ComboListenerValue(zestGraph, nodeLabelType_edit));

 	nodeLabelValue_edit.addSelectionListener(new ComboSelectionListenerValue(zestGraph, nodeLabelType_edit, nodeLabelValue));

 	

+	//fill = new Label(propertiesComposite_nodes, SWT.NONE);

+	//fill.setLayoutData(new RowData(22, SWT.DEFAULT));

+	

     nodeXY = new Label(propertiesComposite_nodes, SWT.NONE);

 	nodeXY.setText("XY: ");

 	nodeXY.setLayoutData(new RowData(20, SWT.DEFAULT));

 	nodeXY_edit = new Label(propertiesComposite_nodes, SWT.NONE);

-	nodeXY_edit.setLayoutData(new RowData(70, SWT.DEFAULT));

+	nodeXY_edit.setLayoutData(new RowData(175, SWT.DEFAULT));

 	

 	

 	edgeTitle = new Label(propertiesComposite_edges, SWT.NONE);

     edgeTitle.setLayoutData(new RowData(30, SWT.DEFAULT));

     edgeTitle.setText("Title: ");

     edgeTitle_edit = new Text(propertiesComposite_edges, SWT.NONE);

-    edgeTitle_edit.setLayoutData(new RowData(400, SWT.DEFAULT));

+    edgeTitle_edit.setLayoutData(new RowData(320, SWT.DEFAULT));

     edgeTitle_edit.addModifyListener(new TextModifyListener(zestGraph, EDGE_TITLE));

 	

     edgeLabelType = new Label(propertiesComposite_edges, SWT.NONE);

@@ -1300,25 +1386,33 @@
     edgeLabelValue.setLayoutData(new RowData(30, SWT.DEFAULT));

     edgeLabelValue.setText("Value: ");

     edgeLabelValue_edit = new Text(propertiesComposite_edges, SWT.NONE);

-    edgeLabelValue_edit.setLayoutData(new RowData(30, SWT.DEFAULT));

+    edgeLabelValue_edit.setLayoutData(new RowData(40, SWT.DEFAULT));

     edgeLabelValue_edit.addModifyListener(new TextModifyListener(zestGraph, EDGE_LABEL_VALUE));

 	

+    edgePop = new Label(propertiesComposite_edges, SWT.NONE);

+    edgePop.setLayoutData(new RowData(55, SWT.DEFAULT));

+    edgePop.setText("Population: ");

+    edgePop_edit = new Text(propertiesComposite_edges, SWT.NONE);

+    edgePop_edit.setLayoutData(new RowData(40, SWT.DEFAULT));

+    edgePop_edit.addModifyListener(new TextModifyListener(zestGraph, EDGE_POPULATION));

+    

 	nodeAURI = new Label(propertiesComposite_edges, SWT.NONE);

     nodeAURI.setLayoutData(new RowData(40, SWT.DEFAULT));

     nodeAURI.setText("NodeA: ");

     nodeAURI_edit = new Label(propertiesComposite_edges, SWT.NONE);

-    nodeAURI_edit.setLayoutData(new RowData(150, SWT.DEFAULT));

+    nodeAURI_edit.setLayoutData(new RowData(145, SWT.DEFAULT));

     

     nodeBURI = new Label(propertiesComposite_edges, SWT.NONE);

     nodeBURI.setLayoutData(new RowData(40, SWT.DEFAULT));

     nodeBURI.setText("NodeB: ");

     nodeBURI_edit = new Label(propertiesComposite_edges, SWT.NONE);

-    nodeBURI_edit.setLayoutData(new RowData(150, SWT.DEFAULT));

+    nodeBURI_edit.setLayoutData(new RowData(145, SWT.DEFAULT));

     

     nodeAURI_edit.setVisible(false);

 	nodeBURI_edit.setVisible(false);

 	edgeLabelType_edit.setVisible(false);

 	edgeLabelValue_edit.setVisible(false);

+	edgePop_edit.setVisible(false);

 	edgeTitle_edit.setVisible(false);

 	nodeURI_edit.setVisible(false);

 	nodeTitle_edit.setVisible(false);

@@ -1523,6 +1617,8 @@
 					edgeLabelType_edit.setVisible(false);

 					edgeLabelValue_edit.setVisible(false);

 					edgeTitle_edit.setVisible(false);

+					edgePop.setVisible(false);

+					edgePop_edit.setVisible(false);

 					GraphNode selectedNode = (GraphNode) selectedItem;

 					NodeData nodeData = (NodeData) selectedNode.getData();					

 					if (selectedNode.getData() != null)

@@ -1587,6 +1683,8 @@
 					nodeLabelType_edit.setVisible(false);

 					nodeLabelValue_edit.setVisible(false);

 					nodeXY_edit.setVisible(false);

+					edgePop.setVisible(false);

+					edgePop_edit.setVisible(false);

 					GraphConnection selectedEdge = (GraphConnection) selectedItem;

 					if (selectedEdge.getData() != null)

 					{

@@ -1600,6 +1698,11 @@
 						case MIGRATION_EDGE:	MigrationEdgeLabel migrationEdgeLabel = (MigrationEdgeLabel)((ConnectionData)selectedEdge.getData()).getEdgeLabel();

 												edgeLabelType_edit.setText("Migration Edge");

 												edgeLabelValue_edit.setText(migrationEdgeLabel.getCurrentValue().getMigrationRate()+"");

+												String pop = ((ConnectionData)selectedEdge.getData()).getEdgePopulation();

+												if (pop == null) pop = "";

+												edgePop_edit.setText(pop );

+												edgePop.setVisible(true);

+												edgePop_edit.setVisible(true);

 												break;

 						case CONTAINMENT_EDGE:  RelativePhysicalRelationshipLabel rprl = (RelativePhysicalRelationshipLabel) ((ConnectionData)selectedEdge.getData()).getEdgeLabel();

 												edgeLabelType_edit.setText("Containment Edge");

@@ -1607,8 +1710,8 @@
 												edgeLabelValue_edit.setVisible(false);											

 												break;

 						case COMMON_BORDER_EDGE:CommonBorderRelationshipLabel cbrl = (CommonBorderRelationshipLabel) ((ConnectionData)selectedEdge.getData()).getEdgeLabel();

-												edgeLabelType_edit.setText("Common Border Edge");

-												edgeLabelValue_edit.setVisible(false);

+												edgeLabelType_edit.setText("Common Border Edge");												

+												edgeLabelValue_edit.setText(((CommonBorderRelationshipLabelValue)cbrl.getCurrentValue()).getBorderLength()+"");

 												break;

 						case UNDEFINED:			edgeLabelType_edit.setText("");

 												edgeLabelValue_edit.setText("");

@@ -1630,6 +1733,8 @@
 				nodeLabelValue.setText("Value: ");

 				nodeLabelValue_edit.setVisible(false);

 				nodeXY_edit.setVisible(false);

+				edgePop.setVisible(false);

+				edgePop_edit.setVisible(false);

 				

 				

 			}

@@ -1683,17 +1788,18 @@
     addAreaLabel.setText("Add Area Label");

     addPopulationLabel.setText("Add Population Label");

 	

-    /*

-    //TODO add edges to graph

-	MenuItem addEdge = new MenuItem(menu, SWT.CASCADE);

-	Menu edgeMenu = new Menu(zestGraph.getShell(), SWT.DROP_DOWN);

-	MenuItem addMigrationEdge = new MenuItem(edgeMenu, SWT.CASCADE);

-	MenuItem addContainmentEdge = new MenuItem(edgeMenu, SWT.CASCADE);

+    

+    //add edges to graph

+	final MenuItem addEdge = new MenuItem(menu, SWT.CASCADE);

+	final Menu edgeMenu = new Menu(zestGraph.getShell(), SWT.DROP_DOWN);

+	final MenuItem addMigrationEdge = new MenuItem(edgeMenu, SWT.CASCADE);

+	final MenuItem addContainmentEdge = new MenuItem(edgeMenu, SWT.CASCADE);

+	final MenuItem addCommonBorderEdge = new MenuItem(edgeMenu, SWT.CASCADE);

 	addEdge.setText("Add Edge");

 	addEdge.setMenu(edgeMenu);

 	addMigrationEdge.setText("Add Migration Edge");

     addContainmentEdge.setText("Add Containment Edge");

-	*/

+	addCommonBorderEdge.setText("Add Common Border Edge");

     

 menu.addMenuListener(new MenuListener() {

     	

@@ -1711,18 +1817,28 @@
 				{

 					//addAreaLabel.setEnabled(true);

 					addLabel.setEnabled(true);

+					addEdge.setEnabled(false);

 				}

 				else 

 				{

 					addLabel.setEnabled(false);

 					//addAreaLabel.setEnabled(false);

+					

 				}

 			}

-			else 

+			else if (selectedItems.size() == 2) 

 			{

 				addLabel.setEnabled(false);

 				//addAreaLabel.setEnabled(false);

+				addEdge.setEnabled(true);

 			}   	

+			else

+			{ 

+				addLabel.setEnabled(false);			

+				addEdge.setEnabled(false);

+			}

+			

+			

 		}

     });

     

@@ -1807,9 +1923,158 @@
 		}

 	});

          

-    zestGraph.setMenu(menu);

+    addCommonBorderEdge.addSelectionListener(new SelectionListener() {

+		public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {

+			List<GraphItem> selectedItems = zestGraph.getSelection();

+			if (selectedItems.size() == 2) 

+			{ 

+				if (selectedItems.get(0) instanceof GraphNode && selectedItems.get(1) instanceof GraphNode)

+				{			

+					

+					GraphNode selectedNodeA = (GraphNode) selectedItems.get(0);

+					GraphNode selectedNodeB = (GraphNode) selectedItems.get(1);

+					//ConnectionData connectionDataA = (ConnectionData) selectedNodeA.getData();

+					//ConnectionData connectionDataB = (ConnectionData) selectedNodeB.getData();

 

+					NodeData nodeDataA = (NodeData) selectedNodeA.getData();

+					NodeData nodeDataB = (NodeData) selectedNodeB.getData();

+					

+					

+					Edge CBR_Edge = createCommonBorderEdge(nodeDataA, nodeDataB);

+					edgeLabelType_edit.setText("Common Border Edge");

+					edgeLabelValue_edit.setText("0");

+					

+					// manage Zest Stuff

+					EdgeLabel edgeLabel =	CBR_Edge.getLabel();

+					String edgeIdentifier = CBR_Edge.getDublinCore().getIdentifier();

+					String edgeTitle = "";

+					CBR_Edge.getDublinCore().setTitle(edgeTitle);

+					

+					GraphConnection gc = new GraphConnection(zestGraph, SWT.NONE, selectedNodeA, selectedNodeB);

+					ConnectionData connectionData = new ConnectionData(CBR_Edge, nodeDataA.getNodeURI(), 

+							  nodeDataB.getNodeURI(), 

+							  CBR_Edge.getURI(), 

+							  edgeLabel, 

+							  edgeTitle, 

+							  edgeIdentifier);

+					gc.setData(connectionData);

+					setEdgeColor(gc);

+					preventOverlay(zestGraph, gc);

+					GraphConnections.put(edgeIdentifier, gc);		

+					stemGraph.getEdges().put(CBR_Edge.getURI(), CBR_Edge);

+					additionalEdges2Graph.put(CBR_Edge.getURI(), CBR_Edge);

+

+				}

+			}

+

+		}

+		public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {

+		}

+	});

     

+    addMigrationEdge.addSelectionListener(new SelectionListener() {

+		public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {

+			List<GraphItem> selectedItems = zestGraph.getSelection();

+			if (selectedItems.size() == 2) 

+			{ 

+				if (selectedItems.get(0) instanceof GraphNode && selectedItems.get(1) instanceof GraphNode)

+				{			

+					

+					GraphNode selectedNodeA = (GraphNode) selectedItems.get(0);

+					GraphNode selectedNodeB = (GraphNode) selectedItems.get(1);

+					//ConnectionData connectionDataA = (ConnectionData) selectedNodeA.getData();

+					//ConnectionData connectionDataB = (ConnectionData) selectedNodeB.getData();

+

+					NodeData nodeDataA = (NodeData) selectedNodeA.getData();

+					NodeData nodeDataB = (NodeData) selectedNodeB.getData();

+					

+					

+					Edge migrationEdge = createMigrationEdge(nodeDataA, nodeDataB, "Population Name", 0.0);

+					URI duplicateURI = checkDuplicateURI(migrationEdge, stemGraph.getEdges());

+					if (duplicateURI != null) migrationEdge.setURI(duplicateURI);

+					//edgeLabelType_edit.setText("Migration Edge");

+					//edgeLabelValue_edit.setText("0");

+					

+					

+					// manage Zest Stuff

+					EdgeLabel edgeLabel =	migrationEdge.getLabel();

+					String edgeIdentifier = migrationEdge.getURI().toString(); //JW 20111107 migrationEdge.getDublinCore().getIdentifier();

+					String edgeTitle = "";

+					migrationEdge.getDublinCore().setTitle(edgeTitle);

+					

+					GraphConnection gc = new GraphConnection(zestGraph, SWT.NONE, selectedNodeA, selectedNodeB);

+					ConnectionData connectionData = new ConnectionData(migrationEdge, nodeDataA.getNodeURI(), 

+							  nodeDataB.getNodeURI(), 

+							  migrationEdge.getURI(), 

+							  edgeLabel, 

+							  edgeTitle, 

+							  edgeIdentifier,

+							  "Population Name");

+					gc.setData(connectionData);

+					setEdgeColor(gc);

+					preventOverlay(zestGraph, gc);

+					GraphConnections.put(migrationEdge.getURI().toString(), gc);		

+					stemGraph.getEdges().put(migrationEdge.getURI(), migrationEdge);

+					additionalEdges2Graph.put(migrationEdge.getURI(), migrationEdge);

+

+				}

+			}

+

+		}

+		public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {

+		}

+	});

+    

+    addContainmentEdge.addSelectionListener(new SelectionListener() {

+		public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {

+			List<GraphItem> selectedItems = zestGraph.getSelection();

+			if (selectedItems.size() == 2) 

+			{ 

+				if (selectedItems.get(0) instanceof GraphNode && selectedItems.get(1) instanceof GraphNode)

+				{			

+					

+					GraphNode selectedNodeA = (GraphNode) selectedItems.get(0);

+					GraphNode selectedNodeB = (GraphNode) selectedItems.get(1);

+					//ConnectionData connectionDataA = (ConnectionData) selectedNodeA.getData();

+					//ConnectionData connectionDataB = (ConnectionData) selectedNodeB.getData();

+

+					NodeData nodeDataA = (NodeData) selectedNodeA.getData();

+					NodeData nodeDataB = (NodeData) selectedNodeB.getData();

+					

+					

+					Edge containmentEdge = createContainmentEdge(nodeDataA, nodeDataB);

+					edgeTitle_edit.setText(containmentEdge.getDublinCore().getTitle());

+					edgeLabelType_edit.setText("Containment Edge");

+

+					

+					// manage Zest Stuff

+					EdgeLabel edgeLabel =	containmentEdge.getLabel();

+					String edgeIdentifier = containmentEdge.getDublinCore().getIdentifier();

+					String edgeTitle = containmentEdge.getDublinCore().getTitle();

+					

+					GraphConnection gc = new GraphConnection(zestGraph, SWT.NONE, selectedNodeA, selectedNodeB);

+					ConnectionData connectionData = new ConnectionData(containmentEdge, nodeDataA.getNodeURI(), 

+							  nodeDataB.getNodeURI(), 

+							  containmentEdge.getURI(), 

+							  edgeLabel, 

+							  edgeTitle, 

+							  edgeIdentifier);

+					gc.setData(connectionData);

+					setEdgeColor(gc);

+					preventOverlay(zestGraph, gc);

+					GraphConnections.put(edgeIdentifier, gc);		

+					stemGraph.getEdges().put(containmentEdge.getURI(), containmentEdge);

+					additionalEdges2Graph.put(containmentEdge.getURI(), containmentEdge);

+

+				}

+			}

+

+		}

+		public void widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent e) {

+		}

+	});

+    

+    zestGraph.setMenu(menu); 

     return dataComposite; 	    	    		

 

 } // createTopComposite

@@ -1831,7 +2096,37 @@
 

 

 

+/* Design issues */

 

+private void setEdgeColor(GraphConnection gc)

+{

+	ConnectionData cd = (ConnectionData)gc.getData();

+	switch (cd.getEdgeLabelType())

+	{

+		case MIGRATION_EDGE: gc.setLineStyle(SWT.LINE_SOLID); break;

+		case COMMON_BORDER_EDGE: gc.setLineStyle(SWT.LINE_DOT); break;

+		case CONTAINMENT_EDGE: gc.setLineStyle(SWT.LINE_DASH); break;

+		case UNDEFINED: gc.setLineStyle(SWT.LINE_SOLID); break;

+		default: gc.setLineStyle(SWT.LINE_SOLID); break;

+	}

+}

+private void preventOverlay(Graph zestGraph, GraphConnection gc_new)

+{

+	int cnt=0;

+	List<GraphConnection> connectionList = zestGraph.getConnections();

+	for (GraphConnection gc : connectionList)

+	{

+	  	if ( (gc.getSource() == gc_new.getSource()) && (gc.getDestination() == gc_new.getDestination())

+	  			||

+	  		 (gc.getSource() == gc_new.getDestination()) && (gc.getDestination() == gc_new.getSource()))

+	  	{

+	  		cnt++;

+	  	}

+	}

+	//found at least one time (itself)

+	cnt--;

+	gc_new.setCurveDepth((int)(cnt*10*Math.pow(-1,cnt)));

+}

 

 

 

@@ -2007,6 +2302,188 @@
 	} catch(Exception e) { Activator.logError(e.getMessage(), e); }

 }

 

+private static URI createEdgeLabelURI(URI uriA, URI uriB) {

+	String sA = uriA.lastSegment();

+	String sB = uriB.lastSegment();

+	

+	// MigrationEdgeLabelItemProvider

+	// uses _ as a special character to separate the two nodes

+	// so we need to replace it.

+	sA=sA.replace('_','.');

+	sB=sB.replace('_','.');

+	String uriString = sA+"_"+sB;

+	

+	//System.out.println("createEdgeLabelURI() : FINALLY, uri = "+uriString);

+	

+    URI uri = STEMURI.createURI(uriString);

+	return uri;

+} // createEdgeLabelURI

+

+private String createEdgeTitle(Node nodeA, Node nodeB) {

+	String nA = nodeA.getDublinCore().getTitle();

+	String nB = nodeB.getDublinCore().getTitle();

+	final StringBuilder sb = new StringBuilder("Edge[(");

+	sb.append(nA);

+	sb.append(")<-->(");

+	sb.append(nB);

+	sb.append(")]");

+	return sb.toString();

+}

+

+

+private Edge createCommonBorderEdge(NodeData nodeDataA, NodeData nodeDataB )

+{

+	// Common Border Edge Stuff

+	Edge CBR_Edge = CommonBorderRelationshipLabelImpl.createCommonBorderRelationship(nodeDataA.getNode(), nodeDataB.getNode(), 0);

+	

+	// the autogenerated edge uri is not correct. Need to replace it

+	URI edgeURI = CBR_Edge.getURI();

+	String sEdge = edgeURI.toString();

+	int last = sEdge.lastIndexOf("/");

+	String sEdge1 = sEdge.substring(0,last);

+	String sEdge2 = nodeDataA.getNodeURI().lastSegment()+ "_" + nodeDataB.getNodeURI().lastSegment();

+	sEdge = sEdge1+"/relationship/commonborder/"+sEdge2;

+	URI newURI = URI.createURI(sEdge);

+	CBR_Edge.setURI(newURI);

+	CBR_Edge.getDublinCore().setIdentifier(newURI.toString());

+	// now we need to set the uri for the label

+	CommonBorderRelationshipLabel label = (CommonBorderRelationshipLabel)CBR_Edge.getLabel();

+	label.setURI(createEdgeLabelURI(nodeDataA.getNodeURI(), nodeDataB.getNodeURI()));

+	CBR_Edge.getLabel().setURIOfIdentifiableToBeLabeled(label.getURI());

+	

+	final DublinCore dc = CBR_Edge.getDublinCore();

+	dc.setTitle(createEdgeTitle(nodeDataA.getNode(), nodeDataB.getNode()));

+	

+	final CommonBorderRelationshipLabelValue labelValue = (CommonBorderRelationshipLabelValue) CBR_Edge.getLabel().getCurrentValue();

+	labelValue.setBorderLength(0);

+	

+    return CBR_Edge;

+	// End Common Border Edge Stuff

+}

+

+private Edge createMigrationEdge(NodeData nodeDataA, NodeData nodeDataB, String populationIdentifier, double migrationRateAB)

+{

+		URI sourceURI = nodeDataA.getNodeURI();

+		URI targetURI = nodeDataB.getNodeURI();

+		

+		EdgesFactory ef = EdgesFactoryImpl.init();

+		MigrationEdge mEdge = ef.createMigrationEdge();

+		//MigrationEdge mEdge2 = ef.createMigrationEdge();

+		

+		// The URI of the edge 1 

+		URI edgeURI = mEdge.getURI();

+		// the autogenerated edge uri is not correct. Need to replace it

+		String s1 = edgeURI.toString();

+		int last = s1.lastIndexOf("/");

+		String sEdge1 = s1.substring(0,last);

+		String sEdge2 = sourceURI.lastSegment()+ "_" + targetURI.lastSegment();

+		s1 = sEdge1+"/relationship/migration/"+sEdge2;

+		URI newURI = URI.createURI(s1);

+		mEdge.setURI(newURI);

+		

+	

+		

+		// ADD The URIs of the nodes connected by these two directed edges

+		// A => B

+		mEdge.setNodeAURI(sourceURI);

+		mEdge.setNodeBURI(targetURI);

+		

+		// now we need to set the uri for the label

+		MigrationEdgeLabel label = mEdge.getLabel();			

+		label.setURI(createEdgeLabelURI(sourceURI, targetURI));

+		label.setURIOfIdentifiableToBeLabeled(label.getURI());

+		

+		MigrationEdgeLabelValue melv = label.getCurrentValue();

+		melv.setMigrationRate(migrationRateAB);

+

+		final DublinCore dc1 = mEdge.getDublinCore();

+		String sA = sourceURI.lastSegment();

+		String sB = targetURI.lastSegment();

+		final StringBuilder sb = new StringBuilder("MigrationEdge[(");

+		sb.append(sA);

+		sb.append(")<-->(");

+		sb.append(sB);

+		sb.append(")]");

+		dc1.setTitle(sb.toString());

+					

+		mEdge.setPopulationIdentifier(populationIdentifier);

+		

+		return mEdge;

+}

+

+private Edge createContainmentEdge(NodeData nodeDataA, NodeData nodeDataB)

+{

+	final Edge cEdge = EdgeImpl.createEdge(nodeDataA.getNodeURI(), nodeDataB.getNodeURI());

+	

+	final RelativePhysicalRelationshipLabel containLabel = LabelsFactory.eINSTANCE

+			.createRelativePhysicalRelationshipLabel();

+

+	containLabel.setURIOfIdentifiableToBeLabeled(cEdge.getURI());

+	containLabel.getCurrentRelationship().setRelationship(

+			RelativePhysicalRelationship.CONTAINS_LITERAL);

+

+	final RelativePhysicalRelationshipLabelValue currentValue = LabelsFactory.eINSTANCE

+			.createRelativePhysicalRelationshipLabelValue();

+	currentValue.setAdjacent(false);

+	currentValue.setRelationship(RelativePhysicalRelationship.CONTAINS_LITERAL);

+	containLabel.setCurrentValue(currentValue);

+	

+	cEdge.setDirected(true);

+	

+	String nodeAURIfull = nodeDataA.getNodeURI().toString();

+	int lastA = nodeAURIfull.lastIndexOf("/")+1;

+	String nodeAURI = nodeAURIfull.substring(lastA,nodeAURIfull.length());

+	

+	String nodeBURIfull = nodeDataB.getNodeURI().toString();

+	int lastB = nodeBURIfull.lastIndexOf("/")+1;

+	String nodeBURI = nodeBURIfull.substring(lastB,nodeBURIfull.length());

+	

+	// create the uri;

+	final StringBuilder sb = new StringBuilder(

+			"edge/relationship/relativephysical/"); //$NON-NLS-1$

+	sb.append(nodeAURI);

+	sb.append("_"); //$NON-NLS-1$

+	sb.append(nodeBURI);

+	sb.append("/"); //$NON-NLS-1$

+	sb.append(RelativePhysicalRelationship.CONTAINS_LITERAL.toString()

+			.toLowerCase());

+	

+

+	cEdge.setURI(STEMURI.createURI(sb.toString()));

+	containLabel.setURI(STEMURI.createURI(sb.toString()));

+	cEdge.setLabel(containLabel);

+	containLabel.setURIOfIdentifiableToBeLabeled(cEdge.getURI());

+	

+	cEdge.getDublinCore().setTitle("Containment: " + nodeDataA.getNodeURI().lastSegment() + "<-" + nodeDataB.getNodeURI().lastSegment());

+	

+	return cEdge;

+}

+

+URI checkDuplicateURI(Edge migrationEdge, EMap <URI, Edge> edgeList )

+{   

+	String newURI = migrationEdge.getURI().toString();

+	

+	int cnt = 1;

+	if (edgeList.containsKey(URI.createURI(newURI)))

+	{

+		//String suffix = newURI.substring(newURI.length()-5, newURI.length()) +  cnt;

+		String suffix = "_dup" + cnt;

+		while (edgeList.containsKey(URI.createURI(newURI+suffix)))

+		{

+			cnt++;

+			suffix = "_dup" + cnt;

+		}

+		String suffix2 = "_dup"+String.valueOf(cnt);

+		newURI = newURI.concat(suffix2); //newURI.substring(0,newURI.length()-1) + Double.parseDouble(newURI.substring(newURI.length()-1, newURI.length()))+1;

+		

+	}	

+	else newURI = newURI.concat("_dup1");

+		

+	migrationEdge.setURI(URI.createURI(newURI));

+	

+ return URI.createURI(newURI);	

+}

+

 

 private void clean(List<org.eclipse.stem.core.graph.Graph> graphList, IProject project)

 {

diff --git a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphDefs.java b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphDefs.java
index 1d83f2b..20d4ccf 100644
--- a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphDefs.java
+++ b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/GraphDefs.java
@@ -15,5 +15,6 @@
 						EDGE_TITLE=7, 

 						EDGE_AURI=8, 

 						EDGE_BURI=9, 

-						EDGE_LABEL_VALUE=10;

+						EDGE_LABEL_VALUE=10,

+						EDGE_POPULATION=11;

 }

diff --git a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/TextModifyListener.java b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/TextModifyListener.java
index d585771..ce859fe 100644
--- a/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/TextModifyListener.java
+++ b/core/org.eclipse.stem.ui.grapheditor/src/org/eclipse/stem/ui/grapheditor/TextModifyListener.java
@@ -18,7 +18,8 @@
 						EDGE_TITLE=GraphDefs.EDGE_TITLE, 

 						EDGE_AURI=GraphDefs.EDGE_AURI, 

 						EDGE_BURI=GraphDefs.EDGE_BURI, 

-						EDGE_LABEL_VALUE=GraphDefs.EDGE_LABEL_VALUE;

+						EDGE_LABEL_VALUE=GraphDefs.EDGE_LABEL_VALUE,

+						EDGE_POPULATION=GraphDefs.EDGE_POPULATION;

 	NodeData nodeData;

 	ConnectionData connectionData;

 	int attribute;

@@ -67,6 +68,7 @@
 		case EDGE_AURI: connectionData.setNodeAURI(text.getText()); break;

 		case EDGE_BURI: connectionData.setNodeBURI(text.getText()); break;

 		case EDGE_LABEL_VALUE: connectionData.setEdgeLabelValue(text.getText()); break;

+		case EDGE_POPULATION: connectionData.setEdgePopulation(text.getText()); break;

 		

 		}