comparison java/src/uk/ac/qmul/eecs/ccmi/simpletemplate/Model.java @ 0:78b7fc5391a2

first import, outcome of NIME 2014 hackaton
author Fiore Martin <f.martin@qmul.ac.uk>
date Tue, 08 Jul 2014 16:28:59 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:78b7fc5391a2
1 /*
2 CCmI Editor - A Collaborative Cross-Modal Diagram Editing Tool
3
4 Copyright (C) 2011 Queen Mary University of London (http://ccmi.eecs.qmul.ac.uk/)
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package uk.ac.qmul.eecs.ccmi.simpletemplate;
21
22 import java.util.Collection;
23 import java.util.LinkedHashMap;
24 import java.util.Map;
25 import java.util.ResourceBundle;
26
27 /*
28 * The Wizard Model holds all the data the user enters during the process of creating a diagram template.
29 * Such data can be re-edited by the user during the same process or if they want to create
30 * a new diagram template out of an existing one. When the user has entered all the data the model is used
31 * to create an instance of the {@link Diagram class} which is then used as a prototype diagram.
32 * Diagram instances that the user will edit are created by cloning the relating prototype diagram.
33 *
34 */
35 class Model {
36 Model(){
37 diagramName = new Record();
38 nodes = new ModelMap<Node>();
39 edges = new ModelMap<Edge>();
40 }
41
42 @Override
43 public String toString(){// FIXME need to port the strings to the .properties file
44 StringBuilder builder = new StringBuilder();
45 builder.append("Diagram Name is ").append(diagramName.value).append(".\n\n");
46 builder.append(diagramName.value + " diagram has "+ (nodes.isEmpty() ? "no" : nodes.size()) + " node"+((nodes.size() == 1) ? "" : "s"));
47 if(!nodes.isEmpty()){
48 builder.append(": ");
49 int i = 0;
50 for(Node n : nodes.values()){
51 builder.append(n.type.value);
52 if(nodes.values().size() == 1)
53 break;
54 if(i == nodes.values().size() - 2){
55 builder.append(" and ");
56 }else if(i < nodes.values().size()-1){
57 builder.append(", ");
58 }
59 i++;
60 }
61 }
62 builder.append(".\n");
63 for(Node n : nodes.values()){
64 builder.append(n.type+" node has a ")
65 .append(n.shape + " shape.\n");
66 builder.append(n.type+" node has "+ (n.properties.isEmpty() ? "no" : n.properties.size())+((n.properties.size() == 1) ? " property" : " properties"));
67 if(!n.properties.isEmpty()){
68 builder.append(": ");
69 int i = 0;
70 for(Property p : n.properties.values()){
71 builder.append(p.type.value);
72 if(n.properties.size() == 1)
73 break;
74 if(i == n.properties.size() - 2){
75 builder.append(" and ");
76 }else if(i < n.properties.size()-1){
77 builder.append(", ");
78 }
79 i++;
80 }
81 }
82 builder.append(".\n");
83 for(Property p : n.properties.values()){
84 builder.append(p.type+" property has position "+p.position);
85 if(p.position.value.equals(SimpleShapeNode.Position.Outside.toString()))
86 builder.append(" and shape "+p.shape+".\n");
87 else
88 builder.append(".\n");
89 builder.append(p.type+" property has "+(p.modifiers.isEmpty() ? "no" : p.modifiers.size())+(p.modifiers.size() == 1 ? " modifier" : " modifiers"));
90 if(!p.modifiers.isEmpty()){
91 builder.append(": ");
92 int i = 0;
93 for(Modifier m : p.modifiers.values()){
94 builder.append(m.type.value);
95 if(p.modifiers.size() == 1)
96 break;
97 if(i == p.modifiers.size() - 2){
98 builder.append(" and ");
99 }else if(i < p.modifiers.size()-1){
100 builder.append(", ");
101 }
102 i++;
103 }
104 }
105 builder.append(".\n");
106 for(Modifier m : p.modifiers.values()){
107 builder.append(m.type+ " modifier ");
108 if(m.format.values.length > 0)
109 builder.append("is formatted as "+m.format+".\n");
110 else
111 builder.append("\n");
112 }
113 }
114 }
115 builder.append('\n');
116 builder.append(diagramName.value + " diagram has "+ (edges.isEmpty() ? "no" : edges.size()) + " edge"+((edges.size() == 1) ? "" : "s"));
117 if(!edges.isEmpty()){
118 builder.append(": ");
119 int i = 0;
120 for(Edge e : edges.values()){
121 builder.append(e.type.value);
122 if(edges.values().size() == 1)
123 break;
124 if(i == edges.values().size() - 2){
125 builder.append(" and ");
126 }else if(i < edges.values().size()-1){
127 builder.append(", ");
128 }
129 i++;
130 }
131 }
132 builder.append(".\n");
133 for(Edge e : edges.values()){
134 builder.append(e.type+ " edge has minimum nodes "+e.minNodes+" and maximum nodes "+e.maxNodes+".\n")
135 .append(e.type+ " edge has a "+ e.lineStyle+" line style.\n")
136 .append(e.type+" edge has "+ ((e.arrowHeads.values.length == 0) ? "no harrow heads.\n" : e.arrowHeads.values.length +" harrow heads: "+e.arrowHeads+".\n"));
137 }
138 builder.append('\n');
139 builder.append("Press up and down arrow keys to go through the summary.\n");
140 return builder.toString();
141 }
142
143 Record diagramName;
144 /* these are sets as when we edit an already existing node we just add */
145 /* to the set the new node and it gets replaced */
146 ModelMap<Node> nodes;
147 ModelMap<Edge> edges;
148
149 static Element copy(Element src, Element dest){
150 if(src instanceof Node){
151 copy((Node)src,(Node)dest);
152 }else if (src instanceof Edge){
153 copy((Edge)src,(Edge)dest);
154 }else if(src instanceof Property){
155 copy((Property)src,(Property)dest);
156 }else{
157 copy((Modifier)src,(Modifier)dest);
158 }
159 return dest;
160 }
161
162 static void copy(Node src, Node dest){
163 dest.id = src.id;
164 dest.type.value = src.type.value;
165 dest.shape.value = src.shape.value;
166 dest.properties.clear();
167 dest.properties.putAll(src.properties);
168 }
169
170 static void copy(Property src, Property dest){
171 dest.id = src.id;
172 dest.type.value = src.type.value;
173 dest.shape.value = src.shape.value;
174 dest.position.value = src.position.value;
175 dest.modifiers.clear();
176 dest.modifiers.putAll(src.modifiers);
177 }
178
179 static void copy(Edge src, Edge dest){
180 dest.id = src.id;
181 dest.type.value = src.type.value;
182 dest.lineStyle.value = src.lineStyle.value;
183 dest.maxNodes.value = src.maxNodes.value;
184 dest.minNodes.value = src.minNodes.value;
185 dest.arrowHeads.values = src.arrowHeads.values;
186 dest.arrowHeadsDescriptions.values = src.arrowHeadsDescriptions.values;
187 }
188
189 static void copy(Modifier src, Modifier dest){
190 dest.id = src.id;
191 dest.type.value = src.type.value;
192 dest.format.values = src.format.values;
193 dest.affix.values = src.affix.values;
194 }
195
196 static class Record{
197 Record(){
198 value = "";
199 }
200 Record(String value){
201 this.value = value;
202 }
203 @Override
204 public String toString(){
205 return value;
206 }
207 String value;
208 }
209
210 static class StrArrayRecord{
211 String [] values;
212 StrArrayRecord(){
213 values = new String[0];
214 }
215
216 StrArrayRecord(String[] values){
217 this.values = values;
218 }
219
220 @Override
221 public String toString(){
222 StringBuilder builder = new StringBuilder();
223 for(int i=0; i<values.length; i++){
224 builder.append(values[i]);
225 if(values.length == 1)
226 break;
227 if(i == values.length - 2)
228 builder.append(" and ");
229 else if(i < values.length -1 )
230 builder.append(", ");
231 }
232 return builder.toString();
233 }
234 }
235
236 private static long uniqueId = 0;
237 static class Element {
238 Element(){
239 type = new Record();
240 id = uniqueId++;
241 }
242
243 void clear () {
244 type.value = "";
245 id = uniqueId++;
246 }
247 long id;
248 Record type;
249 }
250
251 static class Node extends Element{
252 Node(){
253 shape = new Record();
254 properties = new ModelMap<Property>();
255 }
256
257 @Override
258 void clear(){
259 super.clear();
260 shape.value = "";
261 properties.clear();
262 }
263 Record shape;
264 ModelMap<Property> properties;
265 }
266
267 static class Edge extends Element {
268 Edge(){
269 lineStyle = new Record();
270 minNodes = new Record();
271 maxNodes = new Record();
272 arrowHeads = new StrArrayRecord(){
273 @Override
274 public String toString(){
275 StringBuilder builder = new StringBuilder();
276 for(int i=0; i<values.length; i++){
277 builder.append(values[i]+" with label "+arrowHeadsDescriptions.values[i]);
278 if(values.length == 1)
279 break;
280 if(i == values.length - 2)
281 builder.append(" and ");
282 else if(i < values.length -1 )
283 builder.append(", ");
284 }
285 return builder.toString();
286 }
287 };
288 arrowHeadsDescriptions = new StrArrayRecord();
289 }
290 @Override
291 public void clear(){
292 super.clear();
293 lineStyle.value = "";
294 minNodes.value = "";
295 maxNodes.value = "";
296 arrowHeads.values = new String[0];
297 arrowHeadsDescriptions.values = new String[0];
298 }
299 Record lineStyle;
300 Record minNodes;
301 Record maxNodes;
302 StrArrayRecord arrowHeads;
303 StrArrayRecord arrowHeadsDescriptions;
304 }
305
306 static class Property extends Element{
307 Property(){
308 position = new Model.Record();
309 shape = new Model.Record();
310 modifiers = new ModelMap<Modifier>();
311 }
312 Record position;
313 Record shape;
314 ModelMap<Modifier> modifiers;
315
316 @Override
317 void clear(){
318 super.clear();
319 modifiers.clear();
320 position.value = "";
321 shape.value = "";
322 }
323 }
324
325 static class Modifier extends Element {
326 StrArrayRecord format;
327 StrArrayRecord affix;
328
329 Modifier(){
330 affix = new StrArrayRecord();
331 format = new StrArrayRecord(){
332 @Override
333 public String toString(){
334 ResourceBundle resources = ResourceBundle.getBundle(SpeechWizardDialog.class.getName());
335 StringBuilder builder = new StringBuilder();
336 for(int i=0; i<values.length; i++){
337 builder.append(values[i]);
338 if(values[i].equals(resources.getString("modifier.format.prefix")) && !affix.values[0].isEmpty()){
339 builder.append(' ').append(affix.values[0]);
340 }
341 if(values[i].equals(resources.getString("modifier.format.suffix")) && !affix.values[1].isEmpty()){
342 builder.append(' ').append(affix.values[1]);
343 }
344
345 if(values.length == 1)
346 break;
347 if(i == values.length - 2)
348 builder.append(" and ");
349 else if(i < values.length -1 )
350 builder.append(", ");
351 }
352 return builder.toString();
353 }
354 };
355
356 /* affix is always length = 2 as it only contains prefix and suffix string */
357 /* eventually it contains empty strings but its length is not variable */
358 affix.values = new String[2];
359 }
360
361 @Override
362 void clear(){
363 super.clear();
364 format.values = new String[0];
365 affix.values = new String[2];
366 }
367 }
368 }
369
370
371 @SuppressWarnings("serial")
372 class ModelMap<T extends Model.Element> extends LinkedHashMap<Long,T> {
373 public ModelMap(){
374 namesMap = new LinkedHashMap<Long,String>();
375 }
376
377 @Override
378 public void clear(){
379 namesMap.clear();
380 super.clear();
381 }
382
383 public T put(Long key, T value){
384 namesMap.put(key, value.type.value);
385 return super.put(key, value);
386 }
387
388 public void putAll(Map<? extends Long,? extends T> m){
389 for(Map.Entry<? extends Long,? extends T> entry : m.entrySet()){
390 namesMap.put(entry.getKey(), entry.getValue().type.value);
391 }
392 super.putAll(m);
393 }
394
395 public T remove(Object key){
396 namesMap.remove(key);
397 return super.remove(key);
398 }
399
400 public Collection<String> getNames(){
401 return namesMap.values();
402 }
403
404 private Map<Long,String> namesMap;
405 }