fiore@0: /* fiore@0: CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool fiore@0: fiore@0: Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/) fiore@0: fiore@0: This program is free software: you can redistribute it and/or modify fiore@0: it under the terms of the GNU General Public License as published by fiore@0: the Free Software Foundation, either version 3 of the License, or fiore@0: (at your option) any later version. fiore@0: fiore@0: This program is distributed in the hope that it will be useful, fiore@0: but WITHOUT ANY WARRANTY; without even the implied warranty of fiore@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the fiore@0: GNU General Public License for more details. fiore@0: fiore@0: You should have received a copy of the GNU General Public License fiore@0: along with this program. If not, see . fiore@0: */ fiore@0: fiore@0: package uk.ac.qmul.eecs.ccmi.simpletemplate; fiore@0: fiore@0: import java.util.Collection; fiore@0: import java.util.LinkedHashMap; fiore@0: import java.util.Map; fiore@0: import java.util.ResourceBundle; fiore@0: fiore@0: /* fiore@0: * The Wizard Model holds all the data the user enters during the process of creating a diagram template. fiore@0: * Such data can be re-edited by the user during the same process or if they want to create fiore@0: * a new diagram template out of an existing one. When the user has entered all the data the model is used fiore@0: * to create an instance of the {@link Diagram class} which is then used as a prototype diagram. fiore@0: * Diagram instances that the user will edit are created by cloning the relating prototype diagram. fiore@0: * fiore@0: */ fiore@0: class Model { fiore@0: Model(){ fiore@0: diagramName = new Record(); fiore@0: nodes = new ModelMap(); fiore@0: edges = new ModelMap(); fiore@0: } fiore@0: fiore@0: @Override fiore@0: public String toString(){// FIXME need to port the strings to the .properties file fiore@0: StringBuilder builder = new StringBuilder(); fiore@0: builder.append("Diagram Name is ").append(diagramName.value).append(".\n\n"); fiore@0: builder.append(diagramName.value + " diagram has "+ (nodes.isEmpty() ? "no" : nodes.size()) + " node"+((nodes.size() == 1) ? "" : "s")); fiore@0: if(!nodes.isEmpty()){ fiore@0: builder.append(": "); fiore@0: int i = 0; fiore@0: for(Node n : nodes.values()){ fiore@0: builder.append(n.type.value); fiore@0: if(nodes.values().size() == 1) fiore@0: break; fiore@0: if(i == nodes.values().size() - 2){ fiore@0: builder.append(" and "); fiore@0: }else if(i < nodes.values().size()-1){ fiore@0: builder.append(", "); fiore@0: } fiore@0: i++; fiore@0: } fiore@0: } fiore@0: builder.append(".\n"); fiore@0: for(Node n : nodes.values()){ fiore@0: builder.append(n.type+" node has a ") fiore@0: .append(n.shape + " shape.\n"); fiore@0: builder.append(n.type+" node has "+ (n.properties.isEmpty() ? "no" : n.properties.size())+((n.properties.size() == 1) ? " property" : " properties")); fiore@0: if(!n.properties.isEmpty()){ fiore@0: builder.append(": "); fiore@0: int i = 0; fiore@0: for(Property p : n.properties.values()){ fiore@0: builder.append(p.type.value); fiore@0: if(n.properties.size() == 1) fiore@0: break; fiore@0: if(i == n.properties.size() - 2){ fiore@0: builder.append(" and "); fiore@0: }else if(i < n.properties.size()-1){ fiore@0: builder.append(", "); fiore@0: } fiore@0: i++; fiore@0: } fiore@0: } fiore@0: builder.append(".\n"); fiore@0: for(Property p : n.properties.values()){ fiore@0: builder.append(p.type+" property has position "+p.position); fiore@0: if(p.position.value.equals(SimpleShapeNode.Position.Outside.toString())) fiore@0: builder.append(" and shape "+p.shape+".\n"); fiore@0: else fiore@0: builder.append(".\n"); fiore@0: builder.append(p.type+" property has "+(p.modifiers.isEmpty() ? "no" : p.modifiers.size())+(p.modifiers.size() == 1 ? " modifier" : " modifiers")); fiore@0: if(!p.modifiers.isEmpty()){ fiore@0: builder.append(": "); fiore@0: int i = 0; fiore@0: for(Modifier m : p.modifiers.values()){ fiore@0: builder.append(m.type.value); fiore@0: if(p.modifiers.size() == 1) fiore@0: break; fiore@0: if(i == p.modifiers.size() - 2){ fiore@0: builder.append(" and "); fiore@0: }else if(i < p.modifiers.size()-1){ fiore@0: builder.append(", "); fiore@0: } fiore@0: i++; fiore@0: } fiore@0: } fiore@0: builder.append(".\n"); fiore@0: for(Modifier m : p.modifiers.values()){ fiore@0: builder.append(m.type+ " modifier "); fiore@0: if(m.format.values.length > 0) fiore@0: builder.append("is formatted as "+m.format+".\n"); fiore@0: else fiore@0: builder.append("\n"); fiore@0: } fiore@0: } fiore@0: } fiore@0: builder.append('\n'); fiore@0: builder.append(diagramName.value + " diagram has "+ (edges.isEmpty() ? "no" : edges.size()) + " edge"+((edges.size() == 1) ? "" : "s")); fiore@0: if(!edges.isEmpty()){ fiore@0: builder.append(": "); fiore@0: int i = 0; fiore@0: for(Edge e : edges.values()){ fiore@0: builder.append(e.type.value); fiore@0: if(edges.values().size() == 1) fiore@0: break; fiore@0: if(i == edges.values().size() - 2){ fiore@0: builder.append(" and "); fiore@0: }else if(i < edges.values().size()-1){ fiore@0: builder.append(", "); fiore@0: } fiore@0: i++; fiore@0: } fiore@0: } fiore@0: builder.append(".\n"); fiore@0: for(Edge e : edges.values()){ fiore@0: builder.append(e.type+ " edge has minimum nodes "+e.minNodes+" and maximum nodes "+e.maxNodes+".\n") fiore@0: .append(e.type+ " edge has a "+ e.lineStyle+" line style.\n") fiore@0: .append(e.type+" edge has "+ ((e.arrowHeads.values.length == 0) ? "no harrow heads.\n" : e.arrowHeads.values.length +" harrow heads: "+e.arrowHeads+".\n")); fiore@0: } fiore@0: builder.append('\n'); fiore@0: builder.append("Press up and down arrow keys to go through the summary.\n"); fiore@0: return builder.toString(); fiore@0: } fiore@0: fiore@0: Record diagramName; fiore@0: /* these are sets as when we edit an already existing node we just add */ fiore@0: /* to the set the new node and it gets replaced */ fiore@0: ModelMap nodes; fiore@0: ModelMap edges; fiore@0: fiore@0: static Element copy(Element src, Element dest){ fiore@0: if(src instanceof Node){ fiore@0: copy((Node)src,(Node)dest); fiore@0: }else if (src instanceof Edge){ fiore@0: copy((Edge)src,(Edge)dest); fiore@0: }else if(src instanceof Property){ fiore@0: copy((Property)src,(Property)dest); fiore@0: }else{ fiore@0: copy((Modifier)src,(Modifier)dest); fiore@0: } fiore@0: return dest; fiore@0: } fiore@0: fiore@0: static void copy(Node src, Node dest){ fiore@0: dest.id = src.id; fiore@0: dest.type.value = src.type.value; fiore@0: dest.shape.value = src.shape.value; fiore@0: dest.properties.clear(); fiore@0: dest.properties.putAll(src.properties); fiore@0: } fiore@0: fiore@0: static void copy(Property src, Property dest){ fiore@0: dest.id = src.id; fiore@0: dest.type.value = src.type.value; fiore@0: dest.shape.value = src.shape.value; fiore@0: dest.position.value = src.position.value; fiore@0: dest.modifiers.clear(); fiore@0: dest.modifiers.putAll(src.modifiers); fiore@0: } fiore@0: fiore@0: static void copy(Edge src, Edge dest){ fiore@0: dest.id = src.id; fiore@0: dest.type.value = src.type.value; fiore@0: dest.lineStyle.value = src.lineStyle.value; fiore@0: dest.maxNodes.value = src.maxNodes.value; fiore@0: dest.minNodes.value = src.minNodes.value; fiore@0: dest.arrowHeads.values = src.arrowHeads.values; fiore@0: dest.arrowHeadsDescriptions.values = src.arrowHeadsDescriptions.values; fiore@0: } fiore@0: fiore@0: static void copy(Modifier src, Modifier dest){ fiore@0: dest.id = src.id; fiore@0: dest.type.value = src.type.value; fiore@0: dest.format.values = src.format.values; fiore@0: dest.affix.values = src.affix.values; fiore@0: } fiore@0: fiore@0: static class Record{ fiore@0: Record(){ fiore@0: value = ""; fiore@0: } fiore@0: Record(String value){ fiore@0: this.value = value; fiore@0: } fiore@0: @Override fiore@0: public String toString(){ fiore@0: return value; fiore@0: } fiore@0: String value; fiore@0: } fiore@0: fiore@0: static class StrArrayRecord{ fiore@0: String [] values; fiore@0: StrArrayRecord(){ fiore@0: values = new String[0]; fiore@0: } fiore@0: fiore@0: StrArrayRecord(String[] values){ fiore@0: this.values = values; fiore@0: } fiore@0: fiore@0: @Override fiore@0: public String toString(){ fiore@0: StringBuilder builder = new StringBuilder(); fiore@0: for(int i=0; i(); fiore@0: } fiore@0: fiore@0: @Override fiore@0: void clear(){ fiore@0: super.clear(); fiore@0: shape.value = ""; fiore@0: properties.clear(); fiore@0: } fiore@0: Record shape; fiore@0: ModelMap properties; fiore@0: } fiore@0: fiore@0: static class Edge extends Element { fiore@0: Edge(){ fiore@0: lineStyle = new Record(); fiore@0: minNodes = new Record(); fiore@0: maxNodes = new Record(); fiore@0: arrowHeads = new StrArrayRecord(){ fiore@0: @Override fiore@0: public String toString(){ fiore@0: StringBuilder builder = new StringBuilder(); fiore@0: for(int i=0; i(); fiore@0: } fiore@0: Record position; fiore@0: Record shape; fiore@0: ModelMap modifiers; fiore@0: fiore@0: @Override fiore@0: void clear(){ fiore@0: super.clear(); fiore@0: modifiers.clear(); fiore@0: position.value = ""; fiore@0: shape.value = ""; fiore@0: } fiore@0: } fiore@0: fiore@0: static class Modifier extends Element { fiore@0: StrArrayRecord format; fiore@0: StrArrayRecord affix; fiore@0: fiore@0: Modifier(){ fiore@0: affix = new StrArrayRecord(); fiore@0: format = new StrArrayRecord(){ fiore@0: @Override fiore@0: public String toString(){ fiore@0: ResourceBundle resources = ResourceBundle.getBundle(SpeechWizardDialog.class.getName()); fiore@0: StringBuilder builder = new StringBuilder(); fiore@0: for(int i=0; i extends LinkedHashMap { fiore@0: public ModelMap(){ fiore@0: namesMap = new LinkedHashMap(); fiore@0: } fiore@0: fiore@0: @Override fiore@0: public void clear(){ fiore@0: namesMap.clear(); fiore@0: super.clear(); fiore@0: } fiore@0: fiore@0: public T put(Long key, T value){ fiore@0: namesMap.put(key, value.type.value); fiore@0: return super.put(key, value); fiore@0: } fiore@0: fiore@0: public void putAll(Map m){ fiore@0: for(Map.Entry entry : m.entrySet()){ fiore@0: namesMap.put(entry.getKey(), entry.getValue().type.value); fiore@0: } fiore@0: super.putAll(m); fiore@0: } fiore@0: fiore@0: public T remove(Object key){ fiore@0: namesMap.remove(key); fiore@0: return super.remove(key); fiore@0: } fiore@0: fiore@0: public Collection getNames(){ fiore@0: return namesMap.values(); fiore@0: } fiore@0: fiore@0: private Map namesMap; fiore@0: }