Mercurial > hg > ccmieditor
view java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/Model.java @ 0:9418ab7b7f3f
Initial import
author | Fiore Martin <fiore@eecs.qmul.ac.uk> |
---|---|
date | Fri, 16 Dec 2011 17:35:51 +0000 |
parents | |
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.simpletemplate; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; import java.util.ResourceBundle; /* * The Wizard Model holds all the data the user enters during the process of creating a diagram template. * Such data can be re-edited by the user during the same process or if they want to create * a new diagram template out of an existing one. When the user has entered all the data the model is used * to create an instance of the {@link Diagram class} which is then used as a prototype diagram. * Diagram instances that the user will edit are created by cloning the relating prototype diagram. * */ class Model { Model(){ diagramName = new Record(); nodes = new ModelMap<Node>(); edges = new ModelMap<Edge>(); } @Override public String toString(){// FIXME need to port the strings to the .properties file StringBuilder builder = new StringBuilder(); builder.append("Diagram Name is ").append(diagramName.value).append(".\n\n"); builder.append(diagramName.value + " diagram has "+ (nodes.isEmpty() ? "no" : nodes.size()) + " node"+((nodes.size() == 1) ? "" : "s")); if(!nodes.isEmpty()){ builder.append(": "); int i = 0; for(Node n : nodes.values()){ builder.append(n.type.value); if(nodes.values().size() == 1) break; if(i == nodes.values().size() - 2){ builder.append(" and "); }else if(i < nodes.values().size()-1){ builder.append(", "); } i++; } } builder.append(".\n"); for(Node n : nodes.values()){ builder.append(n.type+" node has a ") .append(n.shape + " shape.\n"); builder.append(n.type+" node has "+ (n.properties.isEmpty() ? "no" : n.properties.size())+((n.properties.size() == 1) ? " property" : " properties")); if(!n.properties.isEmpty()){ builder.append(": "); int i = 0; for(Property p : n.properties.values()){ builder.append(p.type.value); if(n.properties.size() == 1) break; if(i == n.properties.size() - 2){ builder.append(" and "); }else if(i < n.properties.size()-1){ builder.append(", "); } i++; } } builder.append(".\n"); for(Property p : n.properties.values()){ builder.append(p.type+" property has position "+p.position); if(p.position.value.equals(SimpleShapeNode.Position.Outside.toString())) builder.append(" and shape "+p.shape+".\n"); else builder.append(".\n"); builder.append(p.type+" property has "+(p.modifiers.isEmpty() ? "no" : p.modifiers.size())+(p.modifiers.size() == 1 ? " modifier" : " modifiers")); if(!p.modifiers.isEmpty()){ builder.append(": "); int i = 0; for(Modifier m : p.modifiers.values()){ builder.append(m.type.value); if(p.modifiers.size() == 1) break; if(i == p.modifiers.size() - 2){ builder.append(" and "); }else if(i < p.modifiers.size()-1){ builder.append(", "); } i++; } } builder.append(".\n"); for(Modifier m : p.modifiers.values()){ builder.append(m.type+ " modifier "); if(m.format.values.length > 0) builder.append("is formatted as "+m.format+".\n"); else builder.append("\n"); } } } builder.append('\n'); builder.append(diagramName.value + " diagram has "+ (edges.isEmpty() ? "no" : edges.size()) + " edge"+((edges.size() == 1) ? "" : "s")); if(!edges.isEmpty()){ builder.append(": "); int i = 0; for(Edge e : edges.values()){ builder.append(e.type.value); if(edges.values().size() == 1) break; if(i == edges.values().size() - 2){ builder.append(" and "); }else if(i < edges.values().size()-1){ builder.append(", "); } i++; } } builder.append(".\n"); for(Edge e : edges.values()){ builder.append(e.type+ " edge has minimum nodes "+e.minNodes+" and maximum nodes "+e.maxNodes+".\n") .append(e.type+ " edge has a "+ e.lineStyle+" line style.\n") .append(e.type+" edge has "+ ((e.arrowHeads.values.length == 0) ? "no harrow heads.\n" : e.arrowHeads.values.length +" harrow heads: "+e.arrowHeads+".\n")); } builder.append('\n'); builder.append("Press up and down arrow keys to go through the summary.\n"); return builder.toString(); } Record diagramName; /* these are sets as when we edit an already existing node we just add */ /* to the set the new node and it gets replaced */ ModelMap<Node> nodes; ModelMap<Edge> edges; static Element copy(Element src, Element dest){ if(src instanceof Node){ copy((Node)src,(Node)dest); }else if (src instanceof Edge){ copy((Edge)src,(Edge)dest); }else if(src instanceof Property){ copy((Property)src,(Property)dest); }else{ copy((Modifier)src,(Modifier)dest); } return dest; } static void copy(Node src, Node dest){ dest.id = src.id; dest.type.value = src.type.value; dest.shape.value = src.shape.value; dest.properties.clear(); dest.properties.putAll(src.properties); } static void copy(Property src, Property dest){ dest.id = src.id; dest.type.value = src.type.value; dest.shape.value = src.shape.value; dest.position.value = src.position.value; dest.modifiers.clear(); dest.modifiers.putAll(src.modifiers); } static void copy(Edge src, Edge dest){ dest.id = src.id; dest.type.value = src.type.value; dest.lineStyle.value = src.lineStyle.value; dest.maxNodes.value = src.maxNodes.value; dest.minNodes.value = src.minNodes.value; dest.arrowHeads.values = src.arrowHeads.values; dest.arrowHeadsDescriptions.values = src.arrowHeadsDescriptions.values; } static void copy(Modifier src, Modifier dest){ dest.id = src.id; dest.type.value = src.type.value; dest.format.values = src.format.values; dest.affix.values = src.affix.values; } static class Record{ Record(){ value = ""; } Record(String value){ this.value = value; } @Override public String toString(){ return value; } String value; } static class StrArrayRecord{ String [] values; StrArrayRecord(){ values = new String[0]; } StrArrayRecord(String[] values){ this.values = values; } @Override public String toString(){ StringBuilder builder = new StringBuilder(); for(int i=0; i<values.length; i++){ builder.append(values[i]); if(values.length == 1) break; if(i == values.length - 2) builder.append(" and "); else if(i < values.length -1 ) builder.append(", "); } return builder.toString(); } } private static long uniqueId = 0; static class Element { Element(){ type = new Record(); id = uniqueId++; } void clear () { type.value = ""; id = uniqueId++; } long id; Record type; } static class Node extends Element{ Node(){ shape = new Record(); properties = new ModelMap<Property>(); } @Override void clear(){ super.clear(); shape.value = ""; properties.clear(); } Record shape; ModelMap<Property> properties; } static class Edge extends Element { Edge(){ lineStyle = new Record(); minNodes = new Record(); maxNodes = new Record(); arrowHeads = new StrArrayRecord(){ @Override public String toString(){ StringBuilder builder = new StringBuilder(); for(int i=0; i<values.length; i++){ builder.append(values[i]+" with label "+arrowHeadsDescriptions.values[i]); if(values.length == 1) break; if(i == values.length - 2) builder.append(" and "); else if(i < values.length -1 ) builder.append(", "); } return builder.toString(); } }; arrowHeadsDescriptions = new StrArrayRecord(); } @Override public void clear(){ super.clear(); lineStyle.value = ""; minNodes.value = ""; maxNodes.value = ""; arrowHeads.values = new String[0]; arrowHeadsDescriptions.values = new String[0]; } Record lineStyle; Record minNodes; Record maxNodes; StrArrayRecord arrowHeads; StrArrayRecord arrowHeadsDescriptions; } static class Property extends Element{ Property(){ position = new Model.Record(); shape = new Model.Record(); modifiers = new ModelMap<Modifier>(); } Record position; Record shape; ModelMap<Modifier> modifiers; @Override void clear(){ super.clear(); modifiers.clear(); position.value = ""; shape.value = ""; } } static class Modifier extends Element { StrArrayRecord format; StrArrayRecord affix; Modifier(){ affix = new StrArrayRecord(); format = new StrArrayRecord(){ @Override public String toString(){ ResourceBundle resources = ResourceBundle.getBundle(SpeechWizardDialog.class.getName()); StringBuilder builder = new StringBuilder(); for(int i=0; i<values.length; i++){ builder.append(values[i]); if(values[i].equals(resources.getString("modifier.format.prefix")) && !affix.values[0].isEmpty()){ builder.append(' ').append(affix.values[0]); } if(values[i].equals(resources.getString("modifier.format.suffix")) && !affix.values[1].isEmpty()){ builder.append(' ').append(affix.values[1]); } if(values.length == 1) break; if(i == values.length - 2) builder.append(" and "); else if(i < values.length -1 ) builder.append(", "); } return builder.toString(); } }; /* affix is always length = 2 as it only contains prefix and suffix string */ /* eventually it contains empty strings but its length is not variable */ affix.values = new String[2]; } @Override void clear(){ super.clear(); format.values = new String[0]; affix.values = new String[2]; } } } @SuppressWarnings("serial") class ModelMap<T extends Model.Element> extends LinkedHashMap<Long,T> { public ModelMap(){ namesMap = new LinkedHashMap<Long,String>(); } @Override public void clear(){ namesMap.clear(); super.clear(); } public T put(Long key, T value){ namesMap.put(key, value.type.value); return super.put(key, value); } public void putAll(Map<? extends Long,? extends T> m){ for(Map.Entry<? extends Long,? extends T> entry : m.entrySet()){ namesMap.put(entry.getKey(), entry.getValue().type.value); } super.putAll(m); } public T remove(Object key){ namesMap.remove(key); return super.remove(key); } public Collection<String> getNames(){ return namesMap.values(); } private Map<Long,String> namesMap; }