Mercurial > repos > IBBoard
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 } |