comparison Preferences.cs @ 0:961030992bd2

Initial commit of IBBoard libraries
author IBBoard <dev@ibboard.co.uk>
date Fri, 19 Dec 2008 11:13:48 +0000
parents
children 0352fa33ee8f
comparison
equal deleted inserted replaced
-1:000000000000 0:961030992bd2
1 using System;
2 using System.Collections;
3 using System.IO;
4 using System.Xml;
5 using System.Reflection;
6 using IBBoard.IO;
7
8 //TODO: Add import/export
9 namespace IBBoard
10 {
11 /// <summary>
12 /// Summary description for Preferences.
13 /// </summary>
14 public class Preferences
15 {
16 private static Type stringType = typeof(string);
17 private static Type hashtableType = typeof(Hashtable);
18 private Hashtable htGlobal;
19 private Hashtable htLocal;
20
21 private string app;
22 private bool modified = false;
23
24
25 public Preferences(string appName)
26 {
27 app = appName;
28 LoadPreferences();
29 }
30
31 /*public Preferences(string appExecPath, string appName, string fullUserDataDir)
32 {
33 LoadPreferences(appExecPath.TrimEnd(Constants.DirectoryChar) + Constants.DirectoryChar + appName + "Pref.xml", fullUserDataDir.TrimEnd(Constants.DirectoryChar));
34 }
35
36 public Preferences(string filepath, string appDir)
37 {
38 LoadPreferences(filepath, appDir);
39 }*/
40
41 private void LoadPreferences()
42 {
43 htGlobal = new Hashtable();
44 htLocal = new Hashtable();
45
46 string globalPath = Constants.ExecutablePath + Constants.DirectoryChar + app + "Pref.xml";
47
48 if (File.Exists(globalPath))
49 {
50 XmlDocument xmld = new XmlDocument();
51 xmld.Load(globalPath);
52 XmlNodeList nl = xmld.LastChild.ChildNodes;
53 XmlNodeList nlHash;
54 MethodInfo m;
55 Type t;
56 Hashtable htTemp;
57
58 if (nl == null || nl.Count==0)
59 {
60 throw new InvalidFileException("Preference file "+globalPath+" did not contain any preferences");
61 }
62
63 for (int i = 0; i<nl.Count; i++)
64 {
65 t = Type.GetType(nl[i].Attributes["type"].Value, true);
66
67 if (t!=stringType)
68 {
69 if (t==hashtableType)
70 {
71 htTemp = new Hashtable();
72 nlHash = nl[i].ChildNodes;
73
74 for (int j = 0; j<nlHash.Count; j++)
75 {
76 if (nlHash[j].NodeType.GetType()==typeof(XmlElement))
77 {
78 t = Type.GetType(nlHash[j].Attributes["type"].Value, true);
79 m = t.GetMethod("Parse", new Type[]{stringType});
80 htTemp[nlHash[j].Attributes["key"].Value] = m.Invoke(null, new object[]{nlHash[j].InnerText});
81 }
82 }
83
84 htGlobal[nl[i].Attributes["id"].Value] = htTemp;
85 }
86 else if (t.IsEnum)
87 {
88 htGlobal[nl[i].Attributes["id"].Value] = Enum.Parse(t, nl[i].InnerText, true);
89 }
90 else
91 {
92 m = t.GetMethod("Parse", new Type[]{stringType});
93 htGlobal[nl[i].Attributes["id"].Value] = m.Invoke(null, new object[]{nl[i].InnerText});
94 }
95 }
96 else
97 {
98 htGlobal[nl[i].Attributes["id"].Value] = nl[i].InnerText;
99 }
100 }
101
102 LoadLocalPreferences();
103 }
104 else
105 {
106 throw new FileNotFoundException("Could not find default preferences at "+globalPath);
107 }
108 }
109
110 private void LoadLocalPreferences()
111 {
112 string path = Constants.UserDataPath + Constants.DirectoryString + "preferences.xml";
113
114 if (File.Exists(path))
115 {
116 XmlDocument xmld = new XmlDocument();
117 xmld.Load(path);
118 XmlNodeList nl = xmld.LastChild.ChildNodes;
119 XmlNodeList nlHash;
120 MethodInfo m;
121 Type t;
122 Hashtable htTemp = new Hashtable();
123
124 nl = xmld.LastChild.ChildNodes;
125
126 for (int i = 0; i<nl.Count; i++)
127 {
128 if (!htGlobal.ContainsKey(nl[i].Attributes["id"].Value))
129 {
130 throw new InvalidFileException("User preferences file contains a value for key \""+nl[i].Attributes["id"].Value+"\" which is not contained in the main preferences");
131 }
132
133 t = Type.GetType(nl[i].Attributes["type"].Value, true);
134 if (t!=stringType)
135 {
136 if (t==hashtableType)
137 {
138 htTemp = new Hashtable();
139 nlHash = nl[i].ChildNodes;
140 Hashtable htTempInner = new Hashtable();
141
142 for (int j = 0; j<nlHash.Count; j++)
143 {
144 if (nlHash[j].NodeType==XmlNodeType.Element)
145 {
146 t = Type.GetType(nlHash[j].Attributes["type"].Value, true);
147 m = t.GetMethod("Parse", new Type[]{stringType});
148 htTempInner[nlHash[j].Attributes["key"].Value] = m.Invoke(null, new object[]{nlHash[j].InnerText});
149 }
150 }
151
152 htTemp[nl[i].Attributes["id"].Value] = htTempInner;
153 }
154 else if (t.IsEnum)
155 {
156 htTemp[nl[i].Attributes["id"].Value] = Enum.Parse(t, nl[i].InnerText, true);
157 }
158 else
159 {
160 m = t.GetMethod("Parse", new Type[]{stringType});
161
162 if (m!=null)
163 {
164 htTemp[nl[i].Attributes["id"].Value] = m.Invoke(null, new object[]{nl[i].InnerText});
165 }
166 }
167 }
168 else
169 {
170 htTemp[nl[i].Attributes["id"].Value] = nl[i].InnerText;
171 }
172 }
173
174 htLocal = htTemp;
175 }
176 }
177
178 public void ReloadPreferences()
179 {
180 htLocal.Clear();
181 LoadLocalPreferences();
182 }
183
184 public object this[string key]
185 {
186 get { return this[key, true]; }
187
188 set
189 {
190 if (!htGlobal.ContainsKey(key))
191 {
192 throw new InvalidOperationException("Preference must already exist in the Global Preferences");
193 }
194
195 if (htGlobal[key].GetType()!=value.GetType())
196 {
197 throw new InvalidOperationException("Preferences must be set with an object of the same type as the existing preference");
198 }
199
200 if (value is Hashtable)
201 {
202 throw new InvalidOperationException("Hashtables in Preferences cannot be set, they can only be added to or removed from.");
203 }
204
205 if (htGlobal[key].Equals(value))
206 {
207 if (htLocal.ContainsKey(key))
208 {
209 htLocal.Remove(key);
210 modified = true;
211 }
212 }
213 else if (!((htLocal[key]==null && value==null) || value.Equals(htLocal[key])))
214 {
215 htLocal[key] = value;
216 modified = true;
217 }
218 //else nothing actually needs modifying
219 }
220 }
221
222 public object this[string key, bool errorOnNoVal]
223 {
224 get
225 {
226 if (htLocal.ContainsKey(key))
227 {
228 return htLocal[key];
229 }
230 else if (htGlobal.ContainsKey(key))
231 {
232 if (htGlobal[key] is Hashtable)
233 {
234 htLocal[key] = ((Hashtable)htGlobal[key]).Clone();
235 return htLocal[key];
236 }
237 else
238 {
239 return htGlobal[key];
240 }
241 }
242 else if (errorOnNoVal)
243 {
244 throw new InvalidOperationException("Key \""+key+"\" was not associated with a preference value");
245 }
246
247 return null;
248 }
249 }
250
251 public bool GetBooleanProperty(string key)
252 {
253 object obj = this[key, false];
254 bool val = false;
255
256 if (obj is bool)
257 {
258 obj = (bool)obj;
259 }
260
261 return val;
262 }
263
264 public string GetStringProperty(string key)
265 {
266 object obj = this[key, false];
267 string str = null;
268
269 if (obj is String)
270 {
271 str = (String)obj;
272 }
273
274 return str;
275 }
276
277 //public String
278
279 public bool IsModified()
280 {
281 return modified;
282 }
283
284 public void Save()
285 {
286 if (htLocal.Count>0)
287 {
288 XmlDocument xmld = new XmlDocument();
289 xmld.LoadXml("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"+
290 "<!DOCTYPE prefs["+
291 "<!ELEMENT preferences (preferece*)> "+
292 "<!ELEMENT preference (CDATA|prefsub)> "+
293 "<!ELEMENT prefsub (CDATA)> "+
294 "<!ATTLIST preference id ID #REQUIRED>"+
295 "<!ATTLIST preference type CDATA #REQUIRED>"+
296 "<!ATTLIST prefsub key CDATA #REQUIRED>"+
297 "<!ATTLIST prefsub type CDATA #REQUIRED>"+
298 "]>"+"<preferences></preferences>");
299 XmlNode xmln = xmld.LastChild;
300 XmlNode pref;
301 XmlAttribute attr;
302 XmlNode prefSub;
303 XmlAttribute attrSub;
304 object o;
305 Hashtable htTemp;
306 Hashtable htGlobalTemp;
307
308 foreach (string key in htLocal.Keys)
309 {
310 pref = xmld.CreateNode(XmlNodeType.Element, "preference","");
311 attr = xmld.CreateAttribute("id");
312 attr.Value = key;
313 pref.Attributes.Append(attr);
314 attr = xmld.CreateAttribute("type");
315 o = htLocal[key];
316
317 attr.Value = o.GetType().AssemblyQualifiedName;
318
319 if (o.GetType().ToString() == "System.Collections.Hashtable")
320 {
321 htTemp = (Hashtable)o;
322 htGlobalTemp = (Hashtable)htGlobal[key];
323
324 foreach(object subkey in htTemp.Keys)
325 {
326 if (!htGlobalTemp.ContainsKey(subkey) || !htGlobalTemp[subkey].Equals(htTemp[subkey]))
327 {
328 prefSub = xmld.CreateNode(XmlNodeType.Element, "prefsub", "");
329 attrSub = xmld.CreateAttribute("key");
330 attrSub.Value = subkey.ToString();
331 prefSub.Attributes.Append(attrSub);
332 attrSub = xmld.CreateAttribute("type");
333 attrSub.Value = htTemp[subkey].GetType().AssemblyQualifiedName;
334 prefSub.Attributes.Append(attrSub);
335 prefSub.InnerText = htTemp[subkey].ToString();
336 pref.AppendChild(prefSub);
337 }
338 }
339 }
340 else
341 {
342 pref.InnerText = o.ToString();
343 }
344
345 pref.Attributes.Append(attr);
346 xmln.AppendChild(pref);
347 }
348
349 if (!Directory.Exists(Constants.UserDataPath))
350 {
351 Directory.CreateDirectory(Constants.UserDataPath);
352 }
353
354 xmld.Save(Constants.UserDataPath + Constants.DirectoryString + "preferences.xml");
355 }
356 else if (File.Exists(Constants.UserDataPath + Constants.DirectoryString + "preferences.xml"))
357 {
358 File.Delete(Constants.UserDataPath + Constants.DirectoryString + "preferences.xml");
359 }
360
361 modified = false;
362 }
363 }
364 }