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 extends Long,? extends T> m){
fiore@0: for(Map.Entry extends Long,? extends T> 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: }