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