Mercurial > hg > accesspd
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 } |