view java/src/uk/ac/qmul/eecs/ccmi/diagrammodel/DiagramEdge.java @ 8:ea7885bd9bff tip

fixed bug : render solid line as dotted/dashed when moving the stylus from dotted/dashed to solid
author ccmi-guest
date Thu, 03 Jul 2014 16:12:20 +0100
parents d66dd5880081
children
line wrap: on
line source
/*  
 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
  
 Copyright (C) 2011  Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package uk.ac.qmul.eecs.ccmi.diagrammodel;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * This class represent an edge in the diagram model. Note that this class is 
 * a tree node.
 *
 */
@SuppressWarnings("serial")
public abstract class DiagramEdge extends DiagramElement {
	/**
	 * 
	 * @param type the type of the edge 
	 * @param availableEndDescriptions the end descriptions this edge allows 
	 */
	public DiagramEdge(String type, String[] availableEndDescriptions){
		setType(type);
		this.availableEndDescriptions = availableEndDescriptions;
		endLabels = new LinkedHashMap<DiagramNode,String>();
		endDescriptions = new LinkedHashMap<DiagramNode,Integer>();
	}

	/**
	 * Returns a more detailed description of the edge than {@link #spokenText()}.
	 * the description includes which nodes this edge is connecting 
	 * 
	 *  @return a description of the edge
	 */
	@Override
	public String detailedSpokenText(){
		final String and = " and ";
		StringBuilder b = new StringBuilder(getType());
		b.append(' ').append(spokenText());
		b.append(". Connecting ");
		for(int i=0; i<getChildCount();i++){
			b.append(((DiagramTreeNode)getChildAt(i)).getName());
			b.append(and);
		}
		// remove the last " and "
		b.delete(b.length()-and.length(), b.length());
		return  b.toString();
	}

	/**
	 * Set a label related to a node. On a graphical representation of the diagram 
	 * the label would be put in proximity of the node. 
	 * 
	 * @param n the node,at whose end the label is located 
	 * @param label the label
	 * @param source the source of the action that triggered this method 
	 */
	public void setEndLabel(DiagramNode n, String label, Object source){
		if(label == null)
			label = "";
		endLabels.put(n, label);
		notifyChange(new ElementChangedEvent(this,n,"endLabel",source));
	}

	/**
	 * Returns the end label related to a node. On a graphical representation of the diagram 
	 * the label would be put in proximity of the node.
	 * 
	 * @param n the node, at whose end the label is located 
	 * 
	 * @return the label at the specified end 
	 */
	public String getEndLabel(DiagramNode n){
		String s = endLabels.get(n);
		if(s == null)
			return "";
		return s;
	}

	/**
	 * Returns an array with all the available end description this edge can be 
	 * assigned. 
	 * @return an array of string available end description 
	 */
	public String[] getAvailableEndDescriptions(){
		return this.availableEndDescriptions;
	}   
	
	/**
	 * Set a string describing the end related to a node. On a visual diagram this 
	 * corresponds to an arrow.
	 * 
	 * @param n the node at the edge end whose description will be set
	 * @param index an index of the array returned by getAvailableEndDescriptions(). The 
	 * edge end description will be set with the string at that position in the array.
	 * if index is equal to NO_END_DESCRIPTION_INDEX, then the description will be set 
	 * as the empty string.
	 * @param source the source of the action that triggered this method 
	 * 
	 */
	public void setEndDescription(DiagramNode n, int index, Object source){
		endDescriptions.put(n, index);
		notifyChange(new ElementChangedEvent(this,n,"arrowHead",source));
	}

	/**
	 * Returns a string describing the end related to a node. On a visual diagram this 
	 * corresponds to an arrow.
	 *    
	 * @param n the node at the edge end whose description will be returned   
	 * @return a description string
	 */
	public String getEndDescription(DiagramNode n){
		Integer index = endDescriptions.get(n);
		if(index == null || index == NO_END_DESCRIPTION_INDEX)
			return "";
		return availableEndDescriptions[endDescriptions.get(n)];
	}

	/**
	 * Returns the connected node at the specified index  
	 * @param index an index into node's list
	 * @return the connected node at the specified index
	 */
	public abstract DiagramNode getNodeAt(int index);

	/**
	 * Returns the number of nodes this edge is connecting
	 * @return the number of nodes this edge is connecting
	 */
	public abstract int getNodesNum();

	/**
	 * Removes a node from this edge. On a graphical representation of the diagram 
	 * this would mean that the node is no longer connected to the other nodes via this edge. 
	 * @param n the node to be removed
	 * @param source the source of this action
	 * @return true if the inner collection changed as a result of the call
	 */
	public abstract boolean removeNode(DiagramNode n, Object source);
	
	/**
	 * Connect a list of nodes with this edge 
	 * @param nodes a list of nodes to connect 
	 * @throws ConnectNodesException if the number of nodes in the list is different 
	 * from the number allowed by this edge.  
	 */
	public abstract void connect(List<DiagramNode> nodes) throws ConnectNodesException;

	/**
	 * An index to be passed to {@link #setEndDescription(DiagramNode, int, Object)} in order 
	 * to set the edge with no description at the end related to that diagram node  
	 */
	public static int NO_END_DESCRIPTION_INDEX = -1;
	private Map<DiagramNode,String> endLabels;
	private Map<DiagramNode,Integer> endDescriptions;
	private String[] availableEndDescriptions;
}