Mercurial > projects > dwt-addons
annotate dwtx/jface/dialogs/DialogSettings.d @ 40:da5ad8eedf5d
debug prints, dwt.dwthelper restructure, ...
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 10 Apr 2008 08:59:39 +0200 |
parents | 2b36428a5ce4 |
children | 7ffeace6c47f |
rev | line source |
---|---|
19 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2006 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.jface.dialogs.DialogSettings; | |
14 | |
15 import dwtx.jface.dialogs.IDialogSettings; | |
16 | |
17 import tango.util.collection.model.Map; | |
18 import tango.util.collection.model.Seq; | |
19 import tango.util.collection.HashMap; | |
20 import tango.util.collection.ArraySeq; | |
21 | |
22 static import tango.text.xml.Document; | |
23 static import tango.text.xml.SaxParser; | |
24 static import tango.text.xml.PullParser; | |
25 static import tango.text.xml.XmlPrinter; | |
26 | |
27 | |
28 import dwt.dwthelper.utils; | |
29 static import dwt.dwthelper.OutputStream; | |
30 static import tango.text.convert.Integer; | |
31 static import tango.text.convert.Float; | |
32 static import tango.text.Text; | |
33 static import tango.io.File; | |
34 static import tango.io.Print; | |
35 static import tango.io.model.IConduit; | |
36 static import tango.io.stream.FileStream; | |
37 static import tango.text.convert.Format; | |
38 import tango.core.Exception; | |
39 alias tango.text.Text.Text!(char) StringBuffer; | |
40
da5ad8eedf5d
debug prints, dwt.dwthelper restructure, ...
Frank Benoit <benoit@tionex.de>
parents:
19
diff
changeset
|
40 import dwt.dwthelper.XmlTranscode; |
19 | 41 |
42 /** | |
43 * Concrete implementation of a dialog settings (<code>IDialogSettings</code>) | |
44 * using a hash table and XML. The dialog store can be read | |
45 * from and saved to a stream. All keys and values must be strings or array of | |
46 * strings. Primitive types are converted to strings. | |
47 * <p> | |
48 * This class was not designed to be subclassed. | |
49 * | |
50 * Here is an example of using a DialogSettings: | |
51 * </p> | |
52 * <pre> | |
53 * <code> | |
54 * DialogSettings settings = new DialogSettings("root"); | |
55 * settings.put("Boolean1",true); | |
56 * settings.put("Long1",100); | |
57 * settings.put("Array1",new String[]{"aaaa1","bbbb1","cccc1"}); | |
58 * DialogSettings section = new DialogSettings("sectionName"); | |
59 * settings.addSection(section); | |
60 * section.put("Int2",200); | |
61 * section.put("Float2",1.1); | |
62 * section.put("Array2",new String[]{"aaaa2","bbbb2","cccc2"}); | |
63 * settings.save("c:\\temp\\test\\dialog.xml"); | |
64 * </code> | |
65 * </pre> | |
66 */ | |
67 | |
68 public class DialogSettings : IDialogSettings { | |
69 alias tango.text.xml.Document.Document!(char) Document; | |
70 alias tango.text.xml.Document.Document!(char).Node Element; | |
71 alias tango.text.xml.XmlPrinter.XmlPrinter!(char) XmlPrinter; | |
72 // The name of the DialogSettings. | |
73 private String name; | |
74 | |
75 /* A Map of DialogSettings representing each sections in a DialogSettings. | |
76 It maps the DialogSettings' name to the DialogSettings */ | |
77 private Map!(String,IDialogSettings) sections; | |
78 | |
79 /* A Map with all the keys and values of this sections. | |
80 Either the keys an values are restricted to strings. */ | |
81 private Map!(String,String) items; | |
82 | |
83 // A Map with all the keys mapped to array of strings. | |
84 private Map!(String,String[]) arrayItems; | |
85 | |
86 private static const String TAG_SECTION = "section";//$NON-NLS-1$ | |
87 | |
88 private static const String TAG_NAME = "name";//$NON-NLS-1$ | |
89 | |
90 private static const String TAG_KEY = "key";//$NON-NLS-1$ | |
91 | |
92 private static const String TAG_VALUE = "value";//$NON-NLS-1$ | |
93 | |
94 private static const String TAG_LIST = "list";//$NON-NLS-1$ | |
95 | |
96 private static const String TAG_ITEM = "item";//$NON-NLS-1$ | |
97 | |
98 /** | |
99 * Create an empty dialog settings which loads and saves its | |
100 * content to a file. | |
101 * Use the methods <code>load(String)</code> and <code>store(String)</code> | |
102 * to load and store this dialog settings. | |
103 * | |
104 * @param sectionName the name of the section in the settings. | |
105 */ | |
106 public this(String sectionName) { | |
107 name = sectionName; | |
108 items = new HashMap!(String,String); | |
109 arrayItems = new HashMap!(String,String[]); | |
110 sections = new HashMap!(String,IDialogSettings); | |
111 } | |
112 | |
113 /* (non-Javadoc) | |
114 * Method declared on IDialogSettings. | |
115 */ | |
116 public IDialogSettings addNewSection(String sectionName) { | |
117 DialogSettings section = new DialogSettings(sectionName); | |
118 addSection(section); | |
119 return section; | |
120 } | |
121 | |
122 /* (non-Javadoc) | |
123 * Method declared on IDialogSettings. | |
124 */ | |
125 public void addSection(IDialogSettings section) { | |
126 sections.add(section.getName(), section); | |
127 } | |
128 | |
129 /* (non-Javadoc) | |
130 * Method declared on IDialogSettings. | |
131 */ | |
132 public String get(String key) { | |
133 return items.get(key); | |
134 } | |
135 | |
136 /* (non-Javadoc) | |
137 * Method declared on IDialogSettings. | |
138 */ | |
139 public String[] getArray(String key) { | |
140 return arrayItems.get(key); | |
141 } | |
142 | |
143 /* (non-Javadoc) | |
144 * Method declared on IDialogSettings. | |
145 */ | |
146 public bool getBoolean(String key) { | |
147 return items.get(key) == "true"; | |
148 } | |
149 | |
150 /* (non-Javadoc) | |
151 * Method declared on IDialogSettings. | |
152 */ | |
153 public double getDouble(String key) { | |
154 String setting = items.get(key); | |
155 if (setting is null) { | |
156 throw new NumberFormatException( | |
157 "There is no setting associated with the key \"" ~ key ~ "\"");//$NON-NLS-1$ //$NON-NLS-2$ | |
158 } | |
159 | |
160 return tango.text.convert.Float.toFloat(setting); | |
161 } | |
162 | |
163 /* (non-Javadoc) | |
164 * Method declared on IDialogSettings. | |
165 */ | |
166 public float getFloat(String key) { | |
167 String setting = items.get(key); | |
168 if (setting is null) { | |
169 throw new NumberFormatException( | |
170 "There is no setting associated with the key \"" ~ key ~ "\"");//$NON-NLS-1$ //$NON-NLS-2$ | |
171 } | |
172 | |
173 return tango.text.convert.Float.toFloat(setting); | |
174 } | |
175 | |
176 /* (non-Javadoc) | |
177 * Method declared on IDialogSettings. | |
178 */ | |
179 public int getInt(String key) { | |
180 String setting = items.get(key); | |
181 if (setting is null) { | |
182 //new Integer(null) will throw a NumberFormatException and meet our spec, but this message | |
183 //is clearer. | |
184 throw new NumberFormatException( | |
185 "There is no setting associated with the key \"" ~ key ~ "\"");//$NON-NLS-1$ //$NON-NLS-2$ | |
186 } | |
187 | |
188 return tango.text.convert.Integer.toInt(setting); | |
189 } | |
190 | |
191 /* (non-Javadoc) | |
192 * Method declared on IDialogSettings. | |
193 */ | |
194 public long getLong(String key) { | |
195 String setting = items.get(key); | |
196 if (setting is null) { | |
197 //new Long(null) will throw a NumberFormatException and meet our spec, but this message | |
198 //is clearer. | |
199 throw new NumberFormatException( | |
200 "There is no setting associated with the key \"" ~ key ~ "\"");//$NON-NLS-1$ //$NON-NLS-2$ | |
201 } | |
202 | |
203 return tango.text.convert.Integer.toLong(setting); | |
204 } | |
205 | |
206 /* (non-Javadoc) | |
207 * Method declared on IDialogSettings. | |
208 */ | |
209 public String getName() { | |
210 return name; | |
211 } | |
212 | |
213 /* (non-Javadoc) | |
214 * Method declared on IDialogSettings. | |
215 */ | |
216 public IDialogSettings getSection(String sectionName) { | |
217 return sections.get(sectionName); | |
218 } | |
219 | |
220 /* (non-Javadoc) | |
221 * Method declared on IDialogSettings. | |
222 */ | |
223 public IDialogSettings[] getSections() { | |
224 return sections.toArray(); | |
225 } | |
226 | |
227 /* (non-Javadoc) | |
228 * Method declared on IDialogSettings. | |
229 */ | |
230 public void load( tango.io.model.IConduit.InputStream input) { | |
231 Document document = new Document(); | |
232 try { | |
233 char[] content; | |
234 char[1024] readbuf; | |
235 int chunksize = 0; | |
236 while( (chunksize=input.read(readbuf)) !is tango.io.model.IConduit.InputStream.Eof ){ | |
237 content ~= readbuf[ 0 .. chunksize ]; | |
238 } | |
239 document.parse( content ); | |
240 | |
241 //Strip out any comments first | |
242 foreach( n; document.query[].filter( delegate bool(Element n) { | |
243 return n.type is tango.text.xml.PullParser.XmlNodeType.Comment ; | |
244 })){ | |
245 //TODO: remove() was added after tango 0.99.5 | |
246 //n.remove(); | |
247 } | |
248 load(document, document.root.firstChild ); | |
249 } catch (IOException e) { | |
250 // ignore | |
251 } catch (TextException e) { | |
252 // ignore | |
253 } | |
254 } | |
255 | |
256 /* (non-Javadoc) | |
257 * Method declared on IDialogSettings. | |
258 */ | |
259 //TODO: solve overload load(char[]) | |
260 public void load(String fileName) { | |
261 auto f = new tango.io.stream.FileStream.FileInput( fileName ); | |
262 load( f.input ); | |
263 f.close; | |
264 } | |
265 | |
266 /* (non-Javadoc) | |
267 * Load the setting from the <code>document</code> | |
268 */ | |
269 private void load(Document document, Element root) { | |
270 | |
271 name = root.getAttribute(TAG_NAME).value(); | |
272 | |
273 foreach( n; root.query[TAG_ITEM] ){ | |
274 if( root is n.parent() ){ | |
275 String key = n.getAttribute(TAG_KEY).value().dup; | |
276 String value = n.getAttribute(TAG_VALUE).value().dup; | |
277 items.add(key, value); | |
278 } | |
279 } | |
280 foreach( n; root.query[TAG_LIST].dup ){ | |
281 if( root is n.parent() ){ | |
282 auto child = n; | |
283 String key = child.getAttribute(TAG_KEY).value().dup; | |
284 char[][] valueList; | |
285 foreach( node; root.query[TAG_ITEM].dup ){ | |
286 if (child is node.parent()) { | |
287 valueList ~= node.getAttribute(TAG_VALUE).value().dup; | |
288 } | |
289 } | |
290 arrayItems.add(key, valueList ); | |
291 } | |
292 } | |
293 foreach( n; root.query[TAG_SECTION].dup ){ | |
294 if( root is n.parent() ){ | |
295 DialogSettings s = new DialogSettings("NoName");//$NON-NLS-1$ | |
296 s.load(document, n); | |
297 addSection(s); | |
298 } | |
299 } | |
300 } | |
301 | |
302 /* (non-Javadoc) | |
303 * Method declared on IDialogSettings. | |
304 */ | |
305 public void put(String key, String[] value) { | |
306 arrayItems.add(key, value); | |
307 } | |
308 | |
309 /* (non-Javadoc) | |
310 * Method declared on IDialogSettings. | |
311 */ | |
312 public void put(String key, double value) { | |
313 put(key, tango.text.convert.Float.toString(value)); | |
314 } | |
315 | |
316 /* (non-Javadoc) | |
317 * Method declared on IDialogSettings. | |
318 */ | |
319 public void put(String key, float value) { | |
320 put(key, tango.text.convert.Float.toString(value)); | |
321 } | |
322 | |
323 /* (non-Javadoc) | |
324 * Method declared on IDialogSettings. | |
325 */ | |
326 public void put(String key, int value) { | |
327 put(key, tango.text.convert.Integer.toString(value)); | |
328 } | |
329 | |
330 /* (non-Javadoc) | |
331 * Method declared on IDialogSettings. | |
332 */ | |
333 public void put(String key, long value) { | |
334 put(key, tango.text.convert.Integer.toString(value)); | |
335 } | |
336 | |
337 /* (non-Javadoc) | |
338 * Method declared on IDialogSettings. | |
339 */ | |
340 public void put(String key, String value) { | |
341 items.add(key, value); | |
342 } | |
343 | |
344 /* (non-Javadoc) | |
345 * Method declared on IDialogSettings. | |
346 */ | |
347 public void put(String key, bool value) { | |
348 put(key, value ? "true" : "false" ); | |
349 } | |
350 | |
351 /* (non-Javadoc) | |
352 * Method declared on IDialogSettings. | |
353 */ | |
354 public void save(tango.io.model.IConduit.OutputStream writer) { | |
355 save(new XMLWriter(writer)); | |
356 } | |
357 | |
358 | |
359 /* (non-Javadoc) | |
360 * Method declared on IDialogSettings. | |
361 */ | |
362 public void save(String fileName) { | |
363 auto stream = new tango.io.stream.FileStream.FileOutput(fileName); | |
364 XMLWriter writer = new XMLWriter(stream.output); | |
365 save(writer); | |
366 writer.close(); | |
367 } | |
368 | |
369 /* (non-Javadoc) | |
370 * Save the settings in the <code>document</code>. | |
371 */ | |
372 private void save(XMLWriter out_) { | |
373 HashMap!(String,String) attributes = new HashMap!(String,String); | |
374 attributes.add(TAG_NAME, name is null ? "" : name); //$NON-NLS-1$ | |
375 out_.startTag(TAG_SECTION, attributes); | |
376 attributes.clear(); | |
377 | |
378 foreach( key,value; items ){ | |
379 attributes.add(TAG_KEY, key is null ? "" : key); //$NON-NLS-1$ | |
380 String string = value;cast(String) items.get(key); | |
381 attributes.add(TAG_VALUE, string is null ? "" : string); //$NON-NLS-1$ | |
382 out_.printTag(TAG_ITEM, attributes, true); | |
383 } | |
384 | |
385 attributes.clear(); | |
386 foreach( key,value; arrayItems ){ | |
387 attributes.add(TAG_KEY, key is null ? "" : key); //$NON-NLS-1$ | |
388 out_.startTag(TAG_LIST, attributes); | |
389 attributes.clear(); | |
390 if (value !is null) { | |
391 for (int index = 0; index < value.length; index++) { | |
392 String string = value[index]; | |
393 attributes.add(TAG_VALUE, string is null ? "" : string); //$NON-NLS-1$ | |
394 out_.printTag(TAG_ITEM, attributes, true); | |
395 } | |
396 } | |
397 out_.endTag(TAG_LIST); | |
398 attributes.clear(); | |
399 } | |
400 foreach( name, section; sections ){ | |
401 section.save(out_); | |
402 } | |
403 out_.endTag(TAG_SECTION); | |
404 } | |
405 | |
406 | |
407 /** | |
408 * A simple XML writer. Using this instead of the javax.xml.transform classes allows | |
409 * compilation against JCL Foundation (bug 80059). | |
410 */ | |
411 private static class XMLWriter : tango.io.Print.Print!(char) { | |
412 /** current number of tabs to use for ident */ | |
413 protected int tab; | |
414 | |
415 /** the xml header */ | |
416 protected static const String XML_VERSION = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; //$NON-NLS-1$ | |
417 | |
418 /** | |
419 * Create a new XMLWriter | |
420 * @param output the write to used when writing to | |
421 */ | |
422 public this(tango.io.model.IConduit.OutputStream output) { | |
423 super( tango.text.convert.Format.Format, output); | |
424 tab = 0; | |
425 print(XML_VERSION); | |
426 newline; | |
427 } | |
428 | |
429 /** | |
430 * write the intended end tag | |
431 * @param name the name of the tag to end | |
432 */ | |
433 public void endTag(String name) { | |
434 tab--; | |
435 printTag("/" ~ name, null, false); //$NON-NLS-1$ | |
436 } | |
437 | |
438 private void printTabulation() { | |
439 for (int i = 0; i < tab; i++) { | |
440 super.print('\t'); | |
441 } | |
442 } | |
443 | |
444 /** | |
445 * write the tag to the stream and format it by itending it and add new line after the tag | |
446 * @param name the name of the tag | |
447 * @param parameters map of parameters | |
448 * @param close should the tag be ended automatically (=> empty tag) | |
449 */ | |
450 public void printTag(String name, HashMap!(String,String) parameters, bool close) { | |
451 printTag(name, parameters, true, true, close); | |
452 } | |
453 | |
454 private void printTag(String name, HashMap!(String,String) parameters, bool shouldTab, bool newLine, bool close) { | |
455 StringBuffer sb = new StringBuffer(); | |
456 sb.append('<'); | |
457 sb.append(name); | |
458 if (parameters !is null) { | |
459 foreach( key, value; parameters ){ | |
460 sb.append(" "); //$NON-NLS-1$ | |
461 sb.append(key); | |
462 sb.append("=\""); //$NON-NLS-1$ | |
463 sb.append(xmlEscape(value.dup)); | |
464 sb.append("\""); //$NON-NLS-1$ | |
465 } | |
466 } | |
467 if (close) { | |
468 sb.append('/'); | |
469 } | |
470 sb.append('>'); | |
471 if (shouldTab) { | |
472 printTabulation(); | |
473 } | |
474 if (newLine) { | |
475 print(sb.toString()); | |
476 newline; | |
477 } else { | |
478 print(sb.toString()); | |
479 } | |
480 } | |
481 | |
482 /** | |
483 * start the tag | |
484 * @param name the name of the tag | |
485 * @param parameters map of parameters | |
486 */ | |
487 public void startTag(String name, HashMap!(String,String) parameters) { | |
488 startTag(name, parameters, true); | |
489 tab++; | |
490 } | |
491 | |
492 private void startTag(String name, HashMap!(String,String) parameters, bool newLine) { | |
493 printTag(name, parameters, true, newLine, false); | |
494 } | |
495 } | |
496 | |
497 } |